Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast parent to its child

Tags:

java

oop

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.

like image 218
inside Avatar asked Jul 25 '14 14:07

inside


1 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();
like image 101
njzk2 Avatar answered Oct 21 '22 01:10

njzk2