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  子类();
子类类型 子类引用 = (子类类型)父类的引用;