嵌入式之路,贵在日常点滴

                                                                ---阿杰在线送代码

目录

一、多态的概念 

二、多态存在的三个必要条件 

三、多态的作用 

四、多态程序例子 

五、对象的上下转型 

六、多态应用案例之打印机


一、多态的概念 

多态性是指同一个操作作用于某一类对象,可以有不同的解释,产生不同的执行结果。 

二、多态存在的三个必要条件 

需要存在继承或实现关系

同样的方法调用而执行不同操作、运行不同代码(方法重写) 

在运行时父类或者接口的引用变量可以引用其子类的对象 

三、多态的作用 

多态通过分离做什么和怎么做,从一个角度将接口和实现进行分离。

多态消除了类型之间的耦合关系。

多态的存在提高了程序的扩展性和后期的维护性。

四、多态程序例子 

class Animal
{
	public String name;
	
	public void eat(){};
}
 
class Dog extends Animal
{
	public void eat(){
		System.out.println("狗吃骨头");
	}
}
 
class Cat extends Animal
{
	public void eat(){
		System.out.println("猫吃鱼");
	}
}
 
public class Test {
	public static void main(String[] args) {
		Animal an1 = new Dog();//默认为子类转父类 向上转型
		Animal an2 = new Cat();//子类转为父类(Animal)
		
		an1.eat();
		an2.eat();
	}
}

运行结果:

狗吃骨头
猫吃鱼

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。 

多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。

五、对象的上下转型 

由子类转型成父类,在继承图上是向上移动的,一般称为向上转型。

向上转型是从一个较专用类型向通用类型转换,所以总是安全的,也就是说,子类是父类的超集。 

class Animal
{
	public String name;
	
	public void eat(){};
}
 
class Dog extends Animal
{
	public void eat(){
		System.out.println("狗吃骨头");
	}
}
 
class Cat extends Animal
{
	public void eat(){
		System.out.println("猫吃鱼");
	}
}
 
public class Test {
	public static void main(String[] args) {
		Animal an1 = new Dog();//默认为子类转父类 向上转型
		Animal an2 = new Cat();//子类转为父类(Animal)
        //Animal an2 = (Animal)new Cat();//子类转为父类(Animal)
		
		an1.eat();
		an2.eat();
	}
}

向上转型过程中,类接口中唯一可能发生的事情是丢失方法,而不是获取方法。

与之相反的操作向下转型,不安全(可能需要instanceof操作符协助)。

  • instanceof运算符用来在运行时通过返回值来指出对象是否是特定类或者是它的子类的一个实例

用法:

result = object instanceof class

result:布尔类型

object:必选项,任意对象表达式

class:必选项,任意已定义的对象类

说明:如果object是class或其子类的一个实例,则instanceof运算符返回true,如果不是或者object是null,则返回false。

  • 典型的使用场合

在对对象做下转型之前,没有其他有关对象信息时务必使用instanceof来判断一下,以避免抛出ClassCastException异常。

class Animal
{
	public String name;
	
	public void eat(){};
}
 
class Dog extends Animal
{
	public void eat(){
		System.out.println("狗吃骨头");
	}
}
 
class Cat extends Animal
{
	public void eat(){
		System.out.println("猫吃鱼");
	}
}
 
public class Test {
	public static void main(String[] args) {
		Animal an1 = new Dog();//默认为子类转父类 向上转型
		Animal an2 = new Cat();//子类转为父类(Animal)
        //Animal an2 = (Animal)new Cat();//子类转为父类(Animal)
		
		an1.eat();
		an2.eat();
		if(an1 instanceof Dog){
			System.out.println("true");
			Dog dog = (Dog)an1;
			dog.eat();
		}
	}
}

 运行结果:

狗吃骨头
猫吃鱼
true
狗吃骨头

对象的上下转型:安全和不安全体现在运行的过程。

六、多态应用案例之打印机

  • 不用多态 
class School
{
	public CaisSeDaYin cy;//类做类型说明
	public HeiBaiDaYin hy;//想象成在主函数中声明就好理解多了
	//在主函数实例化School,然后给该变量赋一个其他类型的变量,以此来调用其他类里面的方法
	
	public void anzhuang(CaisSeDaYin cy){//给该变量赋一个其他类型的变量
		this.cy = cy;
	}
	public void anzhuang(HeiBaiDaYin hy){
		this.hy = hy;
	}
	
	public void print(String contex){//调用此方法来间接调用其他类方法
		hy.print(contex);//赋值类的方法
	}//环环相扣,需要好好理解
}
 
class Dayin
{
	public String pinPai;
	
	public void print(String contex){
		
	}
}
 
class CaisSeDaYin extends Dayin
{
	public void print(String contex){
		System.out.println("彩色打印机打印"+contex);
	}
}
 
class HeiBaiDaYin extends Dayin
{
	public void print(String contex){
		System.out.println("黑白打印机打印"+contex);
	}
}
 
/*
没有用多态的用法:
打印不同的颜色就需要去改变School中print函数,打彩色就cy.print,打黑白就hy.print
或者是多写个函数
 */
public class printor {
	public static void main(String[] args) {
		School s = new School();
		//CaisSeDaYin c = new CaisSeDaYin();		
		//s.anzhuang(c);//s.cy = c;
		//s.print("ajie");
				
		HeiBaiDaYin h = new HeiBaiDaYin();
		/*
		    School类中相当于这样
			HeiBaiDaYin hx;
			hx = h;
			hx.print("ajie2");
		*/
		s.anzhuang(h);//s.hy = h;
		s.print("ajie1");
	}
}

运行结果:

黑白打印机打印ajie1 

  • 使用多态 
class School
{
	public Dayin dayinji;//类做类型说明
	//想象成在主函数中声明就好理解多了
	//在主函数实例化School,然后给该变量赋一个其他类型的变量,以此来调用其他类里面的方法
	
	public void anzhuang(Dayin dayinji){//给该变量赋一个其他类型的变量
		this.dayinji = dayinji;
	}
	
	public void print(String contex){//调用此方法来间接调用其他类方法
		dayinji.print(contex);//赋值类的方法
	}//环环相扣,需要好好理解
}
 
class Dayin
{
	public String pinPai;
	
	public void print(String contex){
		
	}
}
 
class CaisSeDaYin extends Dayin
{
	public void print(String contex){
		System.out.println("彩色打印机打印"+contex);
	}
}
 
class HeiBaiDaYin extends Dayin
{
	public void print(String contex){
		System.out.println("黑白打印机打印"+contex);
	}
}
 
//使用多态
public class printor {
	public static void main(String[] args) {
		School s = new School();
		CaisSeDaYin c = new CaisSeDaYin();		
		s.anzhuang(c);//s.cy = c;
		s.print("ajie");
		
		HeiBaiDaYin h = new HeiBaiDaYin();
		s.anzhuang(h);//s.hy = h;
		s.print("ajie1");
	}
}

运行结果:

彩色打印机打印ajie
黑白打印机打印ajie1

区别在于

不适用多态 

class School
{
	public CaisSeDaYin cy;//类做类型说明
	public HeiBaiDaYin hy;//想象成在主函数中声明就好理解多了
	//在主函数实例化School,然后给该变量赋一个其他类型的变量,以此来调用其他类里面的方法
	
	public void anzhuang(CaisSeDaYin cy){//给该变量赋一个其他类型的变量
		this.cy = cy;
	}
	public void anzhuang(HeiBaiDaYin hy){
		this.hy = hy;
	}
	
	public void print(String contex){//调用此方法来间接调用其他类方法
		hy.print(contex);//赋值类的方法
	}//环环相扣,需要好好理解
}

使用多态

class School
{
	public Dayin dayinji;//类做类型说明
	//想象成在主函数中声明就好理解多了
	//在主函数实例化School,然后给该变量赋一个其他类型的变量,以此来调用其他类里面的方法
	
	public void anzhuang(Dayin dayinji){//给该变量赋一个其他类型的变量
		this.dayinji = dayinji;
	}
	
	public void print(String contex){//调用此方法来间接调用其他类方法
		dayinji.print(contex);//赋值类的方法
	}//环环相扣,需要好好理解
}

多态三个必要条件:继承、重写、 父类引用指向子类对象:Parent p = new Child();