Java inheritance - java

Why does is print last "I'm a Child Class." ?
public class Parent
{
String parentString;
public Parent()
{
System.out.println("Parent Constructor.");
}
public Parent(String myString)
{
parentString = myString;
System.out.println(parentString);
}
public void print()
{
System.out.println("I'm a Parent Class.");
}
}
public class Child extends Parent
{
public Child() {
super("From Derived");
System.out.println("Child Constructor.");
}
public void print()
{
super.print();
System.out.println("I'm a Child Class.");
}
public static void main(String[] args)
{
Child child = new Child();
child.print();
((Parent)child).print();
}
}
Output:
From Derived
Child Constructor.
I'm a Parent Class.
I'm a Child Class.
I'm a Parent Class.
I'm a Child Class.

Because this is an example of polymorphism (late binding). At compile time you specify that the object is of type Parent and therefore can call only methods defined in Parent. But at runtime, when the "binding" happens, the method is called on the object, which is of type Child no matter how it is referenced in the code.
The part that surprises you is why the overriding method should be called at runtime. In Java (unlike C# and C++) all methods are virtual and hence the overriding method is called. See this example to understand the difference.

Both:
child.print();
and
((Parent)child).print();
Should return:
I'm a Parent Class.
I'm a Child Class.
In that order.
Casting an object to its base class doesn't change which method call gets made.
In this case, even after the cast, the child print method gets called and not the parent.

Even though you cast child to Parent this does not change its implementation of the method. This does not actually make it a parent. This is why you can do something like:
Image img = new BufferedImage(...);
Even though Image is abstract img is still a bufferedImage underneath.

Even though you are casting it as the Parent class, that does not mean it will use its parent's functions-- it will only treat the object as a Parent.
By saying ((Parent)child).print(); you are saying "Treat this object as a Parent Object, Not a Child Object". Not "Use the parent method implementations"
Thus if the child object had other methods you wouldn't be able to call them. But since print() is a method of the parent you can still call it, but it uses the actual object's (not the class its casted to) implementation.

in java if we call any method on one object then its calls the method by using sub most object ...............
here:
Object
|
|
Parent
|
|
Child <- sub most object
Case 1::
Child child = new Child();
child.print();
this calling child class method print by using child object... child is sub most
so it prints
output::
I'm a Parent Class.
I'm a Child Class.
Explanation: From child method it is calling parent method because of super.print(); method
so first line is I'm a Parent Class. after completion of parent method execution controls comes back to child method and prints I'm a Child Class.
Case 2::
((Parent)child).print();
if we call like this jvm calls print () method by using sub most object here sub most object is child object so it prints
output::
I'm a Parent Class.
I'm a Child Class.
Explanation: From child method it is calling parent method because of super.print(); method
so first line is I'm a Parent Class. after completion of parent method execution controls comes back to child method and prints I'm a Child Class.

Related

Is it possible to make methods non-virtual in Java?

i am newbie in java and i usually used c++ i just wondering this code works
public class ParentClass {
public void methodA() {
System.out.println("This is Parent A Method");
whoAmI();
}
public void methodB() {
System.out.println("This is Parent B Method and I am Calling Method A");
whoAmI();
methodA();
}
}
public class ChildClass extends ParentClass{
#Override
public void methodA() {
System.out.println("This is Child A Method and I am Calling Parents Method A");
whoAmI();
super.methodA();
}
#Override
public void methodB() {
System.out.println("This is Child B Method and I am Calling Parents Method B");
whoAmI();
super.methodB();
}
}
ChildClass c = new ChildClass();
c.methodB();
and I expected output like this
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Parent A Method
but was
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Child A Method and I am Calling Parents Method A
This is Parent A Method
so i realized that in java all non-static methods are by default virtual functions like virtual keyword in c++.
is there any way to make output like this?
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Parent A Method
You can wrap the methodA's impl of ParentClass in a seperate private method:
public class ParentClass {
public void methodA() {
interMethodA();
}
private void interMethodA() {
System.out.println("This is Parent A Method");
whoAmI();
}
public void methodB() {
System.out.println("This is Parent B Method and I am Calling Method A");
whoAmI();
interMethodA();
}
}
And the ChildClass remains the same.
The code - as is - does not compile since method whoAmI() is undefined. By removing the calls to this method, I was able to reproduce the output.
From what I understand, you want to ensure that methodA in Parent is called from methodB in Parent. Since dynamic dispatching is used in Jjava to determine which actual implementation is called, we have to enforce that methodA cannot be overridden. As #MarquisofLorne pointed out, C++ uses dynamic dispatch aswell, if methodA is defined as virtual in Parent.
To enforce that dynamic dispatch always results in a call to Parent's methodA, there are two general approaches that come to my mind: declaring methodA as final and declaring methodA as private.
Approach one: declare methodA in Parent as final
When going down this route, Child cannot re-define methodA, i.e. the code would result in a compile-time error if methodA is not removed from Child.
Ideone demo
Approach two: declare methodA in Parent as private
This approach is similar to the first approach, but allows you to retain methodA in Child, albeit the #Override-annotation must be removed since private methods cannot be overridden.
Ideone demo
You got:
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Child A Method and I am Calling Parents Method A
This is Parent A Method
Instead of
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Parent A Method
Simply Bacause, In Java calling methodA() or this.methodA() in your methodB() of ParentClass calls the method off of the calling object or instance, Yet the instance is an instanceof ChildClass. Java treats methodA() and this.methodA() as same. The this keyword in Java actually refers to the "currently running instance of the object you're using". Meaning, the overridding methodA() of ChildClass will be called instead of methodA() of ParentClass.
Here is a suggestion, to get the expected output, simply apply modifications on the overridding methodA() of ChildClass by commenting out the printing line.
Otherwise reference this for more details.

Question regarding result of "No late binding for static methods" [Java]

Given the code from Parent class and Child class:
class Parent{
public static void classMethod(){
System.out.println("ClassMethod in Parent");
}
public void hello(){
System.out.println("Hello from parent, call classMethod");
classMethod();
}
}
class Child extends Parent{
public static void classMethod(){
System.out.println("ClassMethod in Child");
}
}
If I have this in main method:
public static void main(String[] arg) {
Parent D = new Child();
D.hello();
}
Why is this the result? ->
Hello from parent, call classMethod
ClassMethod in Parent
So there's a child object of parent class calling an instance method which calls a static method.
I would understand why it calls the static method from the parent class if hello() was static as well, since the object type would be defined at compile time and it would be Parent. However, since hello() here is an instance method, it has to be resolved at runtime, and at runtime, isn't the type of the object the actual type, AKA Child type? So in that case, wouldn't it call the static method from the child object since the object is of child type at run time?
Note: this answer assumes the Child class extends Parent. Otherwise, the code in the main method just throws an error.
This is an example of up-casting and polymorphism. Because it's of the type Parent, its access is limited to the Parent class. When you call the hello() method, it is being called in the Parent class. Then, this method calls classMethod() but, because hello() is a method in the parent class, it calls it in the Parent class as well, which is why you are getting that as a result. The fact that it is static makes no difference: static methods can always be called by instance methods, but not always the other way around.
One thing I should point out is that, because of the line Parent D = new Child();, the object D does not actually have access to any of the static methods in Child even though it is that type. If you wish for D to have access to methods in both Parent and Child, you can use Child D = new Child();
With Parent D = new Child();, if you are calling a method, it must be in the Parent class and will run the method in the parent class - except for if there is an overriding instance method of the same name in the Child class, in which case it will run this method instead. It should also be noted that an overridden method cannot be static

Assigning a parent class to a variable of child type [duplicate]

Why reference variable of child class can't point to object of parent? i.e
Child obj = new Parent();
However we can do vice versa
Kindly answer with memory view (heap)
There is no reason which has something to do with the memory. It's much more simple. A subclass can extend the behaviour of its superclass by adding new methods. While it is not given, that a superclass has all the methods of its subclasses. Take the following example:
public class Parent {
public void parentMethod() {}
}
public class Child extends Parent {
public void childMethod() {}
}
Now let's think about what would happen if you could assign an instance of Parent to a variable of type Child.
Child c = new Parent(); //compiler error
Since c is of type Child, it is allowed to invoke the method childMethod(). But since it's really a Parent instance, which does not have this method, this would cause either compiler or runtime problems (depending on when the check is done).
The other way round is no problem, since you can't remove methods by extending a class.
Parent p = new Child(); //allowed
Child is a subclass of Parent and thus inherits the parentMethod(). So you can invoke this method savely.
The answer is too late.
I believe we can explain it in terms of memory. Maybe I'm wrong but this is what I'm thinking about this scenario.
// Assume, Required 2KB for execution
public class Parent {
public void display(){
System.out.println("From Parent");
}
}
// Total memory required for execution : 4bk
public class Child extends Parent {
#Override
public void display() {
super.display(); // 2KB
}
public void sayHello() {
System.out.println("From Child - Hello"); // 2KB
}
}
//2KB expect //4KB assigned
Parent parent = new Child();
//4KB expect //Only 2KB is assigning
Child child = new Parent();
Here the 'CHILD' class variable is expecting 4KB memory, but we are trying to assign 2KB 'Parent' class objects to it. So the compiler throwing exception.

Why does the following code gives an error?

I am trying to learn about inheritance and I came across this problem.
Here is the code:
import java.util.*;
class Parent
{
void show()
{
System.out.println("show from parent");
}
}
class Child extends Parent
{
public static void main(String s[])
{
Parent p=new Child();
p.show();
p.display();
}
void show()
{
System.out.println("show from child");
}
void display()
{
System.out.println("display from child");
}
}
And the error is:
G:\javap>javac Child.java
Child.java:15: error: cannot find symbol
p.display();
^
symbol: method display()
location: variable p of type Parent
1 error
If I'm able to access show() then why am I not able to access display() knowing that display() is inherited and is also present in the class definition of Child class.
You must understand the distinction between the run time type and the compile time type.
At run time your variable p holds a reference to a Child instance. So calling the show method will run the code in Child#show because this overrides the method Parent#show.
At compile time, the compiler can only know about the declared type of the variable. And this is Parent. So the compiler can only allow access to the fields and methods of type Parent, but not of type Child.
The display method simply isn't declared in Parent, hence the error.
if u want to call the display method of client then you must need to create object of child class.
eg.
Child child=new Child();
otherwise you need to write display method in parent class.
the rules is reference of parent class cant call member of child.
Display() method not in parent class.that is the error .you are access parent class show method not child class.if you are trying to access method in parent class using object you dont need methods in child class

Why this code doesn't call the subclass? Inheritance in Java

public class Parent {
public void printParent()
{
System.out.println("I am the Parent");
System.out.println("----this is ::---" + this);
this.printChild();
}
private void printChild()
{
System.out.println("This is my child");
}
}
public class Child extends Parent {
private void printChild()
{
System.out.println("I am the child");
}
}
public class RelationshipTester {
#Test
public void testRelation()
{
Child parent = new Child();
parent.printParent();
}
}
This is the output :-
I am the Parent
----this is ::---datastructures.lists.inheritance.Child#1a692dec
This is my child
The object is of the type Child , yet it doesn't call the child method and the parent one. I have given this.printChild();
In the Parent class, you have declared printChild as private ... and called it. A private method cannot be overridden. Your printChild in the Child class is not known to the Parent class.
If you were to change the private modifier to public, then you would have an override, and your example should output what you are expecting.
Why won't Java let you override a private method? Well, basically, if you could do it then there would be no way to write a class with an abstraction boundary that a child class could not break. That would (IMO) be a major language design short-coming.
Why doesn't Java report an error or warning? Well there is no error because this is legal Java according to the JLS. As for a warning ... if you compile Parent in isolation there is no problem, because the code as written is declaring and using a private method. If you compile Child in isolation, the compiler can't see the private method in the Parent class. (Indeed, it may not even exist in the version of the .class file for Parent that you are compiling against.) Only if you compiled Parent and Child at the same time might the compiler spot something a bit odd.
The keyword 'this' point to the current class instance and here is the private void printChild(). And then you have created an object of class Child at RelationshipTester class. The scope of the two function is private which means to is bounded to that class only. Thus, it won't overwrite the subclass and would execute the Base class's method.
private methods are not inherited. When you call printParent, you're calling a method on Parent and when that method refers to this, it's referring to an instance of that class (Parent), which has its own printChild method. Making Parent#printChild a protected method should give the expected result.
public class Child extends Parent {
protected void printChild(){
System.out.println("I am the child");
}
}
use protected, not private
In this program we have to remember 2 points:
If we create an object for a subclass (here child) then memory also created for the super class. That means if the method that we are calling that is not found in the child class then Java Virtual Machine goes to parent class and checks for the method that we are calling and if the method is found it will execute. If the method is found in child class itself it will not go to the parent class.
private, static and final methods can't be overridden.
Since the scope of the method is private it is not visible to other class.

Categories

Resources