Live2D
复制代码

11-多态

多态

面向对象的三大特性——封装、继承、多态。

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

多态体现在类与类的继承和类与接口的实现之间。

1、Java中的向上转型和向下转型

向上转型:使用父类或者接口来定义变量存储子类或者实现类的对象

向下转型:将父类型的引用变量转换成子类或者实现类的类型

package k多态;

//父类
public class Animal {
	
	public void eat(){
		System.out.println("动物吃东西!");
	}

}

package k多态;

//子类1
public class Cat extends Animal {
	
	//重写
	public void eat(){
		System.out.println("猫吃鱼!");
	}
	
	//成员方法
	public void move(){
		System.out.println("猫走猫步!");
	}

}

package k多态;

//子类2
public class Dog extends Animal{
	
	//重写
	public void eat(){
		System.out.println("狗啃骨头!");
	}

}

/*
 *     关于java语言中的向上转型和向下转型
 *        1.向上转型(upcasting):子--->父
 *        2.向下转型(downcasting):父--->子
 *        
 *        注意:无论是向上转型还是向下转型,两个类之间必须要有继承关系。
 */

package k多态;

public class Test01 {
	
	public static void main(String[] args){
		
		//向上转型又称:自动类型转换
		//父类型的引用指向子类型的对象
		//程序分两个阶段:编译阶段 和 运行阶段
		//下面程序编译阶段只知道a1是一个Animal类型
		//而在运行的时候堆中的实际对象是Cat类型的
		Animal a1 = new Cat();
		
		//程序在编译阶段a1被编译器看作Animal类型
		//所以程序在编译阶段a1引用绑定的是Animal类中的eat方法 (静态绑定)
		//但是程序在运行阶段堆中的对象实际上是Cat类型,而Cat已经重写了eat方法
		//因而程序在运行时对象绑定的方法是Cat类中的eat方法 (动态绑定)
		a1.eat();//猫吃鱼!
		
		//向下转型:强制类型转换
		Animal a2 = new Cat();
		
		//要执行Cat类中自有的成员方法move,怎么做?
		//只能强制类型转换,需加强制类型转换符
		Cat c1= (Cat)a2;
		c1.move();//猫走猫步!
		
		//判断以下程序运行有什么问题
		Animal a3 =new Dog();//向上转型
		
		//强制类型转换
		//Cat c2 = (Cat)a3;//报错java.lang.ClassException
		
		//在做强制类型 转换的时候程序是存在风险的
		//为了避免ClassException的发生,java引入了 instanceof
		/*
		 * 用法: 
		 * 1.instanceof运算符的运算结果是boolean类型
		 * 2.(引用 instanceof 类型) -->true/false
		 * 
		 * 例如:(a instanceof Cat) 如果结果是true,表示 a引用指向堆中的java对象是Cat类型的
		 */
		Animal a4 = new Dog();

		//在做向下转型的时候要用instanceof运算符判断,避免ClassException
		if (a4 instanceof Cat){
			Cat c2 = (Cat)a4;
		}else {
			System.out.println(a4 instanceof Cat);
		}
		
	}
	

}

2、多态的好处

package l多态的好处;

public class Animal {
	
	public void eat(){
		
	}
	
	public static void name() {
		
		System.out.println("调用静态方法");
		
	}

}

/*
 * 宠物
 */
package l多态的好处;

public class Cat extends Animal{
	
	public void eat(){
		System.out.println("主人在喂猫");
	}


}

/*
 * 宠物
 */
package l多态的好处;

public class Dog extends Animal{
	
	public void eat(){
		System.out.println("主人在喂狗");
	}
	
	public static void name() {
		
		System.out.println("能否覆盖静态方法");
		
	}

}

/*
 *     模拟主人
 */
package l多态的好处;

public class Person {
	
	/*
    //喂养
	public void feed(Dog d){
		d.eat();
	}
	
	//因为用户的业务改变了所以软件要升级
	public void feed(Cat c){
		c.eat();
	}
	//以上代码得出:person类型的扩展能力太差
	 * 
	 */
	//尽量不要面向具体编程,要面向父类编程,面向抽象编程
	public void feed(Animal a){//也就说只要是继承了Animal类的都可以往这传,Animal a就相当于包括
		a.eat();               //上面的Dog d 和Cat c,有多少子类就包括
	}                          //测试调用方法中的参数写子类型的引用,不写父类型的引用a
	
	public void test(Animal b){
		b.name();               
	}   
}

/*
  *   多态的好处:
 *        1.使用多态可以使代码与代码之间的耦合度降低
 *        2.项目的扩展能力增强
 */
package l多态的好处;

public class Test01 {
	
	public static void main(String[] args){
		
		//创建主人
		Person milen = new Person();
		
		//创建宠物
		Dog d = new Dog();
		Cat c = new Cat();

		
		//喂
		milen.feed(d);//此时调用Animal a = d;
		milen.feed(c);//此时调用Animal a = c;
		
		d.name();//子类中的name方法
		milen.test(d);//父类中的静态方法
		
		//所以在方法覆盖中静态方法不建议重写,因为多态的好处项目代码多数使用多态,此间不调用子类的静态方法,重写了也没有意义
		//而且静态方法写在工具类中
	}

}

posted @ 2021-07-22 22:14  Milen-jie  阅读(42)  评论(0编辑  收藏  举报