我正在寻找一种方法来调用(重写)方法的不同定义,具体取决于调用该方法的对象的类型。当我在下面提到这点时,这应该更有意义。
我有两个类定义如下:
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
}
}
从这两个班级我正在使用3个对象,称他们为dog
,cat
和bird
。 dog
和cat
都是SuperClass
类型的对象,而bird
类型为SubClass
。
您注意到所有对象都遵循代码中的相同基本过程,method1()
在执行任何其他操作之前调用method2()
。它们之间的区别显然是SubClass
覆盖method2()
:bird
具有不同的method2()
。
目前我的代码正在按照我想要的方式工作,但我正在寻找更优雅的解决方案(如果有的话)。您可以从上面的代码中看到我如何解决手头的问题:在SuperClass
我基本上检查对象的类型是SuperClass
。在我的实际程序中,伪代码行看起来更像这样(仍然是“伪代码”):
if(this.toString().equals("Dog") || this.toString().equals("Cat")){
method2();
}
bird
在调用method2()
的原始定义之前调用它自己的method1()
定义。基本上这两个类都处理他们自己的method2()
的本地定义。
我更优雅的想法如下:从method1()
完全删除SubClass
的被覆盖定义,并且能够从method2()
内调用SuperClass
的被覆盖定义在适当的时候(即我正在处理的对象是bird
)。
我基本上完全按照我的写作尝试了上述内容,但bird
对象最终使用method2()
中SuperClass
的定义,而不是SubClass
中的定义}。
可以这样做,如果是这样,怎么办?
答案 0 :(得分:1)
您不应该检查超类方法中的类型。不是使用已发布的丑陋toString()
方法,也不是使用instanceof
方法。让多态性为你工作。
多态的整个概念是你可以在超类类型上调用一个方法,并且该对象将表现为它的实际类型。标准的教科书示例如下:
Cat cat = new Cat();
Animal animal = cat;
animal.speak();
想象一下,你没有看到animal = cat
作业。你只有一个Animal
。你不知道它是猫,狗还是大象,你所知道的只有说话方法。由于多态性,该对象将根据其实际类型进行操作,而无需检查内部类型。
答案 1 :(得分:1)
继承和覆盖完全按照您的意愿工作,无需检查实例是超级还是子类。
做,
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")
}
}
在这种情况下,如果您使用超类对象调用method1()
,它将调用超类的method2()
并打印Super method2
。
如果您使用Sub类对象调用method1()
,它将调用子类的method2()
并打印Sub method2
。
答案 2 :(得分:0)
您可以使用instanceOf()
方法检查对象是否是另一个类的实例。但是,对于所有超级类,这也将返回。
但是我相信你所说的是你希望子类调用他们自己的方法版本,如果他们已经过了它。由于Polymorphism
,这将自动发生答案 3 :(得分:0)
为了根据调用方法的对象的类型调用方法的不同定义,可以进行重载,这就是它的工作原理
如果找到合适的函数,则调用该函数。 "适合"在此上下文中表示以下之一: •找到了完全匹配。 •进行了一次微不足道的转换。 •进行了整体推广。 •存在标准转换为所需的参数类型。 •存在用户定义的转换(转换运算符或构造函数)到所需的参数类型。 •找到省略号表示的参数。
编译器为每个参数创建一组候选函数。候选函数是函数,其中该位置的实际参数可以转换为形式参数的类型。 一组最佳匹配函数"为每个参数构建,所选函数是所有集合的交集。如果交集包含多个函数,则重载不明确并生成错误。对于至少一个参数,最终选择的函数总是比组中的每个其他函数更好地匹配。如果不是这种情况(如果没有明确的赢家),则函数调用会生成错误。