Parent class :
public class Parent {
public void run()
{
walk();
System.out.println("Parent run");
}
public void walk()
{
System.out.println("Parent walk");
}
Child Class :
public class Child extends Parent {
public void run()
{
super.run();
System.out.println("child run");
}
public void walk()
{
super.walk();
System.out.println("child walk");
}
public class FirstJava {
public static void main(String[] a) {
Child c=new Child();
c.run();
}
I am gettting below o/p
Parent walk
child walk
Parent run
child run
Here when i call walk() its going for walk() of Child.
Why not for walk() of parent?
While calling walk() which object its refering to and why? any one explain why??
how come its calling both the methods from child as well as parent.
in
Child c=new Child();
c.run();
you apply run corresponding to the type of the value in c, because c values a Child and run is defined on it you call the operation run defined on Child being :
public void run()
{
super.run();
System.out.println("child run");
}
super.run() applies the operation corresponding to the parent class, because the parent class of Child is Parent and run is defined on it you call :
public void run()
{
walk();
System.out.println("Parent run");
}
the operation walk is applied depending on the real type of the instance being Child so you call :
public void walk()
{
super.walk();
System.out.println("child walk");
}
like before because of super that calls the operation on Parent :
public void walk()
{
System.out.println("Parent walk");
}
printing Parent walk then you come back in Child walk printing child walk then come back in Parent run printing Parent run then come back in Child run printing child run
After your edit
Here when i call walk() its going for walk() of Child. Why not for walk() of parent? While calling walk() which object its refering to and why?
As I already say this is because the called method is determined (at the execution) by the real type of the instance, and in that case the instance is a Child, so the called method is the walk defined on Child and not the one on Parent. Of course if there is no walk defined on Child it would be the one defined on Parent. All the method are applied on the unique instance you created in main and being a Child
Of course if walk is a method for the class Parent (e.g. static) rather than for its instances that changes all and walk() in run of Parent would be the walk of Parent. But this is not the case in your code so the real type of the instance counts.
Note also the execution would the all the same modifying your main to have :
public class FirstJava {
public static void main(String[] a) {
Parent c=new Child();
c.run();
}
because even c is declared Parent its value is a Child
If you override a parent method in its child, child objects will always use the overridden version.
Related
Is overloading in inheritance class possible in Java? Parent class and Child class contain the same method name, but different parameters. Is this overloading?
class Parent {
public void add(int a) {
System.out.println("I am parent" + a);
}
}
class Child extends Parent {
public void add(long a) {
System.out.println("I am child.");
}
}
Yes. While extending any class, internally it means all accessible behaviour of the parent class will be present or inherited in child class. i.e, so in your case same name with different argument is overloading.
Yes of course, overloading in inheritance class is possible in Java. Java compiler detect that add method has multiple implementations. so according to the parameter java compiler will determines which method has to be executed.
class Parent {
public void add(int a) {
System.out.println("I am parent " + a);
}
}
class Child extends Parent {
public void add(long a) {
System.out.println("I am child.");
}
}
class Demo{
public static void main(String args[]){
Child child = new Child();
child.add(1); // prints "I am parent 1"
child.add(1L); // prints "I am child."
}
}
Yes, In java allow overloading concept which means you can declare different method with Same name and different parameter .In your case You are extending the parent class ,which means all the property of parent class available in child class(child).
Its a overloading:
Child c = new Child();
c.add(1);//it will call the parent method
c.add(1L);//It will call the child method
I have below parent class :-
class Parent {
Parent() {
System.out.print("Parent ");
}
}
class Child extends Parent {
Child() {
System.out.print("Child");
}
}
So when i execute Child c = new Child();
My output should be "Child" Not "Parent Child"
can we do that using reflection API?
Requirement :-
I have a long Junit Setup hierarchy Which I want to avoid for some of the classes
What happens is when you create the Child class the Parent's class constructor is called first and then the Child's constructor.
What you could do if you must change what happens in the parent constructor is that you extract the related code into a protected method and this way you can override it in the Child class
However it is error prone and not recommended (What's wrong with overridable method calls in constructors?)
class Parent {
Parent() {
overridableInit();
}
protected void overridableInit() {
System.out.print("Parent ");
}
}
//If you want to extend the behavior:
class Child1 extends Parent {
#Override
protected void overridableInit() {
super.overridableInit();
System.out.print("Child1 ");
}
}
//If you want to skip the Parent behavior:
class Child2 extends Parent {
#Override
protected void overridableInit() {
System.out.print("Child2 ");
}
}
As per this question, while I understand why it goes wrong, how can I effectively solve this while keeping my code DRY? I wouldn't want to copy and paste the contents in that function into the constructor.
Suppose I have the following
class Parent
{
Parent()
{
overridableFunction();
}
void overridableFunction()
{ ... }
}
class Child extends Parent
{
Child()
{
super();
overridableFunction()
}
void overridableFunction()
{ ... // overridden }
}
Ideally, I wish the execution flow of the Child constructor to be
Parent() --> Parent.overridableFunction() --> Child.overridableFunction()
How can I achieve this without copying and pasting stuff around thus making the code WET?
If you wish Parent's constructor to execute its own implementation of overridableFunction() and Child's constructor to execute its own implementation of overridableFunction(), what you are basically saying is you don't want Child's overridableFunction() to override Parent's overridableFunction() method.
You can give the two methods different names, or keep the names identical, but make Parent's method private, to avoid any overriding.
I am not sure why you want to do it, but this follows the execution flow you asked for :
class Parent
{
Parent()
{
overridableFunction();
}
void overridableFunction()
{ System.out.println("Parent implementation "); }
public static void main(String[] args) {
new Child();
}
}
class Child extends Parent
{
Child()
{
super();
//remove overridableFunction();
}
#Override
void overridableFunction()
{
super.overridableFunction();
System.out.println("Child implementation ");
}
}
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.
if I have a class myClass1 and a second class myClass1Extended that is an extension of the first class, I have this source code:
myClass1 c1 = something(); // line 1
myClass1Extended c1ex = somethingElse(); // line 2
if (c1ex instanceof myClass1) { // line 3
(myClass1)c1ex.doSomething(); // line 4
}
I have a few questions:
in Line 3, will the operator instanceof return true?
in line 4, supposing the first answer is yes, what will happen if doSomething() has not been overriden in myClass1Extended?
And what happens instead if doSomething() has been overriden?
in line 4, is (myClass1) necessary?
Thank you very much
Why don''t you try the code to see?
yes
it will call the one in the parent class
it will call the one in the child class
no.
Given:
class Parent
{
public void foo()
{
System.out.ptintln("parent::foo");
bar();
}
public void bar()
{
System.out.println("parent::bar");
}
}
class Child
extends Parent
{
public void foo()
{
super.foo();
System.out.ptintln("child::foo");
}
}
You can use the Child class anywhere you use the Parent class, because all Children are types of Parents.
When the compiler looks at this code:
Parent p = new Child();
it verifies that the Child extends or implements the Parent.
When the compiler looks at this code:
p.foo();
it verifies that the type the p is declared as, Parent, has a foo method.
At runtime when the p.foo() line is executed the Virtual Machine looks at the type that p is actually pointing at, Child, and looks there for the foo method. Assuming the foo method is found in Child it runs it, otherwise it looks at the Parent class for it.
In the Parent class when the foo method calls bar the compiler again looks to make sure that the Parent class has a bar method. At runtime the VM again looks at the Child class to for the bar method, and since it does not it calls the one in the Parent.
If the methods don't exist in Parent then they have to exist the in the parent class of Parent, all the way up to java.lang.Object.
To answer your question take this example here:
package test;
public class Parent
{
public void printFoo()
{
System.out.println("foo");
}
public void printBar()
{
System.out.println("bar");
}
}
package test;
public class Child extends Parent
{
#Override
public void printFoo()
{
System.out.println("myFoo");
}
}
package test;
public class Main
{
public static void main(String ... args)
{
Parent test = new Child();
Parent test2 = new Parent();
print(test);
print(test2);
}
public static void print(Parent parent)
{
if (parent instanceof Parent)
{
System.out.println(parent.getClass().getName()+" is Parent");
parent.printFoo();
parent.printBar();
}
}
}
As you can see Child inherits from Parent and overrides printFoo() method. On printing those Parent objects you will get the following output:
test.Child is Parent
myFoo
bar
test.Parent is Parent
foo
bar
So to answer your questions:
1) yes
2) it will call the method of the parent class
3) it will invoke the overriden method - if this method contains a super-call then the parent's method will execute as well
4) No - if you specify f.e. Parent o = new Child() and implement a method in Child that is not present in Parent and you want to invoke the method of the child object, you will have to cast it back to Child ((Child)o).invokeYourMethod()