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
Related
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).
This question already has answers here:
Is it possible to call subclasses' methods on a superclass object?
(9 answers)
Closed 6 years ago.
I am new to Java and I have trouble understanding one thing:
When I am declaring an Object by assigning to a sub object (a class extending object), it doesn't have access to sub object attributes.
Why is that ?
Let's say I have this:
public class A {
public int a;
}
public class B extends A {
public int b;
}
When I create an B object like this:
A object = new B();
I don't have access to object.b
I am forced to declare that way
B object = new B();
Isn't my object supposed to be a B with the first way to ?
The object is of type B only at runtime, at compile time , the compiler does not that its actual type is B since the variable object is declared of type A, an explicit downcast is required
A object = new B();
B b = (B)object;
int x = b.b;
If you called myfunc():
A object = myfunc();
And I define myfunc() as:
A myfunc() {
if (new Random().nextBoolean()) {
return new A();
} else {
return new B();
}
}
Can you still expect to always access object.b? No. myfunc() is only promising that it will return something of class A (or derived from class A)
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.
class A
{
}
class B extend A
{
int i;
int j;
}
Can a class have an IS-A Relationship with itself?
In this question, B is an A, right?
But can class B have an IS-A relationship with class B?
It's an identity (and tautology) - an object of type B will always be able to describe itself as an object of type B.
The further extensions of the is-a relationship pertain to hierarchies of inheritance; that is to say, since B extends A, B is-an A. This allows you to write the following expression:
A anA = new B();
But B is a B too. It hasn't lost that part of its identity because it now inherits from another class.
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.