In the example below :
class Parent{
void fun() {
System.out.println("Parent class");
}
}
class Child extends Parent{
}
public class Main {
public static void main(String[] ar) {
Child ch = new Child();
ch.fun();
}
}
inheritance example,while instantiating object,we can create an object as Parent ch = new Child(); which is valid but why can't we have something like this Child ch = new Parent();
Thanks in advance.
Child ch = new Parent() is invalid because not every Parent is a Child.
Suppose you had a third class:
class AnotherChild extends Parent {int age = 2;}
The following would also be valid:
Parent otherChild = new AnotherChild();
If Cild child = new Parent() were to be made valid, then for the same reason
Child child = new AnotherChild()
Would also have to be made valid because AnotherChild is a Parent.
Now clearly, that is problematic, because Child is different from AnotherChild.
This example is chosen to make it obvious, but even a simple Parent object (new Parent()) is not a Child instance, because it wasn't instantiated with the Child class or any of its sub-classes.
All this is compile-time type checks, which ensures code safety and object/variable compatibility. One can use allowed casts to go around the problem, but if runtime objects are in fact of incompatible types, the execution would still fail.
In your example you have class Child extends Parent{. This means that a Child is a Parent but Parent is not a Child. Parent is the more generic parent class (Ironic) and Child is the more specific sub class. So you can do something like this:
Parent ch = new Child();
Because you are declaring the generic Parent object, and then instantiating it as a Child object. However you cannot do:
Child ch = new Parent();
Because you cannot declare it as the more specific Child object and then instantiate it as the less specific Parent object
Related
When I create a child object with parent reference like this Parent p = new Child();
then basically it is a child object with parent reference and with properties of both parent and child.
Then if it is a child object with parent type reference then why I cannot access child properties with it.
I am trying to do the following thing:
class Parent {
}
class Child extends Parent {
int a = 20;
public static void main(String[] args) {
Parent p = new Child();
System.out.println(p.a); //gives compile time error
// question is , p is parent type reference variable , but it is pointing to object of child
// class, then we should be able to access child properties from it, but we cant, why ?
}
You can do it by typecasting the reference to the child type.
class Parent {
}
class Child extends Parent {
int a = 20;
public static void main(String[] args) {
Parent p = new Child();
System.out.println(((Child)p).a);
}
}
It will throw a ClassCastException if p is not an Object of Child Type. So, it is better to check that p is an Object of Child by instanceof operator
if (p instancof Child) {
System.out.println(((Child)p).a);
}
The reason it isn't working is because parent classes don't have access to their childrens properties. You may be creating a Child class, but you assign it to a Parent object. Since Child is inheriting from Parent you are able to cast Child to Parent.
You are basically doing:
Parent p = (Parent) new Child();
In other words, You are creating a Parent object. There is no a attribue in the Parent class.
You can do:
class Parent{
int a = 20;
}
class Child extends Parent{
public static void main(String[] args){
Child c = new Child();
System.out.println(c.a); //gives compile time error
// question is , p is parent type reference variable , but it is pointing to object of child
// class, then we should be able to access child properties from it, but we cant, why ?
}
Here when you write Parent p = new Child(), then object of child class is created with properties of both Parent and Child class but the reference variable which is used to hold this object is of Parent type or you can say of Parent class.
When we want to access the instance methods or variables of any class, then the reference variable should be of that class only or its child class.
So we cannot access variable of child class with the reference variable of parent class.
Only the variables present in the Parent class can be accessed through the reference variable of parent class, doesn't matter you are using that reference variable to hold parent Class object or Child class object.
So only way to access 'a' instance variable in the code from p reference variable is to typecast p to Child type and then it can access variables of Child class.
`
Parent p = new Child();
System.out.println(((Child)p).a);
`
Here is all possible combination
There is difference at runtime while access member variable and member method
class Parent {
String s = "parent class variable ";
public void display()
{
System.out.println("Parent class method");
}
}
class Child extends Parent{
String s = "child class variable ";
public void display()
{
System.out.println("Child class method");
}
public static void main(String[] args) {
Parent p = new Parent();
Parent c = new Child();
Child cc = new Child();
System.out.println(p.s);
System.out.println(c.s);
System.out.println(cc.s);
p.display();
c.display();
cc.display();
}
}
Output :
parent class variable
parent class variable
child class variable
Parent class method
Child class method
Child class method
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.
Let there are classes:
class Parent {
public Parent getParent() {
...
}
}
class Child extends Parent{
public Parent getChild() {
...
}
}
//instantiating Child by using reference of Parent
Parent parent = new Child();
when I use:
//Works fine
Parent parentObject = parent.getParent();
When I use:
//Doesn't works
Child childObject = parent.getChild();
But when type cast object:
//Works fine
Child childObejct = ((Child)parent).getChild();
being as programmer this is something hectic to type cast explicitly for every call where I wanted to use child members by reference of parent class.
You declared a variable of type Parent named parent that is actually a Child.
If you don't cast the variable you can use only the methods of class Parent.
If you cast the variable to the real type (that in this case is Child) you can access to all the methods of class Child and its super class Parent too.
Note: to have less misunderstandings it is better to name the variable child also if you assign it to the type Parent, so it is clear that this is a real Child.
It is not so complicated. When you have an up-cast, it is simple for the compiler to determine the real type and do the cast because you know every class is simply extended from one parent.
But when you are down-casting an object, compiler can not infer that an object with a Parent reference is which Child object in the runtime because every Parent class can have multiple Child class.
Good Luck.
You would do something like this? I did not understand what you want...
abstract class Parent {
public Parent(){
}
public abstract void doStuff();
}
class Child extends Parent{
public Child() {
super();
}
#Override
public void doStuff() {
// TODO Auto-generated method stub
}
In the main do this
Child c = new Child();
c.doStuff();
//Doesn't works
// parent.getChild() returning Parent object and you are trying to assign to child object, which is not possible implicitly.
Child childObject = parent.getChild();
You can try some more cases by changing as below too:
class Parent {
public Parent getParent() {
return new Parent();
}
}
class Child extends Parent{
public Child getChild() {
return new Child();
}
// to access methods of child class using Parent class,
//You should Override(same method Names and signatures) the methods of Parent Class
public Parent getParent() {
return new Parent();
}
}
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();
I want to try and instantiate a Child object that extends Parent with the properties of a previously instantiated parent object. So something like this:
class Parent {
ClassName property1;
// Setters and getters
}
class Child extends Parent {
public Child(Parent parent) {
this.property1 = parent.getProperty1();
// + other properties
}
}
Parent parent = new Parent();
parent.setProperty1(prop);
Child object = (Child)parent; // Casting exception
Child object2 = new Child(parent); // This is not ideal
Is there any other way to achieve this?
First look up polymorphism. It seems you're not familiar with one of the main features of an OOP language.
Second, you need to instantiate your parent like this
Parent p = new Child();
Child c = (Child) p;