本篇博客将详细讲解Java中的多态。
文章目录
多态
向上转型
在理解多态之前,我们先来看看什么叫向上转型。
看看这段代码:
class Animal {
public String name;
public int age;
public Animal(String name) {
this.name = name;
}
}
class Bird extends Animal {
public Bird(String name) {
super(name);
}
public void fly() {
System.out.println("飞");
}
}
public class TestDemo {
public static void main(String[] args) {
Bird bird = new Bird("圆圆");
Animal bird2 = bird;
}
}
main函数内部的代码其实可以写出这样:
Animal bird2 = new Bird("圆圆");
此时 bird2 是一个父类 (Animal)的引用,指向一个子类(Bird)的实例。这种写法称为 向上转型 .
向上转型一般在三种情况下发生:
- 直接赋值
- 方法传参
- 方法返回
直接赋值在上文已经提到了,下面展示一个方法传参和方法返回。
方法传参:
public class Test {
public static void main(String[] args) {
Bird bird = new Bird("圆圆");
feed(bird);
}
public static void feed(Animal animal) {
animal.fly();
}
}
方法返回:
public class Test {
public static void main(String[] args) {
Ainmal animal = findMyAnimal();
}
public static Animal findMyAnimal() {
Bird bird = new Bird("圆圆");
return bird;
}
}
动态绑定
动态绑定是指父类引用引用了子类的对象,通过这个父类引用调用父类和子类同名的覆盖方法。
同名的覆盖方法也称为 重写 。
重写:
1、方法名相同。
2、参数列表相同。
3、返回值相同(返回值可以是协变类型)。
4、在父子类情况下使用。
我们来看这段代码:
class Animal {
public String name;
public int age;
public void eat() {
System.out.println("我是一只小动物");
System.out.println(this.name + "吃");
}
public Animal(String name) {
this.name = name;
}
}
class Bird extends Animal {
public Bird(String name) {
super(name);
}
@Override
public void eat() {
System.out.println("我是一只鸟");
System.out.println(name + "吃");
}
}
public class TestDemo {
public static void main(String[] args) {
Animal animal = new Bird("圆圆");
animal.eat();
}
}
这段代码运行的结果为:
这段代码并没有运行Animal中的eat()方法,而是运行了Bird中的eat()方法,这就是动态绑定。
动态绑定的注意事项:
- 方法不可以是static。
- 子类的访问修饰限定,要大于等于父类的访问修饰限定。
- private方法不能重写。
- 被final修饰的方法不能重写。
此外,还需知道一点: 通过父类引用,只能访问父类自己的成员 。
向下转型
向上转型是子类对象转成父类对象,向下转型就是父类对象转成子类对象。相比于向上转型来说,向下转型没那么常见,但是也有一定的用途。
例如:
class Animal {
public String name;
public int age;
public void eat() {
System.out.println("我是一只小动物");
System.out.println(this.name + "吃");
}
public Animal(String name) {
this.name = name;
}
}
class Dog extends Animal {
public String color;
public Dog(String name) {
super(name);
}
}
class Bird extends Animal {
public Bird(String name) {
super(name);
}
public void fly() {
System.out.println(name+"飞");
}
@Override
public void eat() {
System.out.println("我是一只鸟"