1. 多态的概念
Java中面向对象有三大特性:封装、继承和多态。
Java中的多态是什么,表现在哪里?
允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)多态要有动态绑定,否则就不是多态。多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作。
2. 多态存在的三个必要条件
1.要有继承;
2.要有方法的重写;
3.父类引用指向子类对象(对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接)。
例:Animal animal = new Cat();
3. 多态的使用--方法的多态
方法的重写Overriding和重载Overloading是Java 多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载 Overloading 是一个类中多态性的一种表现。
案例一:
class Person {
public void eat () {
System.out.println("吃饭");
}
public void eat (String food) {
System.out.println("吃" + food);
}
}
class Man extends Person {
@Override
public void eat() {
System.out.println("吃零食");
}
@Override
public void eat(String food) {
System.out.println("吃"+ food);
}
}
这个简单的案例使用了方法的重载和方法的重写分别体现了多态。
4. 多态的使用--对象的多态
一个对象的编译类型和运行类型是不一样。编译类型是在定义对象的时候,就已经确定好的
而运行类型是可以改变的。编译类型看 = 的左边 ,运行类型看 = 的右边。
例: Person person = new Person();
Person person就是编译类型,new Person()就是运行类型。
案例二:
package com.lmz.day03;
class Animal {
public void run() {
System.out.println("动物在跑");
}
}
class Dog extends Animal {
@Override
public void run() {
System.out.println("狗跑的快");
}
public void eat() {// 自己独有的方法
System.out.println("狗啃骨头");
}
}
class Cat extends Animal {
@Override
public void run() {
System.out.println("猫跑的满");
}
public void cry() {// 自己独有的方法
System.out.println("喵喵喵");
}
}
public class Test {
public static void main(String[] args) {
Animal animal1 = new Dog();// 父类的引用指向子类的对象
animal1.run();
//animal1.eat();// 编译错误
// 因为父类的引用是指向不了子类独有的方法的,意味着父类的引用不能调用子类独有的方法
Animal animal2 = new Cat();
animal2.run();
//animal2.sleep();
}
}
5. 多态的优点
可替换性(substitutability)。多态对已存在代码具有可替换性。例如,多态对动物Animal 类工作,对其他任何动物猫,狗,兔子也同样工作。
可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态
性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。
6. 拓展--向上转型和向下转型
6.1 多态的向上转型
本质:父类的引用指向子类对象;
语法格式:
父类类型 父类引用 = new 子类类型();
将子类的对象赋值给了父类的引用。小范围(子类) 转为大范围(父类)自动转型;
父类的引用可以调用父类的所有成员方法,可以调用子类的重写父类的方法,但是不能调用子类独有的方法。
6.2 多态的向下转型
本质:先将父类引用指向子类对象,再将父类引用赋值给子类引用(需要强转);
语法格式:
父类类型 父类引用 = new 子类();
子类类型 子类引用 = (子类类型)父类的引用;