could parent object be created using super to call parent method - java

Would the parent object be created , if we use the super keyword to call the method of the parent class in child object?
Outcomes show that both Mybase and MySub have the same reference address. Not sure whether it is a good demo.
class Mybase {
public void address() {
System.out.println("super:" + this);
System.out.println( this.getClass().getName());
}
}
class MySub extends Mybase {
public void address() {
System.out.println("this:" + this);
System.out.println( this.getClass().getName());
}
public void info() {
System.out.println("this:" + this);
super.address();
}
}
public class SuperTest {
public static void main(String[] args) {
new MySub().info();
}
}

Well, let's find out!
Your test isn't quite going to answer your question. If you want to see if an object is created, why not create a constructor that prints to the console when called?
public class Test {
static class Parent {
Parent() {
System.out.println("Parent constructor called");
}
void method() {
System.out.println("Parent method called");
}
}
static class Child extends Parent {
Child() {
System.out.println("Child constructor called");
}
#Override
void method() {
System.out.println("Child method called");
super.method();
}
}
public static void main(final String[] args) {
new Child().method();
}
}
If you run this, you get this output:
Parent constructor called
Child constructor called
Child method called
Parent method called
So as you can see, when method() was called, no Parent object was created when the super keyword was used. So the answer to your question is "no".
The reason is because super and super() are different. super (no parentheses) is used to access members of the parent class. super() (with parentheses) is a call to the parent constructor, and is only valid inside a constructor as the first call in the constructor. So using super (no parentheses) will not create a new object.
Also, super() doesn't actually create a new, independent Parent object. It just does the initialization work for the fields of Parent that is needed before the child constructor continues.

Related

How to access overridden method of parent class without using super()?

As shown below, I tried to cast the object of the sub-class to that of its parent class. That went well. But, when I try to access the overridden method of the parent class, it doesn't happen. Instead the overriding method in the child class is called. I know I can do this using the super keyword, but I just want to know why this can't be done by casting?
This is the parent class:
public class Parent {
public void print() {
System.out.println("In parent");
}
}
This is the child class which has its properties inherited from the parent class:
public class Child extends Parent{
public void print() {
System.out.println("In child");
}
}
This is the class which contains the main method:
public class Main {
public static void main(String[] args) {
Child child = new Child();
((Parent)child).print();
}
}
Clarification
In your example, the object is always Child. Casting is applied only to the reference variable. This casting never impacts the actual object.
Options
As mentioned by others, add a separate method that will call super.() or use hiding. Hiding is not actually overriding.
Beware of the side effects of hiding
public class AccessParent {
public static void main(String[] args) {
Parent p = new Child();
p.methodC();
System.out.println(new String(new char[20]).replace("\0", "-"));
p.methodD();
}
}
class Parent {
void methodA() {
System.out.println("Parent.methodA");
}
private void methodB() {
System.out.println("Parent.methodB");
// this will still call Child.methodA
// a hidden method can not control the scope of overridden method
methodA();
}
void methodC() {
System.out.println("Parent.methodC");
methodB();
}
void methodD() {
System.out.println("Parent.methodD");
// hidden method will be called
// technically Child.methodB() is not overridden
methodB();
}
}
class Child extends Parent {
#Override
void methodA() {
System.out.println("Child.methodA");
}
// this not overridden
void methodB() {
System.out.println("Child.methodB");
}
}
This will output
Parent.methodC
Parent.methodB
Child.methodA
--------------------
Parent.methodD
Parent.methodB
Child.methodA```
You can't access a overriden method directly from a child class. The best you can do is add another function to your child that calls the parent print function.
public class Child extends Parent{
public void print() {
System.out.println("In child");
}
public void printParent() {
super.print()
}
}
Then you can access it like this,
public class Main {
public static void main(String[] args) {
Child child = new Child();
child.printParent();
}
}
Overriding is a principle which gives weightage on inheritance.
If you have a specific requirement to behave as per the casting then the method must be class level "static" instead of instance level.
You would loose the beauty of true inheritance and enter in hiding it more. However, the same can be achieved in casting way
package com.company.language;
public class InheritanceTrial {
public static void main(String[] args) {
Child child = new Child();
child.print();
((Parent)child).print();
}
}
class Parent {
public static void print() {
System.out.println("In parent");
}
}
class Child extends Parent{
public static void print() {
System.out.println("In child");
}
}
With the help of java.lang.invoke.MethodHandles, java.lang.invoke.MethodHandle and java.lang.invoke.MethodType we can only access the immediate parent's method. So this might help your question.
Working solution
public class Child extends Parent {
public static void main(String[] args) throws Throwable {
MethodHandle MH_Parent = MethodHandles.lookup().findSpecial(Parent.class, "print" , MethodType.methodType(void.class), Child.class);
MH_Parent.invokeExact(new Child());
}
public void print() {
System.out.println("In child");
}
}
class Parent {
void print() {
System.out.println("In parent");
}
}
Failing Solution
class Parent {
public void print() {
System.out.println("In parent");
}
}
class Child extends Parent{
public void print() {
System.out.println("In child");
}
}
public class Main {
public static void main(String[] args) throws Throwable {
MethodHandle MH_Parent = MethodHandles.lookup().findSpecial(Parent.class, "print" , MethodType.methodType(void.class), Child.class);
MH_Parent.invokeExact(new Child());
}
}

Method overriding with different parameters

Lets say I have a parent class:
class Parent{
public void aMethod() {
//Some stuff
}
}
and it's child class:
class Child extends Parent {
public void aMethod(int number){
//Some other stuff
}
}
Now the child has both methods with different parameters. This does method overloading. But I need method overriding, i.e, If someone tries to call aMethod() with the object of child class then the method of child class should be called or say method of parent class should not be accessible. But I can't change the access modifier of the parent class because the parent class has other children as well and they need the method as is.
So any suggestions?
You can override the Parent's method in the Child class and throw an exception:
class Child extends Parent {
public void aMethod(int number){
//Some other stuff
}
#Override
public void aMethod() {
throw new UnsupportedOperationException();
}
}
Or, if you want the existing method of the Child class to be executed :
class Child extends Parent {
public void aMethod(int number){
//Some other stuff
}
#Override
public void aMethod() {
aMethod (someIntValue);
}
}
Either way Parent's implementation of aMethod() will never be executed for instances of class Child.
this
void aMethod() {
and this
void aMethod(int number)
are totally different methods (their signature is different) so there is not way to say that aMethod(int number) is overriding aMethod()
so what you can do?:
override the only method you can and the OVERLOAD it
public class Child extends Parent {
#Override
public void aMethod() {
// TODDY
}
//here overload it
public void aMethod(int number){
// TODDY
}
}
You can implement a version of aMethod in the Child class and it will be called instead of the parent's version when you call that method on any instance of the Child class.
You don't need to change the Parent's signature to override the method because both public and protected methods can be overridden.
class Child extends Parent {
#Override
public void aMethod() {
// TODO
}
public void aMethod(int number){
//Some other stuff
}
}

If I invoke a parent's method in parent class, does it invoke child class method with the same name

I want to know whether a child class calling parent method that invokes an overloaded method in the parent class, will invoke the overloaded method in the child class
class Parent {
void doStuff() {
}
void asd() {
doStuff();
}
}
class Child extends Parent {
void doStuff() {
// implementation
}
}
static void main(Args... args) {
new Child().asd(); -> does this invoke the doStuff with the implementation or the empty doStuff in the parent class?
}
class Parent{
void doStuff(){
System.out.println("parent class");
}
void asd(){
doStuff();
}
}
class Child extends Parent(){
#Override
void doStuff(){
//super.asd();
System.out.println("child class");
}
}
/**
* When you run the program you will see the two methods being called
* one from the parent class and then the override method for child.
* just uncomment the super.asd() in childs doStuff() to see both print.
**/
public static void main(String [] args){
Child c = new Child();
c.doStuff(); // call methods
}

Java calling Super constructor confusion

class Yfk {
public static void main(String[] args) {
System.out.println(new YfkC().x);
}
}
abstract class YfkA {
int x = 3;
YfkA() { x++; }
}
class YfkB extends YfkA {}
class YfkC extends YfkB {}
The final result is 4. I am not clear about the extend process. In the main function, we create an object YfkC and invoke Yfkc.x. My understanding is since there is no method and filed in class yfkc, so we find in yfkb, and then find in yfkc. At this time, will YfkC be upcasted to YfkA automatically? Equal System.out.println(new YfkA().x); so we will get x = 4; I am confused about the process from YfkC to YfkA.
new YfkC().x
This internally calls the constructor of the sub class. so the value of x is incremented and printed as 4.
YfkC() -> YfkB() -> YfkA() { x++;};
The default constructor of each class is calling the super();. This calls the default constructor of the super class before executing it's own.
If you want to know about the constructor chaining then put as system out and see the calling chain.
public class Yfk {
public static void main(String[] args) {
System.out.println(new YfkC().x);
}
}
abstract class YfkA {
int x = 3;
YfkA() {
System.out.println("YfkA");
x++; }
}
class YfkB extends YfkA {
public YfkB() {
System.out.println("YfkB");
}
}
class YfkC extends YfkB {
public YfkC() {
System.out.println("YfkC");
}
}
output:
YfkA
YfkB
YfkC
4
When you invoke any Child constructor. There is a chain call to the immediate parent class constructor from the current class. And the call continues until the Object class constructor invokes since that the possible most Parent classes super class is.
Here is an example how constructor behaves in inheritance
public class ParentClass {
public ParentClass() {
System.out.println("Parent default constructor invoked");
}
public ParentClass(int a) {
System.out.println("Parent argumented constructor invoked");
}
public static void main(String[] args) {
SubSubClass sub = new SubSubClass();
}
}
class SubClass extends ParentClass {
public SubClass() {// not calling any super
System.out.println("Child default constructor invoked");
}
public SubClass(int b) {
super(b);
System.out.println("Child default constructor invoked");
}
}
class SubSubClass extends SubClass {
public SubSubClass() {// not calling any super
System.out.println("Sub Child default constructor invoked");
}
public SubSubClass(int b) {
super(b);
System.out.println("Sub Child default constructor invoked");
}
}
OUTPUT:
Parent default constructor invoked
Child default constructor invoked
Sub Child default constructor invoked
I wrote an article covering this topic, hope that clears your doubt.
Constructor inheritance(ovveriding) and reasons behind restricting constructor inheritance in Java
Whenever a child class is instantiated, its parent constructors are invoked in sequence, up the chain.
In your hierarchy, you have:
YfkC
YfkB
abstract YfkA
Object
...and in each of their constructors, there is an implicit call to super().
So, new YfkC invokes YfkB's constructor, which invokes the abstract class's YfkAs constructor, which results in the incrementation of x.
If you were to execute new YfkC().x again, you'd get 5, since every time you new up any of YfkA's children, you would be invoking that constructor.

How to call parent class method from it's constructor

I am creating child class object. I know parent class constructor called first .If i want to call parent class print method so I am used this.print() but this is not working.
Please suggest me how to call parent class print() method without creating parent class object.
public class Test
{
public static void main(String[] args)
{
Child Child = new Child();
}
}
class Parent
{
void print()
{
System.out.println("parent class print method");
}
Parent()
{
this.print();
}
}
class Child extends Parent
{
void print()
{
System.out.println("child class print method ");
}
}
in child constructor You can call a super class method like :
super.print();
see java docs
public class Superclass {
public void printMethod() {
System.out.println("Printed in Superclass.");
}
}
public class Subclass extends Superclass {
// overrides printMethod in Superclass
public void printMethod() {
super.printMethod();
System.out.println("Printed in Subclass");
}
public static void main(String[] args) {
Subclass s = new Subclass();
s.printMethod();
}
}
To call any parent method use super. This also works for the constructor:
class Child extends Parent
{
void print()
{
System.out.println("child class print method ");
}
Child() {
super.print(); // parent print method
this.print(); // child print method
}
}
"this" keyword refers to current class and "super" keyword refers to its parent class or interface which it extends or implements respectively.
Clear my concept thanks to anwser my question..
public class Test
{
public static void main(String[] args)
{
Child Child = new Child();
}
}
class Parent
{
void print()
{
System.out.println("parent class print method");
}
Parent()
{
this.print();
}
}
class Child extends Parent
{
void print()
{
super.print();
}
}
output:
parent class print method

Categories