编码时,我对多态性产生了一个有趣的疑问,我无法理解这个问题。
public class Animal {
public void getLegs() {
SOP("4 legs");
}
}
public class Kangaroo extends Animal {
public void getLegs() {
SOP("2 legs");
}
public static void main(String[] args) {
Animal a = new Kangaroo(); // without changing this how can I get Animal getLegs
SOP(a.getLegs()); // Important Line
}
}
现在如果我想调用getLegs
的{{1}}方法,我该怎么办?可能吗?它仍然是多态的吗?
答案 0 :(得分:3)
是的,这是展示多态性的最基本形式。
基本上您正在处理名为Animal
的{{1}}。当您调用a
时,您的代码不会绑定到a.getLegs()
中getLegs()
的实现,而是绑定到{{1}中的最低子类实现Animal
}}
如果getLegs()
有一个实现,则子类实现称它为 hidden 。如果Kangraoo()
没有实现,则无法构建Animal
的独立类,因为它们缺少所有必需方法的实现,并且在这种情况下,Animal
是据说是一个抽象类(一个不能直接构造,但只能由它的子类构造)。
答案 1 :(得分:2)
如果您真的想要为Animal调用方法,并且可以使用静态方法,则可以使用隐藏而不是覆盖。
它的工作原理如下:对于静态方法,被调用的方法是与声明的类型相关的方法,而不是对象实例。换句话说,它遵循类,因为该方法是类方法,而不是实例方法。
一个改编自this page的例子:
public class Animal {
public static void testClassMethod() {
System.out.println("The class" + " method in Animal.");
}
public void testInstanceMethod() {
System.out.println("The instance " + " method in Animal.");
}
}
public class Kangaroo extends Animal {
public static void testClassMethod() {
System.out.println("The class method" + " in Kangaroo.");
}
public void testInstanceMethod() {
System.out.println("The instance method" + " in Kangaroo.");
}
public static void main(String[] args) {
Kangaroo myRoo = new Kangaroo();
Animal myAnimal = myRoo;
myRoo.testInstanceMethod();
myAnimal.testInstanceMethod();
Kangaroo.testClassMethod();
Animal.testClassMethod();
}
}
结果将是(注意第3和第4行,而不是第1和第2行):
The instance method in Kangaroo.
The instance method in Kangaroo.
The class method in Kangaroo.
The class method in Animal.
答案 2 :(得分:1)
在Java中,无法访问Animal的实现。它将永远返回袋鼠的版本。
(注意在C#中 可以通过用“new”标记覆盖方法来实现,但它是一个相当专业的用例)。
访问似乎是Animal的东西,但获得Kangaroo指定的行为正是多态性的原因 - 子对象在其父对象所在的任何地方都可以被替换。
通常,您不希望让调用代码知道继承层次结构,因为这会将代码紧密地耦合在一起。如果你真的需要访问Animal的这种方法的实现,它表明你的设计可能是错误的。
答案 3 :(得分:1)
现在如果我想调用Animal的getLegs方法,我该怎么办?有可能吗?
如果要访问被覆盖的方法 - 这与多态性相矛盾 - 您可以使用反射。从getLegs
的类中获取Animal
方法,然后在Kangaroo对象上调用它。但是,这是一个黑客攻击,而不是你在常规程序中所做的事情。
SOP( Animal.class.getMethod("getLegs").invoke(a) );
答案 4 :(得分:1)
多态性的精神是执行在运行时决定的不同代码。为了更清楚,我会稍微修改你的代码。
public class Animal {
public void getLegs(){
SOP('4 legs');
}
}
public class Kangaroo extends Animal{
public void getLegs(){
SOP('2 legs');
}
public static void main(String[] args){
Animal a = new Kangaroo(); //without changing this how can I get Animal getLegs
Kangaroo kng= new Kangaroo ();
Animal an = new Animal();
SOP(a.getLegs()); // Kangaroo's version is called
SOP(kng.getLegs()); //Again, Kangaroo's version is called
SOP(an.getLegs()); //Animal version is called
}
}
并且是的,正如所有人说你不能从你的Animal a = new Kangaroo();
行调用动物......因为没有人会想要这样做。相反,他会直接写。 Animal a = new Animal();
..
所以最后是决定哪个方法被称为
的对象而不是referance