JAVA多态

战神三考:Why、What、How
1、为何用多态?
2、多态是什么?
3、多态怎么用?

1、为什么要用多态

1)提高了代码的维护性 (通过继承和实现来保证)
	2)提高了代码的扩展性 (通过多态来保证)
	3)降低代码耦合度

2、多态基本概念

1.多态是继封装、继承之后,面向对象的第三大特性。

	2.多态的理解:
	现实事物经常会体现出多种形态,比如老虎,是一种猫科动物,蛇是一种冷血动物,
	但老虎和蛇都是属于动物,也分别属于自己动物类别,当然猫科动物属类中还有很
	多种,即动物在这里表现出了多种形态。                                                                                                            

	Java作为面向对象的语言,同样可以描述一个事物的多种形态。
	如Snake类继承了Animal类,一个Snake的对象便既是Snake,又是Animal。

	3.多态体现为父类引用变量可以指向具体的子类对象。

	4.前提条件:必须有父子继承关系或者实现关系。

	注意:在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法。

	5.多态的定义与使用格式

	定义格式:父类类型 变量名 = new 子类类型();

	6.理解:

	多态是同一个行为具有多个不同表现形式或形态的能力。

	多态就是同一个接口,使用不同的实例而执行不同操作。

3、多态怎么用

3.1、多态中的成员特点

// 上代码
public class Animal {
    public String name = "animal";

	@Override
    public void eat(){
        System.out.println("动物吃东西!");
    }
}

public class Tiger extends Animal {
    public String name = "tiger";

    @Override
    public void eat() {
        System.out.println("虎吃鸡!");
    }
    
    public void run() {
		System.out.println("虎奔跑!");
	}
}

public class Snake extends Animal {
    public String name = "snake";
    
    @Override
    public void eat() {
        System.out.println("蛇吞象!");
    }

	public void run() {
		System.out.println("蛇爬行!");
	}
}
1.多态成员变量:编译检查的时候检查Animal类中是否有此变量定义
		Animal tiger = new Tiger(); 

		System.out.println("name = " + tiger.name); // name 是Animal中的值,编译期只能取到父中的值
	上述打印输出结果为: name = Animal

	2.使用多态调用成员方法:编译时检查左边类型,运行时实际调用右边对象

    	Animal snake = new Snake();

    	System.out.println(sanke.eat()); // snake 的门面类型是 Animal,
    	
    但实际类型是Snake, 所以运行时调用的是Snake中重写后的方法。打印输出结果为: 蛇吞象!

3.2、多态的转型和instanceof关键字

多态的转型分为向上转型和向下转型两种
	向上转型:多态本身就是向上转型过的过程
    使用格式:父类类型 变量名=new 子类类型();

    适用场景:当不需要面对子类类型时,通过提高扩展性,或者使用父类的功能就能完成相应的操作。
	
	Amimal tiger = new Tiger();
	
	tiger.run(); // 这样写会报错,因为编译检查tiger是Animal类型,Animal中没有run方法。
	
	((Snake)tiger).run(); // 此时编译检查能通过,但是运行时会报错,因为tiger实际类型是Tiger类型,
	此时强制类型转换成Snake,编译时检测tiger是Animal类型,Snake也是Animal的子类,所以
	编译时无法发现老虎不能转化为蛇类型。

	if (tiger instanceof Tiger) {
		((Tiger) tiger).run() // 此时经过instanceof判断后才能进行强制类型转换,编译和运行时均能通过。
	}

	作用:用来判断某个对象是否属于某种数据类型。

3.3、多态案例

// 上代码
public class Keeper {
    public void feed(Animal animal){
        animal.eat();
    }
}

public class Test {
    public static void main(String[] args) {
        Keeper GodXiu = new Keeper();

        Animal snake = new Snake();

        Animal tiger = new Tiger();
        GodXiu.feed(snake);
        GodXiu.feed(tiger);
    }
}

上述案例中输出打印结果:
蛇吞象!
虎吃鸡!

4、个人思考总结

目前在日常开发中经常使用多态的地方就是使用集合的时候:
List list = new ArrayList();
        Map map = new HashMap();
今天的个人理解和分享就到这了,后续有新的感悟会继续补充更新!