Java 重载和重写方法中的多态性
让我们看一下这个简单的Java代码:Java 重载和重写方法中的多态性,java,polymorphism,overloading,overriding,Java,Polymorphism,Overloading,Overriding,让我们看一下这个简单的Java代码: public class Animal { public void eat() { System.out.println("Generic Animal Eating Generically"); } } public class Horse extends Animal { public void eat() { System.out.println("Horse eating hay "); } public v
public class Animal {
public void eat() {
System.out.println("Generic Animal Eating Generically");
}
}
public class Horse extends Animal {
public void eat() {
System.out.println("Horse eating hay ");
}
public void eat(String s) {
System.out.println("Horse eating " + s);
}
}
我试图找出三个eat()方法的哪个版本将运行。现在,当我打字的时候
Animal a = new Animal();
a.eat();
其结果是“普通动物以普通方式进食”,这是完全可以理解的
我打字时也会发生同样的情况:
Horse h = new Horse();
h.eat();
Animal ah = new Horse();
ah.eat();
输出是“吃干草的马”,这也是完全合乎逻辑的
但这让我感到困惑。当我打字时:
Horse h = new Horse();
h.eat();
Animal ah = new Horse();
ah.eat();
我得到:
Horse eating hay
我希望编译器从Animal类引用而不是Horse对象引用调用eat()方法
所以我的问题是,当我有一个泛型引用变量时,如何确定编译器将调用哪个方法
引用对象类型的类型(例如:Animal horse=new horse();这在Java中称为动态绑定。explicite对象类型不用于引用类型 无法使用单个方法调用重写的超级方法和重写方法,请参阅:。您可以向马添加一个方法,该方法将调用委托给动物,如:
public class Horse extends Animal {
public void animalEat() {
super.eat();
}
public void eat() {
System.out.println("Horse eating hay ");
}
}
Ohkay,
new关键字将创建给定类的实例
new Horse();
现在Horse类已经是Animal的子类了。所以下面将实例化
public void eat() {
System.out.println("Horse eating hay ");
}
现在您正试图将该对象存储在动物对象中。
这意味着马的对象存储在动物的对象中
Animal ah = new Horse();
所以在动物的对象中马的成员已经被存储。
这就是编译器打印子类方法值的原因
我希望编译器从Animal类引用而不是Horse对象引用调用eat()方法
让我们首先更正此语句。变量ah
是类型Animal
的引用,语句newhorse()
创建类型Horse
的实例,并将其分配给Animal
引用
现在术语已经清楚了,这种行为是预期的,被称为运行类型多态或动态方法调度是基于类型为Animal
的引用类型解析的,但在运行时,将调用的方法基于类型为Horse
的实例类型
当我有一个引用对象类型的泛型引用变量类型时,如何确定编译器将调用哪个方法
您可以按照以下简单步骤操作:
ah.eat()
正在调用方法eat
Animal ah=new Horse()
中,引用类型为Animal
,这是父类Animal ah=new Horse()
中,实例类型为Horse
,它是子类理解子类从其父类继承方法也是值得的。假设您从
Horse
类中删除public void eat()
方法,您不再过度使用eat()
方法;但是,public void eat(字符串s)Horse
中的方法仍然被认为会使继承自Animal
的eat
方法过载。接下来,让我们添加一个公共无效eat(字符串s)Animal
中的method。通过此添加,您现在在Animal
中重载了eat
方法,并在Horse
类中覆盖了它。无论您如何更改代码,上面提到的4个步骤都将帮助您决定将调用哪个方法。发生这种情况是因为方法覆盖了g、 在方法重写中,引用类型并不重要,重要的是对象类型。Animal ah
只是对对象的引用,而实际对象的类型是Horse
。因此,将调用Horse
的方法,而不是引用类型Animal
的方法。无法调用overriden super方法。我不完全遵循这个。当你可以说super.eat()时,为什么你需要一个单独的animalEat
方法
在eat
方法本身内部?@ck您肯定可以在重写方法中实现它,但是您总是调用super,可能您不希望这样。通常,当您想要调用重写方法时(其中没有super)您可以实现它。对于少数需要访问超级方法的情况,您可以添加animalEat
方法-因此这是一种增强。我明白您的意思。但是不能调用重写的超级方法的语句是不正确的,因为始终可以通过super
执行此操作这意味着不可能使用单个方法调用重写的超级方法和重写方法。您的帖子确实很有帮助,但您能否回答这两个问题。1)根据条件(2),如果父类和子类中有重载方法(而不是重写的方法),该怎么办?然后引用会决定调用哪个方法吗?我的第二个问题是(从你的最后一句话)我们还有什么其他可能的情况?非常感谢,很抱歉我的问题打扰了你。(顺便说一句,我选择了你最好的答案)。没关系。我刚刚发现引用类型决定了调用哪个重载方法。但是当我们有一个被重写的方法时,是对象决定了哪个方法。非常感谢,很抱歉给你添麻烦。@JesseJames添加了一个新的parag