Home » Java » Cast parent to its child

Cast parent to its child

Posted by: admin December 28, 2021 Leave a comment

Questions:

I have:

class A
{
     public String getID() { return "id of A";}
}

class B extends A
{ 
     public String getID() { return "id of B"; }
}

and

class C {
 public A returnA() { 
    return new A(); 
  } 
}

Now I somehow need to do:

C c = new C();
B b = (B)c.returnA(); 
String id = b.getId();

But I don’t have access to implementation of C.returnA(), and I can’t change return type of it to B.

Answers:

You are casting a parent into a children.
You can never do that, because new A() is absolutely not a B.

Consider this: String extends Object. Now try to cast (String) new Object(). It wouldn’t make any sense at all.

Because your object is not a B anyway, there is no way it could have the behavior of B.

What you want here is use a Decorator Pattern. See http://en.wikipedia.org/wiki/Decorator_pattern

Here is an example of what a implementation of a Decorator could be:

public class B extends A {

    private A decorated;
    public B(A decorated) {
        this.decorated = decorated;
    }

    @Override
    public String getID() {
        return "id of B";
    }

    @Override
    public void otherMethodOfA() {
        return decorated.otherMethodOfA();
    }
}

Note that it is mandatory to override all methods of A to make sure you call the method on the decorated element. (here otherMethodOfA is an example)

Use like this:

C c = new C();
B b = new B(c.returnA());
String id = b.getID();

###

That won’t work. c.returnA() returns an A. An A is not a B. (A B is an A, but that’s not relevant here).

###

The answer of njzk2 is perfect. Anyway, if you ended up reading this post and like me, you don’t like overriding every method, you can just do this:

public class B extends A {

    public B(A nonDecorated) {
        this.anotherValueOfA = nonDecorated.getAnotherValueOfA();
    }

    @Override
    public String getID() {
        return "id of B";
    }
}

There is no need to override every method and the object is constructed with the values from its parent.

This is, of course, assuming class A is:

class A {
    private int anotherValueOfA;
    public String getID() {return "id of A";}
    public int getAnotherValueOfA() {return this.anotherValueOfA;}
}