多态,对象上下转型,动态和静态绑定 简单易懂(附程序帮助理解)

  • 由子类转型成父类,在继承图上是向上移动的,一般称为向上转型
  • 向上转型是从一个专用类型向通用类型转换,所以总是安全的,也就是说,子类是父类的一个超集
  • 向上转型过程中,类接口中唯一可能发生的事情就是丢失方法,而不是获取方法
  • 与之相反的操作是向下转型,不安全(可能需要instanceof操作符协助)
  • 里氏替换原则:子类型必须能够替换掉他们的父类型
  • 安全的上转型和LSP的实施,充分体现继承的“is-a”的关系
public class AnimalDemo {
	
	public static void main(String[] args) {
		/**
		 * 向上转型可能是安全的,但是有可能导致子类方法的丢失,子类中特有的方法有可能不能调用
		 * 父类中的引用只能调用父类中有的方法或子类重写父类的方法
		 */
		Animal dog = new Dog("旺财");//向上转型
		dog.eat();
		//dog.sleep();//父类没有这个方法,子类中特有方法调用报错
		Animal cat = new Cat("招财猫");
		cat.eat();
		//向下转型是不安全的,需用instanceof判断
		if (dog instanceof Cat) {
			//没有打印,这种情况下存在异常
			System.out.println("aa");
			Cat cat2 = (Cat) dog;
		}
		//转化类型一直,从专有类型转换为通用类型,可以调用子类特有方法
		if (cat instanceof Cat) {
			System.out.println("aa");
			Cat cat2 = (Cat) cat;
			cat2.sleep();
		}
	}

}

class Animal{
	@SuppressWarnings("unused")
	private String name;
	public Animal(String name) {
		this.name = name;
	}
	//这是一个通用的方法,告诉其子类去实现
	public void eat() {
		
	}
}


class Dog extends Animal{

	public Dog(String name) {
		super(name);
	}
	//对父类方法重写
	public void eat() {
		System.out.println("坑骨头");
	}
	public void sleep() {
		System.out.println("睡觉");
	}	
}

class Cat extends Animal{

	public Cat(String name) {
		super(name);
	}
	public void eat() {
		System.out.println("吃鱼肉");
	}
	public void sleep() {
		System.out.println("睡觉");
	}
}

程序输出

坑骨头
吃鱼肉
aa
睡觉

动态绑定和静态绑定

静态绑定

在程序执行前方法已经被绑定,针对java简单的可以理解为程序编译期的绑定(静态绑定)Java当中的方法final,static,private和构造方法都是前期绑定的

通俗来讲,程序在执行时,它的类型是不能够改写的,final,static,private和构造方法是不能改写的

动态绑定

运行时,根据变量实际引用的对象类型决定调用哪个方法(动态绑定)

静态绑定在编译器进行

     Person sayHi()  编译时就已经确定sayHi() 方法是Person的,此方法类型为上述三种类型

动态绑定在运行期进行

    Person p = new Teacher();

    p.sayHi();

多态的概念是基于对象引用的动态绑定特性

  • 多态是具有表现多种行为能力的特征
  • 同一个实现接口,使用不同的实例而执行不同的操作,如上述程序中的猫狗操作,以及下图帮助理解

public class PrinterDemo {
	
	public static void main(String[] args) {
		ColorPrinter colorPrinter = new ColorPrinter("惠普打印机");
		School school = new School();
	/*	school.setColorPrinter(colorPrinter);
		school.print("hello");*/
		BlankPrinter blankPrinter = new BlankPrinter("戴尔");
		school.setBlankPrinter(blankPrinter);
		blankPrinter.print("java");
	}

}

class Priter{
	private String brand;

	public Priter(String brand) {
		super();
		this.brand = brand;
	}
	public String getBrand() {
		return brand;
	}
	//打印的方法应该由其子类来具体的实现
	public void print(String content) {
		
	}
}
class ColorPrinter extends Priter{

	public ColorPrinter(String brand) {
		super(brand);
	}
	//对父类的方法重写
	public void print(String content) {
		System.out.println(getBrand() + "彩色打印" + content);
	}
}

class BlankPrinter extends Priter{

	public BlankPrinter(String brand) {
		super(brand);
	}
	//对父类的方法重写
	public void print(String content) {
		System.out.println(getBrand() + "黑白打印" + content);
	}
}
/**
 * 通过学校类组合打印机两个类
 * @author QuLvT
 *
 */
class School{
	private ColorPrinter cp = null;
	private BlankPrinter bp = null;
	//安装打印机的方法
	public void setColorPrinter(ColorPrinter cp) {
		this.cp = cp;
	}
	public void setBlankPrinter(BlankPrinter bp) {
		this.bp = bp;
	}
	//交给学校安装的哪种类型的打印机来打印
	public void print(String content) {
		//彩色
		//cp.print(content);
		//黑白
		bp.print(content);
	}
}

关于多态的理解,可以好好理解一些这个程序

开闭原则:对修改时封闭的,对扩展时开放的,不要违反开闭原则

可以使用多态解决这个问题,父类的引用对象可以引用其子类的对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值