Multiple casting on inherited objects - java

interface I{
}
class A implements I{
}
class B extends A {
}
class C extends B{
public static void main(String args[])
{
A a = new A();
B b = new B();
b = (B)(I)a; //Line 1
}
}
I know this is not an actual code :)
I just need to know how the casting gets done at Line 1.
I know the reference variable 'a' gets cast to Class B/Interface I.
But I am not sure of the sequence in which the casting takes place..can someone tell me which cast gets executed first.
PS : I searched for similar posts but most of them were from C++.If a similar post is already there wrt to Java do point it..tx

a gets cast to type I first, and then to type B, as casting is right-associative.

Why would you cast it in the first place? This is multiple level inheritance but what happens here is all them methods in class I get inherited by class A, as class B inherits class A the methods in class A get passed onto class B. This means that all the methods class A inherits will also be in class B
That means class B is also a type of class I and therefore i believe there is no need to cast at all

Related

Why enum can't extend another class while all other classes can [duplicate]

This question already has answers here:
Java : If A extends B and B extends Object, is that multiple inheritance
(11 answers)
Closed 7 years ago.
I have a simple question:
If I declare a class A - means this class in implicitly inheriting from Object Class.
Now If class B inherits from class A
is this Class B also not Inheriting from Object class ?
If yes, does that mean writing the keyword 'extends' some how override the implicit inheritance ( from class Object) ?
All classes extend form Object, either implicitly or explicitly, directly or indirectly, the whole class hierarchy in Java ends up pointing at Object, which is at the root. For instance, when you write this:
public class MyClass extends Object {
Is exactly the same as this:
public class MyClass {
And if we have this:
public class MySubClass extends MyClass {
Then MySubClass extends from MyClass which extends from Object. It's a transitive inheritance relationship, and it occurs in only one direction: at no point in the hierarchy it will be possible that a single class extends from more than one class - that's why we say that in Java we have single-inheritance (as opposed to: multiple-inheritance.)
A inherits from Object and B inherits from A. So you have 3 levels of inheritance (2 explicit). There is no multiple inheritance here.
`Object`
|
`A`
|
`B`
When you 'extends', your class gets everything from the base class and adds extra stuff. So, if A extends Object, you've got all of Object in A. If B extends A, it gets all of A which also has all of Object. So, B now has Object, A and anything in B itself.
Multiple inheritence is when you extend a class from many things at once:
public class M extends SomeBase, AndAnotherBase {
This isn't allowed in Java. It adds complication in languages that do allow it because you can end up with class M being comprised of SomeBase, AndAnotherBase... and if they both already derive from Object... M would have 2 Objects in it. This starts to get tricky to deal with as you have to know which Object within M you're dealing with.
You specifically mention inheriting from Object, but if you are asking about inheritance in general between children and grandchildren, then yes, B will inherit from all predecessors.
public class A{
public String getAString(){
return "Hello from A";
}
}
public class B extends A {
public String getBString(){
return getAString() + " and Hello from B.";
}
}
public class C extends B{
}
public class Main{
public static void main(String[] args){
C c = new C();
// Inherited from A Inherited from B
System.out.println(c.getAString() + "..." + c.getBString());
}
}
This gives
Hello from A...Hello from A and Hello from B.
Notice C has no code in the class body. All functionality is being inherited.
Inheriting from Object is a little special in that it is implicit. There is no need to say extends Object on any class -- it's redundant. But the inheritance mechanism is no different.

use super () in Java?

I'm trying to learn java oop and i find some problem understanding the use of super method when i make some exemple . Please chek the code below .
can you please tell me why the super(); method doesn't refer to the superClass ? i don't understand .
superClass :
package javaapplication;
public class A {
protected String val;
public A(){
this.val = " Class A ";
}
}
subClass
package javaapplication;
public class B extends A {
public B(){
this.val = " Class B";
System.out.println(super.val);
}
}
Main Class
package javaapplication;
public class JavaApplication {
public static void main(String[] args) {
B a = new B();
}
}
output : run : Class B
why i got "Class B" ?
Because there is only one val variable, and your B constructor is setting it to " Class B".
You can use super.something to refer to something (member variable or method) on the superclass instead of the current class, but those will only be different if both classes declare something. In this case, both A and B are sharing the val defined by A.
A constructor in Java (now focus on your constructor of class B) ALWAYS calls either another constructor of class B if you explicitly tell you to do so with this(arguments...) or a constructor of the super class A if you explicitly tell you to do so with super(arguments...) or if you don't specify any call to another constructor it calls super(). And this call is the first instruction of any constructor. Unless the class you are talking about is Object.
So first the A constructor is called, setting val to "Class A" but then the constructor of class B continuous erasing that value and replacing it with "Class B".
Albeit a good example on how constructors work but in essence bad programming as this is not what you would do. A good programmer would add a contstructor in class A accepting the value for val and in class B you would call it using super("Class B") and val would be a private variable defined in class A.
Note that because class B extends class A, any instance of class B has the attributes defined in class B and class A, so super.val or this.val is doing referencing exactly the same variable. One could add a new variable val in class B but again this would be bad programming, if the compiler would accept this, I am not sure.
when you doB a = new B(); constructor of B is executed which internally call base class constructor as the first operation.So this sets the value of variable val as Class A. But then you are manually doing this.val = Class B which sets the value again as Class B
Just comment out this.val = Class B from constructor B, it will print Class A

Regarding overriding principle

I have a question and below is my code.
class A
{
int i=10;
public void m1() {
System.out.println("I am in class A");
}
}
class B extends A
{
public void m1() {
System.out.println("I am in class B");
}
}
class main2 extends A
{
public static void main(String...a) {
A a1= new B();
a1.m1();
}
}
Now my question; it's OK to get the variable "i" of the parent class A, but the method that I am getting is also of class A. Is it getting class B's method, as it overrides class A's method?
In Java, any derived class object can be assigned to a base class variable. For instance, if you have a class named A from which you derived the class B, you can do this:
A a1 = new B();
The variable on the left is type A, but the object on the right is type B. As long as the variable on the left is a base class of B, you are allowed to do that. Being able to do assignments like that sets up what is called “polymorphic behavior”: if the B class has a method that is the same as a method in the A class, then the version of the method in the B class will be called. For instance, if both classes define a method called m1(), and you do this:
a1.m1();
the version of m1() in the B class will be called. Even though you are using an A variable type to call the method m1(), the version of m1() in the A class won’t be executed. Instead, it is the version of m1() in the B class that will be executed. The type of the object that is assigned to the A variable determines the method that is called.
So, when the compiler scans the program and sees a statement like this:
a1.m1();
it knows that a1 is of type A, but the compiler also knows that a1 can be a reference to any class derived from A. Therefore, the compiler doesn’t know what version of m1() that statement is calling. It’s not until the assignment:
A a1 = new B();
is executed that the version of m1() is determined. Since the assignment doesn’t occur until runtime, it’s not until runtime that the correct version of m1() is known. That is known as “dynamic binding” or “late binding”: it’s not until your program performs some operation at runtime that the correct version of a method can be determined. In Java, most uses of inheritance involve dynamic binding.
Yes, it calls the B implementation of m1. When you run this code, it prints
I am in class B
just as expected. (Note that you don't actually use i in any of the code you posted, so I'm not sure what the first part was about...)
Yes it will invoke B's version of method, Since the object is of class B

Hierarchy of inner classes in Java

I am using a hierarchy of inner classes to represent some data in an application and I have run into an error message that I simply do not understand. My code can be boiled down to the following minimal example:
public class A {
public class B extends A {}
public class C extends B {}
}
Javac (and my IDE of course) fails to compile the code with the following error message:
A.java:3: cannot reference this before supertype constructor has been called
public class C extends B {}
^
1 error
I didn't write this anywhere. There is no more code than provided above, so I assume javac has generated something related to the inner class.
I have found another way to represent my data, so I am simply interested in a good explanation of why it doesn't compile.
You need an outer class instance to create an inner class instance i.e something like new Outer().new Inner();
To extend the inner class (Parent inner class) with another inner class (child inner class), you cannot call the constructor of 'parent inner class' because the instance of 'outer class' is not there.
Try like this,
public class A{
public class B extends A {
B() { }
}
public class C extends B {
C() {
new A().super();
}
}
public static void main(String args[]) {
}
}
Similar question : Odd situation for “cannot reference this before supertype constructor has been called”
The other poster is correct, but how to fix? Simply make your class static:
public class A {
public static class B extends A {}
public static class C extends B {}
}
Note that if your inner classes refer to fields of the outer class, you can't make them static, otherwise you can (and should - doing so reduces dependencies).
Your code compiles under Java 7.
The following workaround compiles under Java 6.
public class C extends B
{
public C()
{
A.this.super();
}
}
#saugok's link to the previous question quoted Joshua's explanation. Basically he argued that since C is subclass of A, C inherits A's members as C's members. Therefore B is also C's member. (For example a class literal C.B.class is valid.) Therefore he argues that C.this is the enclosing instance for B's super(), therefore C(){super();} is actually C(){C.this.super();}. Since C.this cannot be evaluated before super constructor, thus the error.
However this doesn't seem to be warranted by the language spec. See #8.1.3. Since B is not immediately lexically enclosed by C, B is not a direct inner class of C, there is no reason to say that B's direct enclosing instance must be an instance of C.
We need to pass B() an instance of A. It is true that C.this is an instance of A ( try this code: new C().new B().new C().new B();) therefore it could be a candidate. There is also another candidate, A.this. A.this is available and ready to use (it's passed in as the hidden parameter to C()).
According to javap, javac 7 compiles the code into
class B
private A this$0;
B( A a )
this$0 = a;
super(); // A()
class C extends B
private A this$0;
C( A a )
this$0 = a;
super( a ); // B(A)

Inheritance and the "this" keyword

Suppose that we have next situation:
Parent class A:
class A{
public A(){}
public doSomething(){
System.out.println(this.getClass());
}
}
with a child class B:
class B extends A{
public B(){}
public void doSomething(){
super.doSomething();
System.out.println(this.getClass());
}
}
and Main class:
class Main{
public static void main(String[] args){
A ab=new B();
ab.doSomething();
}
}
When I execute this code result is
B
B
Why does this, referenced in superclass A, returns B as a class when the reference is of type A?
It doesn't matter what the reference is, it's the instantiated object's class that counts. The object that you're creating is of type B, therefore this.getClass() is always going to return B.
Despite the fact that you are calling the doSomething() method of A, the this during that call is a B, and so the getClass() method is called on B not on A. Basically the this will always be a B whether you are using a method from superclass A, a method from B, or from A's superclass Object (the parent class of all Java classes).
this doesn't do anything for you in this situtaion. Calling this.getClass() is no different than just calling getClass();
So, A calls getClass(), which will return B if you are dealing with an instance of B that extends A.
Think of it in terms of runtime vs static types:
Animal a = new Cat();
The static type (in this case written on the left hand side) of variable a is Animal (you couldn't pass a into a method that required a Cat without a downcast) but the runtime type of the object pointed to by a is Cat.
a.getClass() exposes the runtime type (if it helps think of it as the most specific subtype).
Interestingly in Java overloaded methods are resolved at compile-time (without looking at the runtime type). So given then following two methods:
foo(Cat c);
foo(Animal animal)
Calling foo(a) would call the latter. To 'fix' this the visitor pattern can be used to dispatch based on the runtime type (double dispatch).
The output of program is correct.
When in Main class ab.doSomething(); line get executed doSomething() method of class B will be called then super.doSomething(); line will call doSomething() method of class A. As this keyword indicates reference of current object(ab is the object of class B see A ab=new B(); as constructor is of class B),i.e.System.out.println(this.getClass()); line in class A will print B only.
Again control will come back to System.out.println(this.getClass());in class B, So again B will get print.
In birdeye view only object of class B has created. That is why we are getting B B in output.

Categories