How inheritance works indeed? - java

Please help me to understand how inheritance works.
If I have two classes, parent and child. When I create an instance of child is parent class instance constructed as well or not?
My code of Parent class.
public class Parent {
private char s;
#Override
public int hashCode() {
return s;
}
}
And Child
public class Child extends Parent {
private int i;
public Child(int i) {
super();
this.i = i;
}
#Override
public int hashCode() {
return i;
}
}
And finally the test
public class Main {
public static void main(String[] args) {
Child child = new Child(100);
System.out.println(child.hashCode());
System.out.println(child.getClass().getSuperclass().hashCode());
}
}
In output I get
100
2000502626
So the hashes of objects are different. It means that when I create instance of Child it is also created instance of Parent. Am I right?

Your question has nothing to do with inheritance.
the 100 you get from child instance's hashcode() method, as you expected.
The 2000502626 was from Parent.class, not Parent object.
Parent.class has type java.lang.Class
parent object has type Parent

When you create a Child object a Parent constructor is invoked as well, because a Child is a Parent.
But when you do this:
System.out.println(child.getClass().getSuperclass().hashCode());
you're not invoking Parents instance hashode. You are invoking hashCode() of the instance of the Class object.
See what child.getClass().getSuperclass() returns. It returns an instance of type Class not of type Parent/Child.
You cannot invoke Parents instance methods using child.getClass().getSuperClass() - that doesn't return the instance of a type, but an object representing this type.
Try doing this in child method:
#Override
public int hashCode() {
System.out.println("In child hashCode: " + i);
System.out.println("Parents hashCode: " + super.hashCode());
return i;
}
This will return 100 and 0, as Parents s hasn't been initialized.

Actually, there will be just one child object created. Since every child is a parent, the parent constructor will be invoked. if you print this in both child as well as parent instance methods, it will print the same (child object)
check - this question

If I have two classes, parent and child, When I create an instance of child is parent class instance constructed as well or not?
Yes. It works through Constructor. When you call constructor of your child class to create object, it first calls its parent class contructor and hence creates object of parent class

Yes. Both parent and child object are created. The child class constructor calls the parent(super) class constructor first, then only other functions of the child class are performed. As you can see from your own code two different values getting printed.

Related

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.

Java this in parent and child not working as expected

I'm misunderstanding something really basic with inheritance.
I have a parent class:
public class Parent {
String s = "Parent";
Parent () {}
String getS() {
return this.s;
}
}
and a child class:
public class Child extends Parent {
String s = "Child";
Child() { }
}
Main is like:
Parent parent = new Parent();
Child child = new Child();
Log.e(TAG, "parent:" + parent.getS());
Log.e(TAG, "child:" + child.getS());
I expect parent.getS() to return "Parent" and child.getS() to return "Child" but both return "Parent." Doesn't the method prefix determine the this for the method when called this way?
Thank you
Steve S.
Your getS() methods from parent class is inherited in Child class
and hence it is available for Child object.
Overriding is only for methods and not for instance variables.
So even if you define a new variable with same name, it will not take effect as it will not be overridden
You should create a getter method i.e. getS() in the Child class to retrieve "Child" when you call child.getS() in your main method. In this way, you override the getS() method that was inherited from the Parent class.
The way you would set the s-member in the parent-portion of a child-class, would be to offer a protected constructor (it could, of course, also be public):
protected Parent(String s) { this.s = s; }
which sets the string to the given value. You would then call this constructor as the first call in your child-constructor with
super("Whatever you want");

Accessing private instances in child class

I've seen answers for questions related to mine on Stack Overflow, but I am still left with some ambiguity. A parent class method has access to its own private instance variables. If a child class inherits the class, what happens when the getA() method is called on an instance of the Child class? Does it return the a from the Parent class or the a from the Child class?
class Parent {
private int a = 10;
public int getA() {
return a;
}
}
class Child extends Parent {
private int a = 22;
}
public class Test {
public static void main(String []args) throws Exception {
Child c = new Child();
System.out.println(c.getA());
}
}
As the Method getA() is inherited, if you call this Method, you'll always invoke the Parent's Method.
The current Object will be treated as a Parent and not as a Child, and the Parent's a will be returned.
Even though you have your own variable a, this variable wont override the Parent's a. They are different from each other, have different addresses and different values.
If you want getA() to return Child's a, you need to override the Method to return your new variable.
class Child extends Parent {
private int a = 22;
#Override
public int getA(){
return a;
}
}
You could also "go crazy" and do stuff like the following:
class Child extends Parent {
private int a = 22;
#Override
public int getA(){
int superA = super.getA();
return a+superA;
}
}
That way you could return the sum of Parent's and Child's a.
(Just an example)
This is a duplicate of this SO post.
The variable a in subclass Child hides the a in the parent class Parent.
Private variables are local to the class and in your code you are inheriting the properties of the parent class so you can access getA() and it will return the parent's attribute.
And you cannot access child's variable unless you have public getter method for child attribute.
Stick to basics "private member variable will only be accessed within the class by its own member functions and fields cannot be inherited" so basically when you are accessing the private variable A in parent class , the method is supposed to access its own private member rather then the private field of any child class.
Fields cannot be overridden.
In your code, an instance of child (like the one referred to by c) has two different fields, which are both called a.
You cannot access Parent's private variables inside Child, full stop. That's the entire point of private. There is nothing* you can write inside Child to make the parent's a field equal 22.
* Technically, you could with reflection. Reflection doesn't count though, since its purpose is essentially to allow you to break things, and do things that are otherwise impossible.

Why am I able to access child methods in the parent class?

I have a problem with the understanding of inheritance in Java: I am able to access overwritten methods of the child class when I cast it back to the parent class.
As an Example there are given the two following classes:
The parent one:
public class Parent {
public void whatAreYou() {
System.out.println("parent");
}
}
And a child class:
public class Child extends Parent {
#Override
public void whatAreYou() {
System.out.println("child");
}
public void onlyChildrenCanDoThis() {
//...
}
}
When I now do the following:
Child c = new Child();
Parent p = c;
p.whatAreYou();
I get this output:
child
This is very strange for my understanding of inheritance in Java. I would expect to get a parent output, because I narrowed the child class to the parent class, and with that I should just have access to variables and methods of the parent class.
This is working with p.onlyChildrenCanDoThis(), as I cannot access it, because it is not implemented in the parent class...
...but with overwritten methods Java is not behaving that way! Why is that?
What you are dealing with here is polymorphism. c is instantiated as new child(), and that is why you get child as an output. The fact that p is of type parent doesn't change that fact, it still points to the instance of child.
Here's what you have done
child c = new child();
You created Object of Child class and assigned its reference to c.
parent p = c;
Here you have copied reference of child object to p. Remember the object is still Child's object not parents's object.
p.whatAreYou();
Here you have called whatAreYou method. you are calling this using reference variable p which is pointing to object of child. hence child's method will be called.
Another Interpretation
The output is as it is because of the line parent p = c;
Imagine this:
class Car {
public void whatAreYou() {
System.out.println("Car");
}
}
class Cadillac extends Car {
public void whatAreYou() {
System.out.println("Caddillac");
}
}
If you now say
Cadillac coolCar = new Cadillac();
Car testCar = coolCar;
testCar.whatAreYou();
It becomes pretty obvious that the output is, "Cadillac", no? This is how you can look at inheritence:
Cadillac objects are allways Cars. Car objects can be Cadillacs
Since I explicitly set the Cadillac reference coolCar to point to an object of a Cadillac, and the Car reference testCarto point to the same object, we get the output "Cadillac"
To make it even more obvious, you could even say
Car coolCar = new Cadillac();
Car testCar = coolCar;
testCar.whatAreYou();

Categories

Resources