I am trying to figure out why the casting is redundant(thats the warning I get) in the end whats printed is "C".
public class Main {
public static void main(String[] args){
C c = new C();
B b1 = (B) c;
b1.f();
}
}
class A{
void f(){
System.out.println("A");
}
}
class B extends A{
}
class C extends B{
void f(){
System.out.println("C");
}
}
C extends B means that C is a B. And you do not need to cast C to B, because it IS a B.
So upcast (C to B) is always redundant. The only case when you would need cast is downcast (B to C):
B b = new C();
C c = (C) b;
Class c extends class B. So any C object is also a B object because of inheritance. So you do not need to explicitly cast '(B)' before c.
Related
So guys I've been playing around with inheritance and I've stumbled upon this program :
public class HelloWorld {
static class A {
void f() { System.out.println("A"); }
}
static class B extends A {
void f() { System.out.println("B"); }
}
static class C {
void func(B b) { b.f(); }
}
static class D extends C {
void func(A a){ a.f(); }
}
public static void main(String args[]) {
( (new D())).func( (A) (new B()));
A a = new B();
a.f();
B b = new B();
C c = new D();
c.func(b);
}
}
So how come even though A and C are implemented exactly the same way in the final few lines, A's methods
get overriden by B, but C's don't get overriden by D?
The program prints as follows :
B
B
B
Because Class D function definition is more general than C. C's function takes B type parameter but D function takes type A parameter which is a parent of B. It is more general than a function defined in C.
static class D extends C {
void func(A a){
a.f();
}
}
B b = new B();
C c = new D();
c.func(b);
Variable c is pointing to D's object so c.func(b) invokes method defined in D. A is a parent of B hence B's method is called. Same as it is called using A's reference as shown below.
A a = new B();
a.f();
It is because the method func in D does not override the same of C as the signature change.
static class C {
void func(B b) { b.f(); }
}
static class D extends C {
void func(B a){ a.f(); }
}
This will result in an override of the method
Given this Java code:
class A {
public void foo (Object o) { System.out.println("A"); }
}
class B {
public void foo (String o) { System.out.println("B"); }
}
class C extends A {
public void foo (String s) { System.out.println("C"); }
}
class D extends B {
public void foo (Object o) { System.out.println("D"); }
}
class Main {
public static void main(String[] args) {
A a = new C(); a.foo("Java");
C c = new C(); c.foo("Java");
B b = new D(); b.foo("Java");
D d = new D(); d.foo("Java");
}
}
why is the result ACBB?
I wil try to explain what I think, and I would appreciate if someone lets me know where my gap is.
So what I thought with the first two calls is:
a has static type A, but dynamic type C so Java should dispatch the method call dynamically and call foo() in C printing "C".
c has static and dynamic type C, so now since we inherit from A, it has to choose the most specific method, which is public void foo(String s) and thus printing "C"
b has static type B but dynamic type D so also in this case it should dynamically dispatch and call foo() in D printing "D".
d has static and dynamic type D, so now since we inherit from B, it has to choose the most specific method, which is public void foo(String o) and thus printing "B"
What is wrong in this explanation I've given here?
foo(Object) doesn't override foo (String) but overloads it. Hence D has 2 methods and since the most specific one will be used it will be foo(String) when you pass a string parameter.
From JLS 15.12.2 (emphasis by me):
This step uses the name of the method and the argument expressions to locate methods that are both accessible and applicable, that is, declarations that can be correctly invoked on the given arguments.
There may be more than one such method, in which case the most specific one is chosen.
A a = new C(); a.foo("Java"); calls foo(String) method from a which is a A
C c = new C(); c.foo("Java"); calls foo(String) method from c which is a C
B b = new D(); b.foo("Java"); calls foo(String) method from b which is a B
D d = new D(); d.foo("Java"); calls foo(String) method from d which only exists on B (D contains foo(Object))
public class A
{
public void printA(){
System.out.println("A");
}
}
public class B extends A
{
public void printB(){
System.out.println("B");
}
}
public class C extends B
{
public void printC(){
System.out.println("C");
}
}
public class test {
public static void main(String[] args)
{
A a = new B();
a.printA(); // work
B b = (B) a;
b.printB(); // work
C c = (C) b;
c.printC(); // not work throw java.lang.ClassCastException
}
}
i have three classes A and B and C
C extends from B and B extends from A
why down casting work from A to B, and does not work from B to C ,although the relation between them like A and B , B is parent of C so how it work JVM??
Classes can only be cast to their parent classes, they have no knowledge about their subclasses.
Since your object is an instance of B, it does not implement methods of C.
This will work:
A a = new C();
a.printA(); // work
B b = (B) a;
b.printB(); // work
C c = (C) b;
c.printC(); // work
if i have group of classes let say class A,B,C and D and Class A initiate class B, class B initiate class C and class C initiate class D and their is arguments must be passed from A to D, what is the best way to passing??do i have to pass the arguments across all the classes i have ??
i tried this solution but i search for one easier.
class A
{
B b=new B(the_arguments);
}
class B
{
C c=new C(the_arguments);
}
class C
{
D d=new D(the_arguments);
}
thanks in advance .
Can you create a constructor in each successive class that takes a single argument of the previous class type? You'd need to make appropriate getters, or expose the arguments to the other classes (which wouldn't be too bad if they derived from each other).
class A
{
B b = new B(this);
}
class B
{
B(A a) { this.foo = a.foo; ... } // Constructor
C c = new C(this);
}
class C
{
C(B b) { this.foo = b.foo; ... } // Constructor
D d = new D(this);
}
class D
{
D(C c) { this.foo = c.foo; ... } // Constructor
}
If I have class A { and class B extends A { will
B[] b = new B[1];
b[0] = new B();
System.out.println(b instanceof A[]);
print out true or false?
The JLS states that if B is assignable to A, then yes, B[] is assignable to A[].
This opens the door to serious implications though, demonstrated by this code:
class A {}
class B extends A {}
class C extends A {}
//...
B[] bs = new B[2];
A[] as = bs;
as[0] = new C(); //runtime error
B b = bs[0];
This code compiles but fails at runtime. We call that a lack of type safety.
// A.java
public class A {}
// B.java
public class B extends A {}
// Test.java
public class Test {
public static void main(String[] args) {
B[] b = new B[1];
b[0] = new B();
System.out.println(b instanceof A[]);
}
}
When run:
> javac *.java && java Test
true
It will print true.
false.
Arrays don't follow the same rules as normal Objects.