简体   繁体   中英

Use of method in superclass that has been overridden in a subclass, depending on the type of the objects that call it

I am looking for a way to call different definitions of a (overridden) method depending on the type of the objects that are calling the method. This should make more sense when I labour the point below.

I have two classes defined as follows:

public class SuperClass{

     public method1(){
           if (objects are of type SuperClass and not SubClass){ //pseudocode
                method2();
           }
           //do some more stuff
     }

     public method2(){
         //do stuff
     }
}

public class SubClass extends SuperClass{

     @Override
     public method1(){
          method2();
          super.method1();
     }

     @Override
     public method2(){
         //do stuff
     }

}

From these two classes I am working with 3 objects, call them dog , cat , and bird . dog and cat are both objects of type SuperClass , whereas bird is of type SubClass .

You notice that all the objects follow the same basic procedure in the code, their method1() calls upon method2() before doing anything else. The difference between them is obviously that SubClass overrides method2() : bird has a different method2() .

Currently my code is working how I want it, but I'm looking for a more elegant solution (if there is one). You can see from my code above how I've stepped around the issue at hand: in SuperClass I basically check that the objects are of type SuperClass . In my actual program that pseudocode line looks more like this (still "pseudocodey"):

 if(this.toString().equals("Dog") || this.toString().equals("Cat")){
      method2();
 }

And bird calls it's own definition of method2() before calling the original definition of method1() . Basically both classes are dealing with their own local definition of method2() .

My idea of a more elegant is as follows: completely remove the overridden definition of method1() from SubClass and be able to call the overridden definition of method2() from within SuperClass at the appropriate time (ie when the object I'm dealing with is bird ).

I basically tried the above exactly as I wrote it, but the bird object ended up using the definition of method2() that is in SuperClass rather than the one in SubClass .

Can this be done, if so, how?

You should not check for the type in the superclass method. Not with the posted ugly toString() method, not with instanceof either. Let polymorphism work for you.

The whole concept of polymorphism is that you can call a method on a superclass type, and the object will behave as it's actual type. The standard textbook example goes something like this:

Cat cat = new Cat();
Animal animal = cat;
animal.speak();

Imagine you didn't see the animal = cat assignment. You just have an Animal . You don't know if it's a cat, or a dog or an elephant, all you know is that has a speak method. The object will behave according to its actual type, without needing to check types inside, thanks to polymorphism.

Inheritance and Overriding works exactly as you want it to, without you having to check if the instance if super or sub class.

Just do,

public class SuperClass{
     public method1(){
         method2(); // Note that you don't need any instance check here.
         //do some more stuff
     }

     public method2(){
         SOP("Super method2");
     }
}

public class SubClass extends SuperClass{
     @Override
     public method2(){ // Note that you don't have to override method1
         SOP("SUB method2")
     }
}

In this case, if you call, method1() with an Super class object, it will call method2() of super class and print Super method2 .

If you call, method1() with a Sub class object, it will call method2() of sub class and print Sub method2 .

You can use the instanceOf() method to check if an object is an instance of another class. However this will return true for all super classes as well.

However I believe what you are saying is that you want sub classes to call their own version of a method if they have over ridden it. This will happen automatically due to Polymorphism

In order to call different definitions of a method depending on the type of the objects that are calling the method you might to do overloading, This is how it works

If a suitable function is found, that function is called. "Suitable" in this context means one of the following: • An exact match was found. • A trivial conversion was performed. • An integral promotion was performed. • A standard conversion to the desired argument type exists. • A user-defined conversion (either conversion operator or constructor) to the desired argument type exists. • Arguments represented by an ellipsis were found.

The compiler creates a set of candidate functions for each argument. Candidate functions are functions in which the actual argument in that position can be converted to the type of the formal argument. A set of "best matching functions" is built for each argument, and the selected function is the intersection of all the sets. If the intersection contains more than one function, the overloading is ambiguous and generates an error. The function that is eventually selected is always a better match than every other function in the group for at least one argument. If this is not the case (if there is no clear winner), the function call generates an error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM