【JAVA】`Animal a = new Dog();`到底是什么意思?
【JAVA】`Animal a = new Dog();`到底是什么意思?
Sarzn认真看这句代码 Animal a = new Dog();
- 一个对象 a
- a 的引用是 Animal
- 用来创建这个 a 对象的是 Dog()
在java 中引用 ≠ 对象 Animal
是一个引用他就像一个遥控器一样,指向 a 这个对象,但是这个 a
对象实际的东西还是 Dog.只是 Animal 决定了 a 对象能用什么方法
在这一句话中有两个关键点,我们逐一比对 1. a 对象实际的东西还是 Dog 2. Animal 决定了 a 对象能用什么方法
1. a 对象实际的东西还是 Dog
假设我们有一段这样的代码 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26class Animal { // 父类 Animal
public void eat() {
System.out.println("Animal eat something");
}
}
class Dog extends Animal { // 子类 Dog
public void eat() {
System.out.println("Dog eat something");
}
}
class Cat extends Animal { // 子类 Cat
public void eat() {
System.out.println("Cat eat something");
}
}
public class Main {
public static void main(String[] args) {
Animal a = new Dog(); // <- 注意这里
Animal b = new Cat();
a.eat(); // 输出 Dog eat something
b.eat(); // 输出 Cat eat something
}
}
类比我们在看电视 - 遥控器把台选好了 - 但是电视放什么,还是电视台自己说了算
2. Animal 决定了 a 对象能用什么方法
假设有一段代码是这样的 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26class Animal { // 父类 Animal
public void eat() {
System.out.println("Animal eat something");
}
public void drink() {
System.out.println("Animal drink something");
}
}
class Dog extends Animal { // 子类 Dog
public void eat() {
System.out.println("Dog eat something");
}
public void walk() {
System.out.println("Dog walk");
}
}
public class Main {
public static void main(String[] args) {
Animal a = new Dog(); // <- 注意这里
a.eat(); // 输出 Dog eat something
a.drink(); // 输出 Animal drink something
a.walk(); // 错误!
}
}a.walk();这一段代码,因为 Animal
这个遥控器根本就没有 walk,他只有 eat 和 drink,所以我们用不了 walk,只能用
eat 和 drink
类比我们在看电视 - 实际上电视里面有 100 个台 - 但是遥控器只有 10 个台 - 所以导致我们只能看 10 个台(别的台我们也看不了了,因为遥控器摇不到)
那为什么不直接写
Dog a = new Dog();?
好问题!如果只看这一行,确实没区别。但用父类引用有两个巨大好处:
1. 写通用代码 1
2
3
4
5
6
7public static void feed(Animal a) {
a.eat();
}
feed(new Dog()); // 可以
feed(new Cat()); // 可以
feed(new Pig()); // 也可以(只要 Pig 继承 Animal)
如果feed 的参数类型写死成 Dog,那就只能喂狗了。用 Animal,任何动物子类都能传进来
2. 用一个集合装不同的子类对象 1
2
3
4
5
6
7
8Animal[] zoo = new Animal[3];
zoo[0] = new Dog();
zoo[1] = new Cat();
zoo[2] = new Pig();
for (Animal a : zoo) {
a.eat(); // 每个动物都用自己的方式吃
}
如果不用父类引用,你就没法把狗、猫、猪放进同一个数组里
一句话总结
Animal a = new Dog() 的意思是: 实际创建的是
Dog 对象(决定了实际行为),但用 Animal
类型的引用来操作它(决定了能调用哪些方法)。
这种用父类的眼光看子类对象的写法,是 Java
实现多态和写出灵活、可扩展代码的基础。



