我正在学习Java,据我所知,我知道所有对象都是在调用函数时在运行时创建的。
我遇到了这两个让我感到困惑的例子
示例1:
class Animal {
void jump() {
System.out.println("Animal");
}
}
class Cat extends Animal {
void jump(int a) {
System.out.println("Cat");
}
}
class Rabbit extends Animal {
void jump() {
System.out.println("Rabbit");
}
}
public class Circus {
public static void main(String args[]) {
Animal cat = new Cat();
Rabbit rabbit = new Rabbit();
cat.jump();
rabbit.jump();
}
}
本守则的输出是:
动物 兔
示例2
class Employee {
String name = "Employee";
void printName() {
System.out.println(name);
}
}
class Programmer extends Employee {
String name = "Programmer";
void printName() {
System.out.println(name);
}
}
public class Office1 {
public static void main(String[] args) {
Employee emp = new Employee();
Employee programmer = new Programmer();
System.out.println(emp.name);
System.out.println(programmer.name);
emp.printName();
programmer.printName();
}
}
这个例子的O / P是
员工 雇员 雇员 程序员
现在我的问题是为什么示例1 cat.jump()
将输出作为'Animal'返回
在示例2中,为什么programmer.printName()
正在返回“程序员”。
我认为这与动态和静态绑定有关,但我无法理解它们是如何在这些示例中实现的。
答案 0 :(得分:0)
因为在第一个场景中,您在Cat对象上调用了jump(),该对象从其基类Animal继承此方法。
我认为你期待" Cat"要输出但不是这种情况,因为你调用了jump(),而不是jump(int)。
答案 1 :(得分:0)
一般信息:
Java是动态绑定或后期绑定,这意味着在运行时,程序将通过检查对象的动态类型来查看被调用的方法是否被覆盖并将调用它。在其他世界,有:
Animal cat = new Cat();
cat.jump();
JVM在运行时,在调用jump()之前会查看动态类型cat
,它会注意到它是动态类型Cat。因此,如果存在名为jump()的覆盖方法,它将在Cat中搜索。如果找到它,它将使用它,否则它将上升到父(Animal)并从那里执行jump()
。
请注意,静态方法的行为不同,并且不会被覆盖。
返回您的代码行为
在示例1中,您呼叫jump()
而不是jump(int n)
。在类Cat中,您重载方法jump()而不是重写。所以如果你试着调用cat.jump(1);您将获得输出Cat
。重载方法将创建一个具有相同方法名但不同参数的附加方法。
全部放在一起
您会混淆2个概念,动态绑定和重载与覆盖。 Java是动态绑定,它将执行最接近创建对象的实际类型(动态类型)的方法。如果某个方法被具有此示例的子项覆盖:cat.jump()其中cat具有静态类型(Animal)和动态类型(Cat),则将从动态类型Cat执行方法jump()(如果在此处找到),如果不是发现它将从静态类型Animal执行它。
覆盖方法正在创建一个已存在于子类内的父类中的方法。 (这里动态绑定扮演角色)
重载一个方法正在创建一个已存在于子类内部父类但具有不同参数的方法。 (这就是为什么你没有把猫作为输出)