一:概念
字面意思就是多种形态。 表示去完成某个行为,当不同的对象去完成时会产生不同的状态。
比如:打印机
打印机可以打印黑白的和彩色的。
还有动物喂食:猫就喂猫粮,修钩喂狗粮等等。
总的来说,同一件事,发生在不同对象身上会产生不同的效果
二:多态的条件
必须在继承体系下。
必须有向上转型
要通过父类的引用调用子类重写的方法(动态绑定)
下面我们来看一段代码:
public class Test01 {
public static void eatMap(Animal animal) {
animal.eat();
}
public static void main(String[] args) {
eatMap(new Dog("小黄",2));
eatMap(new Cat("喵喵", 1));
}
}
class Animal {
private String name;
private int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat() {
System.out.println(this.name + "干饭");
}
}
class Dog extends Animal{
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println(super.getAge()+ "岁的" + super.getName() + "在吃狗粮");
}
}
class Cat extends Animal{
public Cat(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println(super.getAge()+ "岁的" + super.getName() + "在吃猫粮");
}
}
上面就是一段多态的代码
其中
这里便是重写的方法,最后一个是父类的。
这个是继承体系。
这里是通过传参向上转型。
满足了这三个条件才能实现多态。
我们看看运行结果
通过调用一种方法,产生不同的反应。
三:方法的重写
上面讲到了方法的重写,之前我们有方法的重载,那么什么是重写呢?
方法的返回值和形参、方法名不变,里面的核心代码进行重写。
重载是方法名不变,传入参数数量或者类型要变,返回值无所谓,
那么方法的重写要注意以下几点:
子类在重写父类方法时,方法名,返回值类型、传入参数都不能改变。
被重写的返回值类型可以不同,但是要具备父子关系。比如说:
你的父类返回值类型时Animal的,那么你的子类返回类型可以是他的子类,Dog或者时Cat都行
这种也称为协变类型。
重写的访问权限不能低于父类的访问权限。比如你父类是用的public修饰的,那你只能大于或者等于他,所以你也只能用public来修饰。
被private和static、final修饰的也不能重写,构造方法也不能重写
四:向上转型和向下转型
什么是向上转型?
你可以理解为一个创建一个子类对象,放到父类类型中去,
就行把创建的一个狗对象放到动物类当中去,这就是向上转型
语法格式:父类类名 + 对象名 = new + 子类类型();
使用方式有三种:
直接赋值(上面这种)
这种就是方法传参
还有一种就是方法返回
向上转型的优点:代码变得更加灵活了。
缺点:不能调用子类的特有方法
向下转型
因为我们之前将animal向上转型了,此时它的类型是Animal的,所以要强转为Dog,然后赋值给dog。
主要用在无法调用子类特有的方法时,就可以向下转型,然后再调用。
但是这种方法不是很安全,比如你传入的如果时Cat类,却强转为Dog了,那么就会报错。
因此java中引入了instanceof 来判断,如果结果为true那么便会执行下面的向下转型。