1

Let's set up an hypothetical scenario. I have parent class

public class A {
    protected void doSomething(){
        //do something the A way
    } 
}

And child class

public class B extends A{
    @Override
    protected void doSomething(){
        // do something the B way
    } 
}

And i have some hypothetical class that:

public class SomeClass implements someInterface{
    @Override
    public void someMethod(A aObject){
        aObject.doSomething();
    } 
}

But i want to use the behavior of B, i can't change the method parameter nor i can downcast it to B.

Obviously i'm handling a bigger problem but this is the same principle, the answer i have for myself is to clone the properties of A into B, then use B. But before that i'd like to hear more opinions.

EDIT: Constraint, i can't pass an instance of B to the method nor use the instanceof method.

EDIT 2: I never receive an instance of B because someClass overrides this method from an interface that must always use an instance of A.

EDIT 3: This is a situation generated by poorly designed legacy code i ran into, i just wanted to figure out the faster but clean way to fix as an excercise.

Ringo
  • 850
  • 9
  • 24
  • 2
    If the parameter `A` is an `instanceof B`, `B`'s `doSomething()` method will be used, since it is `Overriding` `A`'s `doSomething()` method. There will be no need for casting `A` to `B` to get this to work. – CoderMusgrove Jul 21 '15 at 01:44
  • possible duplicate of [Call a method of subclass in Java](http://stackoverflow.com/questions/2701182/call-a-method-of-subclass-in-java) – Tim Biegeleisen Jul 21 '15 at 01:46
  • "I never receive an instance of B because someClass overrides this method from an interface that must always use an instance of A." How can you be sure you never receive an instance of B (since B is-a A) ? The only constraint I trust is the one described in `someInterface`. – Spotted Jul 24 '15 at 12:24
  • Do you have the possibility to refactor A and/or B ? – Spotted Jul 24 '15 at 12:30

4 Answers4

3

Just pass an instance of B to someMethod() since B "ISA" A, it will work and will call B's doSomething().

John3136
  • 28,809
  • 4
  • 51
  • 69
  • Constraint: i never receive an instance of B – Ringo Jul 21 '15 at 01:49
  • Then your design is wrong. If you want to call `B`'s `doSomething()` on an `A` (and not the subclass `B`), then that code belongs in `A` (or some utility package). – John3136 Jul 21 '15 at 01:59
  • Agreed, the good thing is that the code is not mine precisely, the bad thing is that i have to deal with it. Thanks John. – Ringo Jul 21 '15 at 02:00
2

The simple answer is that this is not possible.

When you create the object of the superclass, it does not have the methods of the subclass. Hence, it is not at all possible to call the subclass method on superclass object.

Samrat Dutta
  • 1,727
  • 1
  • 11
  • 23
1

To use the method of class B the object you pass in would have to be an instance of the class B. Then the method from class B will be called automatically when you do aObject.doSomething() because at runtime the A object will be identified as a B object which has in fact overriden the doSomething() method.

Zarwan
  • 5,537
  • 4
  • 30
  • 48
  • Constraint: i never receive an instance of B – Ringo Jul 21 '15 at 01:49
  • @LuisDurazo if you don't have an instance of B I don't see how it is possible to call a method from class B on the object, unless the method is static and you're passing it in as a parameter. B is A, but A is not B. It does not go both ways. So if you receive an instance of A unless you are able to cast it you cannot treat it as B. – Zarwan Jul 21 '15 at 01:51
  • That is exactly the question, is there truly no way?, can't i clone A to fit into B and null all the other properties of B? – Ringo Jul 21 '15 at 01:52
  • @LuisDurazo It is not possible as far as I know, unless you have some sort of structure set up for it. i.e. B has a constructor that takes in an instance of A then you construct a new instance of B and pass in A then call the method on that. – Zarwan Jul 21 '15 at 01:56
  • I agree, it's actually a 800 lines object for A and a few hundred too for B, There are code smells everywhere, that method in particular should not be there in the first place. Oh well, legacy code. – Ringo Jul 21 '15 at 01:58
  • @LuisDurazo you could try just extending the classes and adding your own methods to use. – Zarwan Jul 21 '15 at 02:03
1

Another answer is that this is completely backwards to the proper way to think of inheritance, and of methods to be called by different classes.

For B to extend A, B needs to be a special case of A. We could have such a relationship between passengerAuto/vehicle, or circle/shape, etc.

You appear to be trying to create a method within a class and then create an inheritance relationship around that so that you can use the method from both places. But there are LOTS of places to put methods which can be called from multiple places, and this is a very poor one.

Don't do this. Don't design your classes so that you can make 'nifty' method calls. It's the OO programming equivalent of "Here, hold my beer and watch this."

arcy
  • 12,845
  • 12
  • 58
  • 103
  • I agree that this is poorly designed, i'll have to refactor most of it either way (this is legacy code i didnt write), thanks arcy. – Ringo Jul 21 '15 at 02:14