why subclass reference can't hold superclass object in java - java

class One{
}
class Two extends One{
}
class Main{
public static void main(String[] args){
Two t = new One(); // invalid
}`
}
I am not able to understand the reason behind it, why child class reference could not hold the object of parent, while superclass reference can hold the object of subclass.

Because a dog has all the behaviours of an animal, but something that is only known to be an animal is not guaranteed to have all the behaviours of a dog.

Every Child is a Parent but not every Parent is a Child. Rule of Inheritance.

If we think in terms of set theory, compared to the parent class, the child class is a super set.
The child class has all possible properties and methods, compared to the parent class.
So, a parent class object can refer to its child class object, as the child class object includes the parent's methods and properties.
Thinking vice versa, since a parent class object does not have all the methods and properties needed by a child class, a child class object cannot refer to a parent class object.

The type of TWO cannot be an instance of ONE because there are members and methods that TWO has which ONE doesn't have. However, The type of ONE can reference TWO because TWO has everything that ONE has.
For example, if ONE can WALK and TWO can also RUN, then if you have an object from the type ONE then is needs to be able to WALK. So if ONE references TWO that works because TWO can walk.
But when you have an object of type TWO then it needs to be able to RUN so you cannot reference it to ONE which cannot RUN.

Consider class Two contain a method, let say demo().
class One{
}
class Two extends One {
void demo(){
System.out.println("in Two");
}
}
class Main{
public static void main(String[] args){
Two t = new One(); // Suppose this is valid at compilation time
t.demo();
}
}
Now suppose if compiler doesn't give us error when we create object of class One i.e. child reference holds object of parent. Further t is reference of class Two, hence t.demo() is valid.
Now when program runs, reference t contains object of class One. When program reaches t.demo() then t contains object of class One and class One does not have any method named demo().
So to prevent such type of errors compiler checks if object is type of reference i.e. object class is same as reference class or child of reference class.

Related

Every class is implicitly a subclass of Object Java

I'm reading Java Inheritance Docs and got this paragraph, but I don't what is mean of this. Can any body explain?
Excepting Object, which has no superclass, every class has one and
only one direct superclass (single inheritance). In the absence of any
other explicit superclass, every class is implicitly a subclass of
Object.
Edited
Another point related to this question:
And due to Object is superclass, NetBeans show me extra method list when I try to call any Member of class with object reference? All those methods are declared in Object class?
It means that,in java the Object class is the parent class of all the classes by default. In other words, it is the topmost class or the base class of java. All other classes inherit the properties of Object class.
Meaning of implicitly - suggested though not directly expressed.
If samething applied in Java classes. Consider there is a class called Test.
If you write
public class Test {....}
That is equivalent to
public class Test extends Object {....}
Though you didn't write it, it's equivalent to it. You need not to write extends Object manually. Internally JVM treats that your class is extends Object. Since the part after extends is your class, here Object is your super class.
But,
When you write
public class Test extends BigTest{....}
Things changed now. You are telling BigTest is my parent class. That means you are implicitly writing yourself that BigTest is my parent. Interesting part here is though BigTest is your direct Parent class, internally Object also your Parent.
So now you have 2 parent classes. One is BigTest which you mentioned and other is Object. If you didn't mention anything, only Object is your Parent.
Edit :
This is the reason that you will see extra list of method when you will try to call any member of class with object-reference. Those methods are declared in Object class.
why java do this? any feature of this?
Yes. There are benefits of it. Main reason is to reduce the code duplication.
Continue reading here .... Why Object as super class in Java ?
It means that the following two classes are the same:
class MyClass {
}
class MyClass extends Object {
}
If a class definition doesn't specify extends, the class implicitly extends Object.
The Object class comes with the JRE, you use any class without it. Java does this so you can have a reference to any object e.g.
Object o = x;
This works because no matter what x is, it is also an Object.
Note: even int[] class is a sub-class of Object.

Java: Number of References to Outer Classes using Inheritance

Every non-static nested class keeps a reference to its outer class for the purpose of accessing the outer class's methods and fields.
Given this class...
class Parent
{
// some fields
// some methods
protected class NestedParent
{
// some other fields
// some other methods
}
}
... and this class:
class Child extends Parent
{
// some fields
// some methods
protected class NestedChild extends NestedParent
{
// some other fields
// some other methods
}
}
The class NestedParent has a reference to its outer class Parent; because NestedChild inherits from NestedParent it will have that reference, too. However, will NestedChild also have a separate reference to Child or will it use the inherited reference and cast it to Child for accessing Child's members?
I ask this question because I am trying to figure out the final size of NestedChild. If it has one additional reference of 4 bytes this is a big waste of memory in the project I am working in since there will be millions of instances of NestedChild.
Your understanding is little wrong as every Child class instance is of type Parent class and so Child class instance is the outer enclosing class for NestedChild
The NestedChild class will have a reference to Child instance only,so no issue of memory here.Java works by reference and not by actual Object unlike C(there is no concept of pointers,only references).The Child instance holds reference to Parent Class members(see the Object graph).
Object references are part of the Object heap and class definition lies in method area.
EDITED FOR CLARITY:-
Try commenting out "extends Parent" from Child,you would see that compiler complains that no enclosing object of type Parent is present for NestedChild inner class.

Why exactly does the no-arg constructor of parent class get invoked while creating an instance of child class? [duplicate]

I have a question about inheritance in Java.
I have two classes A and B , and class B, inherits from A:
public class A {
public A() {
System.out.println("Hi!");
}
}
public class B extends A {
public B() {
System.out.println("Bye!");
}
public static void main(String[] args) {
B b = new B();
}
}
When I run program B, the output is:
Hi!
Bye!
Question : why the constructor of class A is invoked, when I create and object of class B ?
I know that B inherits everything from A - all instance or class variables, and all methods, and in this sense an object of B has all characteristics of A plus some other characteristics defined in B. However, I didn't know and didn't imagine that when I create an object of type B, the constructor of A is also invoked.
So, writing this:
B b = new B();
creates Two objects - one of type B, and one of type A.
This is getting interesting,
can somebody explain why exactly this happens?
It doesn't create two objects, only one: B.
When inheriting from another class, you must call super() in your constructor. If you don't, the compiler will insert that call for you as you can plainly see.
The superclass constructors are called because otherwise the object would be left in an uninitialized state, possibly unbeknownst to the developer of the subclass.
Your subclass actually looks like this after the compiler inserts the super call:
public class B extends A {
public B() {
super();
System.out.println("Bye!");
}
}
It doesn't create 2 objects, it only creates one instance of B. The reason the super class constructor is invoked is because, like you said, B has all of the fields of A, and these fields need to be initialized.
Remember inheritance is an "is a" relationship between the base class and the subclass, thus every time you have an instance of a subclass, by definition you will also have an instance of the base class (as part of the instance, not as two separate instances). To initialize the base class properly the constructor is called.
Additionally, think about what would happen if you subclass depended on some internal state of the base class. Wouldn't you want the instance of the base class to be initialized then?
This is done because the constructor is used to initialize the object. Since B is also an A, it calls the constructor for A first, then the constructor for B.
As a side note, you can use super(arg1, etc) to choose which constructor of A is called based on the parameter types you pass... but it must be the first line in the constructor.
The constructor contains all of the initialization for A. You are not creating two objects. You are creating one object, then running the initializer for the superclass to initialize its members, and then running the initializer for the deriving class to initialize its members.
It does not create two objects, it just creates one object b. b is of type B and of type A. A constructor is basically saying here is what you need to do to construct me. So when you are creating a new "B" instance, you are building an object that is both a B() and an A(). Imagine the following scenario:
class Q {
int i;
public Q() {
// set default value
i= 99;
}
}
class Z extends Q {
public Z() {
}
}
If the constructor for Q WAS NOT called, how would i get its default value?
The creation of B does not create an extra A.
But by creating B, you create a kind of A, because B is a A.
Java/C++ call the constructor of A for your implicitly. Why? Language design. But doing so is fine, because the constructor of A might contain some initializations. And as B uses all the features and bugs of A, these features better be initialized properly.
The constructor of a class is very important concept in most OOP
Classes, by providing state and the means to manipulate that state, allow the easier maintenance of invariants. The constructors role is to get the class into a state that conforms to those invariants (or throws thus forbidding usage of an invliad object).
this is somewhat looser than intended in many languages since the constructor is allowed to pass its own 'this' reference elsewhere but this is at least under the control of the class (as such it can know that it is in a sufficiently stable and valid state for it to be accessible to the rest of the world)
Inheritance makes this complex since B is-a A in a very real sense and thus can invoke any of the methods provided by A. The parts of B that are A should therefore get their chance to initialize themselves before B gets a look in, thus the constructor for A is called before the real work of the B constructor begins.
If A intializes members in it's constructor and you forget to call super in your derived class then the members of A could be in a bad state. Java is trying to stop you from shooting yourself in the foot.
Only one object is created, both contractors are running on the same object.
The reason is simple, as you know B has all the variables and methods of A, so if some variable of A needs initializing so methods of A can work someone has to initialize it - and that someone is A's constructor.
for example:
public class A {
public A() {
x = 1;
}
private int x;
public int getX() {
return x;
}
}
public class B extends A {
public B() {
}
public static void main(String[] args) {
B b = new B();
System.out.println(b.getX()); // should print 1
}
}
When new object is create(B), inside B A object is created(because of extends keywords) . In B class JVM search B class constructor, but due to extends keywords it goes to super class constructor. inside A class x value is initialized. But x is private so that we can access outside class throw getXxx() method and get the result.
When sub class object is created then internally it was not created for super class object.But the memory should be allocated for super class members.
In java when you create an object of child class the constructor of parent class is always called because Object class is the parent of every super class and when you call the constructor of Object class then only your object is created and java does not support multiple inheritance in case of class so if you extends any other class then the relationship between you child class and the Object class is through the Parent class so to call the constructor of the Object class the constructor of Parent class must be called.
Every superclass has a constructor and each constructor up the hierarchy runs at the time an object of a subclass is created.
if super class object is not created then how sub class is accessing super class non static methods and variables.
I studied that non-static methods and variables can be accessed only through objects..

It is said that when we create an object of a sub-class automatically the objects of its super-classes get created. is it true?

it is said that when we create an object of a sub-class automatically the objects of its super-classes get created. is it true ? if yes then what if the super class is an abstract class.
No, that's not true. An object has only one type: the class that you instantiated. The object will also contain all the fields of the superclass, and it will be possible to call all the methods of the superclasses (that have not been overridden) on the object, but it is still only one object.
For example, say you have:
class A {
int i;
}
class B extends A {
int j;
}
If you instantiate new B(), you get one object that has storage for two fields, i and j.
The subclass "is-A" instance of the superclass, so it doesn't create a different object, your subclass instance IS the super class instance.

Understanding the concept of inheritance in Java

I am just refreshing the oops features of the java. So, I have a little confusion regarding inheritance concept. For that I have a following sample code :
class Super{
int index = 5;
public void printVal(){
System.out.println("Super");
}
}
class Sub extends Super{
int index = 2;
public void printVal(){
System.out.println("Sub");
}
}
public class Runner {
public static void main(String args[]){
Super sup = new Sub();
System.out.println(sup.index+",");
sup.printVal();
}
}
Now above code is giving me output as : 5,Sub.
Here, we are overriding printVal() method, so that is understandable that it is accessing child class method only.
But I could not understand why it's accessing the value of x from Super class...
Thanks in advance....
This is called instance variable hiding - link. Basically you have two separate variables and since the type of the reference is Super it will use the index variable from Super.
Objects have types, and variables have types. Because you put:
Super sup = new Sub();
Now you have a variable sup of type Super which refers to an object of type Sub.
When you call a method on an object, the method that runs is chosen based on the type of the object, which is why it prints "Sub" instead of "Super".
When you access a field in an object, the field is chosen based on the type of the variable, which is why you get 5.
index is simply a field belonging to the parent class. Because it belongs to the parent class, it means that it's an attribute to all the children.
To simply the concept:
A Class Animal could have a field age and a field name
All sub classes would share those attributes, but would have additional field(s), which would be contained into those children classes only. For example hairColour could be the only attribute of the Dog class, but not to the class Snake, which could have a simple unique attribute venomous
In this structure all Animal have a name, and an age, which is what could define Animals in general, an each specie have some extra attribute(s) unique to them, which are contained into their respective sub classes.
Your code doesn't clearly show this, as your sub class has no constructor, indeed no super constructor call. As explained by Petar, your none private attribute index is access from the super class
This happens coz functions follows runtime binding whereas variables are bound at compile time.
So the variables depend on the reference's datatype whereas the functions depend on the value represent by the reference's datatype.
When we assigning the object of sub class to parent class object only the common property both class can be accepted by the parent class object , is called as object slicing
that's why the value of patent class 5 is printed its only happen with property not a method

Categories

Resources