Java inheritance behaviour with instance of - java

I have the following
Class A extends B
B class is an abstract class
What will be returned if I do:
A a = new A();
a instance of B?
If it returns false, which solution I could use for having true as result?

//Define these classes.
class A {} //It can be an abstract class as well.
class B extends A {}
//Main code.
A b = new B();
System.out.println(b instanceof A); //prints true.
If you try B instanceof A // you will get a compilation error because B is not an object, but it is a class name.

"x instanceof y" returns true if "object" x is instance of class "y". The word instance is used for an object. Since A and B are both classes the code should return a compilation error

Related

Instanceof does not show compile error with interface, but with abstract class does

I think the title is self explanatory.
So suppose I have this code:
interface A { }
abstract class B { }
class C { }
C c = new C();
System.out.println(c instanceof A); //fine
System.out.println(c instanceof B); // compile error
In a comment from the question I read this:
The compiler can never know whether a given type doesn't implement an interface because a potential subclass could implement it.
So if for interface this works, why it should not work for an abstract class ? It also should be extended by some other class, as it can't exist by it's own. Can someone clarify this?
Update
Compile message:
Error:(22, 28) java: incompatible types: C cannot be converted to B
It is simple: C extends Object. No subclass of C could possible extend B. You can't add another base class, because Java doesn't support multiple inheritance.
Whereas a subclass of C can very well implement that additional interface.
But there is simply no way how a C object could also be a B instance.
So:
D extends C implements B // obviously all fine
whereas
D extends B extends C
is impossible. Because B is already defined to not extend anything but Object. Of course, the "trick" here is that both classes B, C are both known, and as said: C isn't extending B.
Take for example
class D extends C implements A{}
C c = new D();
The compiler can immediately tell that c can never refer to an instance of B because if a class extends C it cannot extend B also. As the above example shows, the same cannot be said of interfaces.
That is because it's strictly impossible to create instances of an abstract class in java.
The operator instanceof is called from class Object and cannot be called if there is no instance of a class that revoked it (object).

instance Of Operator in java

class A {}
class B {}
public class Demo {
public static void main(String[] args) {
A a = new A();
System.out.println(a instanceof B);
}
}
This code is giving compile time error.
How can I use instanceof to give false instead of compile time error when object is not an instance of class specified.
Java knows an A cannot be a B so it won't compile. If you change the line to
Object a = new A();
it will compile (and return false) as it can no longer tell if an Object can be cast into type B.
If class A and B are not related through inheritance, then compiler will throw an error when you try to perform a instanceof B
In your case, A is NOT a subclass of B, so you can't do an instanceof check like a instanceof B
But, if you change your classes like below:
class A {}
class B extends A {}
public static void main(String[] args) {
B b=new B();
System.out.println(b instanceof A);
}
Now b instanceof A will return true because B IS-A (type of) A
You can read the Java doc here on the same subject:
The instanceof operator compares an object to a specified type. You
can use it to test if an object is an instance of a class, an instance
of a subclass, or an instance of a class that implements a particular
interface.
You can use this :
System.out.println(a.getClass().equals(B.class));
Instead of :
System.out.println(a instanceof B);
Quoting JLS Sec 15.20.2:
If a cast (§15.16) of the RelationalExpression to the ReferenceType would be rejected as a compile-time error, then the instanceof relational expression likewise produces a compile-time error. In such a situation, the result of the instanceof expression could never be true.
(Where they are describing RelationalExpression instanceof ReferenceType)
You can't write B b = (B) a; either, because A and B are both classes (*), and are unrelated, in the sense that A does not directly or indirectly extend B, nor vice versa.
As such, a reference to an A can never contain an instance of a B, so it is nonsensical to test this. As such, the compiler stops you from testing this, as it likely indicates a logical error.
(*) You could write a instanceof B if B were an interface, because a might refer to a subclass of A which additionally implements B, e.g.
class ChildOfA extends A implements B {}
A a = new ChildOfA();
System.out.println(a instanceof B); // fine.

Create object in java [duplicate]

This question already has answers here:
What does it mean to "program to an interface"?
(33 answers)
Closed 6 years ago.
What does this statement mean:
B b = new C();
Does it mean that b is object of class B and C at the same time? Can anyone clarify this in detail.
I know
B b = new B();
when I create object from class B, but I don't know what this statement mean
B b = new C();
In this statement, C is clearly has an "isA" relationship with B - i.e., B is either C's ancestor or an interface that C implements.
In other words, you have one of
class B { ... }
class C extends B [ ... }
or
interface B { ... }
class C implements B { ... }
where there could also be combinations of these and B and C could be more than one inheritance step apart, for instance
class B { ... }
class X extends B { ... }
class C extends X { ... }
You're creating a C instance and assigning it to a variable of type B, meaning you'll only be able to use methods visible via B (without explicit casting, at least).
B b = new C();
It means that the reference of B type refers to the instance of C type. The C class is a subclass of the B. In this case, you can use methods that are defined in the B class by using overridden versions of these methods in the A class (if such methods exist). That mechanism called polymorphism.
Imagine, you have two subclasses of the B class, for example, A and C. You will write a general implementation in methods of the parent class. Then you will override a behavior of some methods in the child class to make them more specific.
B b1 = new A();
B b2 = new C();
// the same type of references
b1.performAction();
b2.performAction();
// the same methods, but the different code will be executed
// if the methods are overridden in the childs

Class/object Casting [duplicate]

This question already has answers here:
Downcasting in Java
(12 answers)
Closed 8 years ago.
I am getting an exception for the following code.
class A {
void foo() {
System.out.println("Running foo()");
}
}
class B extends A {
void foo() {
System.out.println("Overidden foo()");
}
}
public class Casting {
public static void main(String[] args) {
A obj = new B();
obj.foo();
// B ref = (B) obj;
// ref.foo();
B ref = (B) new A();
ref.foo();
}
}
But if I run
B ref = (B) obj;
ref.foo();
instead of
B ref = (B) new A();
ref.foo();
it works properly.
Can anyone explain what is happening here.?
obj is an instance of B because you created it using the contructor of class B. This is why B ref = (B) obj; works fine.
In B ref = (B) new A(); you are simply casting an object of type A created using the constructor of A (which is the parent class) to a subclass type which will cause a java.lang.ClassCastException. The opposite casting would work, i.e.
A ref = (A) new B();
ref.disp();
in which case you converting an instance of a subclass to its parent which is fine since an object of type B is also an instance of A.
It's pretty easy to explain.
By doing new A() you receive an A-object. Then you tell the JVM it's of type B, but that's obviously wrong and the JVM can't cast from A-type to B-type, how should Java know how to do that? It's not sure that A has the same methods as B. It's just a parent, B could have methods A hasn't. If you could cast from A to B you could have B objects that don't behave like B objects and don't have the B classes methods.
If you have a B-object you can treat it like a A-object because every B-object has at least the same methods, constructors and ivars.
An example using ducks:
Imagine you have got an abstract Duck class (but you didn't declared it as abstract). This class is the parent class of all other duck classes and also including RubberDuck. As reason of that the Duck class just has some basic methods like getSize but no method like walk or eat (a rubber duck can't eat herself).
What would happen if you create a duck object and downcast it to BuffleheadDuck and you would try to invoke the walk method? A BuffleheadDuck duck knows how to walk, but an abstract duck can't walk.

why i am getting ClassCastException in this case

Please tell me why i am getting ClassCastException in this case
I have type casted , the source of B class to A as shown below , but why i am still getting ClassCastException here .
public class A extends B
{
}
public class B {
public String getData() {
return "B";
}
}
public class Main {
public static void main(String args[]) {
A a = new A();
B b = new B();
a = (A) b;
System.out.println(a.getData());
}
}
It becomes more obvious if we play with different classnames:
public class Car extends SomethingWithWheels {} // was A extends B
public class SomethingWithWheels {} // was B
public class Train extends SomethingWithWheels {} // aahh, some C extends B
Now, lets cast again:
SomethingWithWheels somethingWithWheels = getItFromSomewhere();
Car car = (Car) somethingWithWheels;
The compiler has to complain, because somethingWithWheels (B) could be a Train instance (C), which can't be cast to Car (A).
You can't cast a base class to derived class. You can do the other way round though.
Because your instance "b" is not of type A (B does not extend A), so when you cast "b" to A it fails.
The opposite would work (casting an instance of type A to type B)
Because an instance of B is not an instance of A. It's really that simple.
If you create an instance of A, it's also a B - because that's what the subclassing means. However, if you create an instance of B, that is not an A, and can't be assigned/cast as such.
The only time you can cast is if the run-time class of an object is compatible with the type you're trying to cast to. You can't change the class of an existing object - which is what I think you might be trying to do here - only tell the compiler "look, I know it's really something more specific".
So as a counter-example, the following would work:
public static void main(String args[]) {
B b = new A();
A a = (A) b;
System.out.println(a.getData());
}
In this case, the variable b is declared to hold a reference to a B. It turns out that you populate it with an instance of A, but for the rest of the program the compiler isn't allowed to assume that b is an A, because it's not guaranteed. Since you know it's an A in your specific case, you insert the cast, which causes a run-time check that the object actually is an A. This succeeds, and from that point on you can call methods specific to A on your a variable.
In this case however there is no reason at all to do any casting - there are no extra methods available on the subclass that you'd need to call, and no methods which only take an A but not a B. Even if A overrode getData to do something different, you would still get this behaviour if invoking through a B reference.
You are downcasting and you try to cast a supertype to a subtype, thats why it does well during compilation but fails at runtime with ClassCastException.
You can call:
System.out.println(a.getData());
after removing the line where you try to cast the types

Categories