让我们用这个简单的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 void eat(String s) {
System.out.println("Horse eating " + s);
}
}
我试图找出这三个ate()方法的哪个版本将运行。现在,当我键入
Animal a = new Animal();
a.eat();
结果是“普通动物一般地吃”,这是完全可以理解的。
当我输入时也会发生同样的事情:
Horse h = new Horse();
h.eat();
结果是“吃干草的马”,这也是完全合乎逻辑的。
这就是我困惑的地方。当我输入:
Animal ah = new Horse();
ah.eat();
我得到:
Horse eating hay
我期望编译器从动物类引用调用ate()方法,而不是马对象引用。
所以我的问题是,当我有一个泛型引用变量类型引用一个对象类型时(比如:Animal horse=new horse()),我如何确定编译器将调用哪个方法;
发生这种情况是因为方法重写。在方法重写中,引用类型无关紧要,重要的是对象类型Animal ah
只是对对象的引用,实际对象的类型为Horse
。因此,将调用马
的方法,而不是引用类型动物
的方法。
这在Java中称为动态绑定。explicite对象类型不用于引用类型。
无法使用单个方法调用重写的超级方法和重写方法,请参阅:如何调用超类的重写方法。您可以向马添加一个方法,将调用委托给动物,如:
public class Horse extends Animal {
public void animalEat() {
super.eat();
}
public void eat() {
System.out.println("Horse eating hay ");
}
}
我希望编译器从Animal类引用而不是Horse对象引用调用eat()方法。
让我们先纠正一下这个说法。变量ah
是类型Animal
的引用,语句new Horse()
创建类型Horse
的实例,并将其分配给Animal
引用。
现在术语已经很清楚了,这种行为是可以预期的,被称为运行类型多态性或动态方法调度。在编译时,ate()
基于引用类型解析,引用类型是动物
,但是在运行时,将被调用的方法基于实例类型是Ma
。
当我有一个引用对象类型的泛型引用变量类型时,如何确定编译器将调用哪个方法
您可以遵循以下简单步骤:
eat
Animal ah=new Horse()
中,参考类型是Animal
,即父类Animal ah=new Horse()
中,实例类型是Horse
,它是子类
如果上述所有条件都满足,您将看到运行类型多态性,并且将调用子类中的方法。在任何其他场景中,将根据引用类型解析要调用的方法。
理解子类从父类继承方法也是值得的。假设您从Horse
类中删除了public void eat()
方法,您不再过度使用eat()
方法;然而,Horse
中的public void eat(String s)
方法仍然被认为会使继承自Animal
的eat
方法负担过重。接下来,让我们在Animal
中添加一个public void eat(String s)
方法。通过这个添加,您现在在Animal
中重载了eat
方法,在Horse
类中重载了它。无论您如何更改代码,上面提到的4个步骤都将帮助您决定调用哪个方法。
问题内容: 让我们看一下这个简单的Java代码: 我试图找出三个eat()方法的哪个版本。现在,当我键入 输出是“一般动物食用”,这是完全可以理解的。 当我键入以下内容时,会发生相同的事情: 输出是“吃干草的马”,这完全是合乎逻辑的。 这就是让我感到困惑的地方。当我键入: 我得到: 我希望编译器从Animal类引用而不是Horse对象引用中调用eat()方法。 所以我的问题是,当我有一个引用对象类
我试图理解重载和重写静态和非静态方法是如何工作的。事实上,我试图理解这些方法如何能够和不能出现在父类和子类中。我想出了下面的规则: 我们不能重写静态方法,只能隐藏它们。通过隐藏,我们的意思是在编译时根据引用变量类型决定执行哪个方法,而不是重写(,在运行时根据实例类型选择哪个方法执行)。 例如,让,然后隐藏. 我们可以重写实例方法。 例如重写. 两个或多个具有相同签名的方法不能以静态或非静态组合形式
本文向大家介绍java中重载,继承,重写和多态的区别,包括了java中重载,继承,重写和多态的区别的使用技巧和注意事项,需要的朋友参考一下 重载,继承,重写和多态的区别: 1)继承是子类获得父类的成员。 2)重写是继承后重新实现父类的方法。 3)重载是在一个类里一系列参数不同名字相同的方法。 4)多态则是为了避免在父类里大量重载引起代码臃肿且难于维护。 网上看到一个有趣的说法是:继承是子类使用父类
我想知道: 为什么在Java中不能重写静态方法? 静态方法可以在Java中重载吗?
问题内容: 这是我遇到的一个测试练习问题,希望您能帮助我理解概念 让Hawk成为Bird的子类。假设某个类有两个重载的方法void foo(Hawk h)和void foo(Bird b)。在声明Bird x = new Hawk()之后,将在调用foo(x)中执行哪个版本; 这是我到目前为止的代码,有人可以向我解释为什么foo(bird b)被执行吗? 问题答案: Java执行重载解析以选择方法
问题内容: 就Java而言,当有人问: 什么是多态性? 将超载或重载是一个可以接受的答案? 我认为还有更多。 如果你有一个抽象基类,它定义了一个没有实现的方法,并且你在子类中定义了该方法,那该方法是否仍然覆盖? 我认为过载不是肯定的正确答案。 问题答案: 表达多态性的最清晰方法是通过抽象基类(或接口) 此类是抽象的,因为该方法不适用于人类。只有男性和女性子类别才可以定义。同样,人类是一个抽象的概念