Interfaces and classes in JAVA - java

Lets have following Class Diagram as an example
I made similar classes in java like below
public class B {
}
public interface C {
}
public class A extends B implements C {
}
public class D {
C c = new A();
C c1 = new B(); // Error, Type mismatch: cannot convert from B to C. WHY ?
C c2 = (C) new B(); // Works fine. This makes me confuse ... What does this actually mean ?
}
Can anybody explain this ?

C c1 = new B()
You can never instantiate class B as interface C since it doesn't implement interface C.
C c2 = (C) new B()
In the second case you are explicitly casting the instance of B to type C. The compiler allows this, but you'll get a run-time exception.

Why C c2 = (C) new B(); does not compile: see Ankur Shanbhag's answer.
C c2 = (C) new B(); may compile well, but since c2 is a B object and thus cannot be converted to C, this will throw an exception at runtime.
I made an example:
public class D {
public static void main(String[] args) {
C c2 = (C) new B();
System.out.println(c2);
}
}
And received an exception:
Exception in thread "main" java.lang.ClassCastException: casting.B cannot be cast to C

C c1 = new B(); // Error, Type mismatch: cannot convert from B to C. WHY ?
You can refer to derived classed only through super class references. In your case, C is a not a super class of B. Hence the error
C c2 = (C) new B(); // This makes me confuse ... What does this actually mean ?
Compiler wont allow you to perform the above casting. To cast from one type to another, both the classes must be in the same Object hierarchy.

Extends means "is a kind of".
A is a kind of B, so it has all the features of B.
However, B isn't a kind of A, so it doesn't necessarily have all the features of A, including implementing the interface C. That's why you get the type mismatch.
But in this case:
C c2 = (C) new B()
Casting tells the compiler "Don't check this because I know what I'm doing." So it may compile.
But if at runtime the object you actually cast can't be typed as a C, you'll get a ClassCastException. In your case, you are casting a B to a C, and a B isn't a kind of C any more than it is a kind of A. So you'll get the exception.

Related

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

Inheritance in Java simple clarification

So, I have this:
public class A {
public int a = 0;
public void m(){
System.out.println("A"+a);
}
}
And this:
public class B extends A {
public int a = 5 ;
public void m (){
System.out.println("B"+a);
}
public static void main(String[] args) {
A oa = new A();
B ob = new B();
A oab = ob;
oa.m();
ob.m();
oab.m();
System.out.println("AA"+oa.a);
System.out.println("BB"+ob.a);
System.out.println("AB"+oab.a);
}
}
Output:
A0
B5
B5
AA0
BB5
AB0
I don't understand why oab.m(); output is B5 instead of A0. Can someone explain this to me?
That's the whole point of polymorphism. The concrete type of oab is B (since the object was created with new B()). So the method B.m() is called.
Look at the Animal example in http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29 to understand why it's useful. When you have an animal, and this animal is a Cat, you expect it to say "Meow!" when you make it talk.
B ob = new B();
A oab = ob;
Similar as
A oab=new B();
I don't understand why oab.m(); output is B5 instead of A0
Because you creating object of B and referencing it to A so m() is being inherited and that's why B's version of m()is being called.
A oa = new A();
B ob = new B();
A oab = ob;
From the code above ob is an instance of class B. It can be stored in a variable of class A as A extends B. But as the stored Object instance is of B and hence it is not aware of A's m() function.
Hence the out put is B5
In inheritance actual method invocation depends on the type of the actual object and not on the type of the reference.
B ob = new B();
A oab = ob;
Here oab is a reference variable of type A but it is pointing to object of type B i.e. ob so at runtime oab.m() will invoke overridden m() method from class B
In Java there is something like late binding (polymorphism). It means that code of method is not linked while compilation time (early binding), but while runtime. While invoking oab.m(); JVM is checking actual type (class) of object from aob reference (in your case B) and based on that info invoking code of method from that class. That is why oab.m(); returns B5.
You also need to know that late binding works only for methods, not fields. For fields value will be determined by reference type, so oab.a will return 0 not 5.
Imagine you had the following:
public class C extends A {
public int a = 7 ;
public void m (){
System.out.println("C"+a);
}
Now if you had this in your Main method...
C oc = new C();
A oac = oc;
oac.m();
...you would want that last call to output the stuff that is specific for the class C.
The point is that B is an A, and C is an A, but each of them have more specific versions of the values that an A contains, and when you ask for those data, the specific versions of them should be returned.
Now you can do this:
// Get an instance of B or C, but you don't
// care which - could be either:
A someVersionOfA = getAnInstanceOfA();
// This works no matter if you've got an instance
// of B or C, but the result should vary accordingly:
someVersionOfA.m();
As someone else mentioned, think of A as "Animal", B as "cat", and C as "Dog". If m() means "Make some noise", then calling m() should result in "Meow" or "Woof!" depending on on the instance getAnInstanceOfA() returned.
You have just copied the internal address of B to A one, and replacing it.
B inherit from A, so no compilation problem.
Finally, the reference to A is destroyed, it is now a copy of reference to B

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

what would be the output?

Please explain me below situation
What would be the output?
interface A{}
class B implements A{}
class C extends B{}
class D extends C{}
class E extends D{
public static void main(String args[]){
C c = new C();
B b = c;
A a = (E)c;
a = (B)c;
c = (C)(B)c;
}
}
Being completely strict, that' won't compile because in line 4 you type Class instead of class
Class D extends C{}
And later you define twice a and c
C c = new C(); // once
B b = c;
A a = (E)c; // once a
A a = (B)c; // twice c
C c = (C)(B)c; // twice
Now assuming those were typos the output would be ClassCastException because c can't be casted to E.
When you perform a cast is like you were saying: "I'm the programmer and I know this is a..." ____(put your class here) And the compiler will allow you compile.
But if in runtime the instance is not really a ____ ( an E in this case, which is not ) then it will throw ClassCastException.
The program won't fail with A a = ( B ) c; because c is an instance of C which is a subclass of B.
You can say that, C is a B. To understand it better think on the following declaration:
class Employee extends Object {
}
Every Employee is an Object so the cast will succeed, actually is it so clear that it will succeed that you don't even need to put the cast operator ().
Employee e = new Employee();
Object o = ( Object ) e; // or much better:
Object o2 = e; // no cast needed when assigning to superclass.
But not necessarily an Object is an Employee.
Object o = ....
Employee e = ( Employee ) o; // will fail if o was not created as an Employee.
That's why A a = ( E ) c; fail, because, the reference c was not created as an E
I hope that helps.
ClassCastException at A a = (E)c;
Without actually trying it, I'll go out on a limb and say that this line will cause two compiler errors:
C c = (C)(B)c;
You're declaring the variable 'c' twice.
You can't cast from B to C.
And if you actually put a double cast like that into a real project, then you deserve to get your ass kicked.
The object c is created as a new C. Since C extends B it is no problem assigning it to a variable of type B. However C knows nothing about E, so you can't cast here. You can only do this with super-classes. Since A is the absolute top level it is fine to assign any objects of the types you have defined to it.
I think there's no output. Because you didn't tell it where the entry point is.
If you did specify the main class as D E, there would still be no output since all those classes extend an empty class.

Categories