面向对象三大特性之一——多态

一.多态定义

1. 多种形态
 一个对象可以当做自己类的对象来看,也可以当做它的父类的对象来看
 (对于这个对象来说,是多种形态)
2.一个父类引用可以指向它的不同子类的对象
 (对于父类引用,也表现出多种形态)

Animal animal=new Cat();猫是动物

二.多态的条件

1.继承父类
2.重写父类方法(可以不用)
3.父类的引用指向子类的对象,子类对象赋值给父类的引用。

//Pet是父类 Pig是子类

Pet pet=new Pig //把猪^(* ̄(oo) ̄)^转换成动物

三.多态法则

1.可以访问什么

若子类对象当父类对象看待, 只能访问父类中定义的成员属性与方法,而不能访
问子类的成员(扩展的部分),子类特有的成员属性和特有的成员方法。

2.访问的到底是什么

若子类对父类的方法进行覆盖(重写),则在调用时会调用子类对象重写的方法

package com.gongsi.cn.oa.work729.test1;

public class Pet {
	private String name;
	private String XinTai;
	public Pet() {
		super();
	}
	public Pet(String name, String xinTai) {
		super();
		this.name = name;
		XinTai = xinTai;
	}
	public void eat() {
		System.out.println("吃东西");
	}
	
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getXinTai() {
		return XinTai;
	}
	public void setXinTai(String xinTai) {
		XinTai = xinTai;
	}
	
	

}
package com.gongsi.cn.oa.work729.test1;

public class Dog extends Pet{

	public Dog() {
		super();
	}

	public Dog(String name, String xinTai) {
		super(name, xinTai);
	}

	public void eat() {
		System.out.println("吃骨头");
	}
	

}
package com.gongsi.cn.oa.work729.test1;

public class Cat extends Pet{

	public Cat() {
		super();
		
	}

	public Cat(String name, String xinTai) {
		super(name, xinTai);
	
	}
	
	public void eat() {
		System.out.println("吃老鼠");
	}

}
package com.gongsi.cn.oa.work729.test1;

public class test {
	public static void main(String[] args) {
		Pet p1=new Dog("汪汪", "狗的样子");
		p1.eat();
		Pet p2=new Cat("喵喵", "猫的样子");
		p2.eat();
		
	}

}

 

 

 

3.多态的机制是由什么决定

1) 静态绑定
  发生在编译期间,一个方法或一个属性能不能调用或访问,是看左边的类型来决定,父类的引用指向子类的对象
2) 动态绑定
  发生在运行时,会找到具体的那个对象的方法来执行

四.多态使用

1.返回类型使用多态

//Manager类
// 多态的应用二:使用方法的返回类型实现多态
	public Pet getPet(String pet) {
		if (pet.equals("狗")) {
			return new Dog(); // 创建了一个狗的对象,还没有取名字
		} else if (pet.equals("猫")) {
			return new Cat();
		} else if (pet.equals("鸭")) {
			return new Duck();
		} else if (pet.equals("鸡")) {
			return new Chicken();
		} else if (pet.equals("猪")) {
			return new Pig();
		} else {
			return null;
		}

	}
//主函数
	应用二
	Manager manager=new Manager();
        //Pet dogPet=manager.getPet("狗");
	//manager.getPet("狗")=new Dog();
	//Pet dogPet=new Dog();
	
	Pet dogPet=manager.getPet("狗");
	dogPet.eat();
	Pet catPet=manager.getPet("猫");
	catPet.eat();
		

2.参数使用多态

//Manager类

public void feed(Pet pet) { //局部变量pet
	pet.eat();
}
//Cat类
public void eat() {
		System.out.println("猫吃老鼠");
	}

//主函数
	应用一
	Manager manager=new Manager();

	Dog dog =new Dog();
	manager.feed(dog);
	
	Cat cat=new Cat();
	manager.feed(cat);
	
	Duck duck=new Duck();
	manager.feed(duck);
	
	Pig pig=new Pig();
	manager.feed(pig);
	
        Chicken chicken=new Chicken();
	manager.feed(chicken);

3.成员变量使用多态

//manager类
// 多态的应用三:使用成员变量实现多态
	private Pet pet;// 使用率90%

	public Pet getPet() {
		return pet;
	}

	public void setPet(Pet pet) {
		this.pet = pet;
	}

	// 多态的应用一(2):使用方法的形参实现多态
	public void feed() { // 已经有了全局变量pet,不用再像 “多态的应用一(1)” 一样
		pet.eat();
	}
	//应用三 主函数
	Manager manager=new Manager();
	Dog dog =new Dog();
	manager.setPet(dog);
	manager.feed();
	

4.数组中使用多态

https://mp.csdn.net/mp_blog/creation/editor/119239688

五.多态的好处

1 使得程序更加灵活和可扩展
2 提高可维护性

经常修改的问题
1 源代码找不到
2 修改bug容易引入更多的bug

基于上面问题提出一个软件设计原则
OCP - Open - Close - Principle - 开闭原则
对扩展开放,对修改关闭
(1)对于扩展是开放的(Open for extension)。这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。也就是说,我们可以改变模块的功能。
(2)对于修改是关闭的(Closed for modification)。对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。模块的二进制可执行版本,无论是可链接的库、DLL或者.EXE文件,都无需改动。

六.证明方法重写是可有可无的(instanceof)

//Manager类
// 证明方法的重写是可选的 instanceof - 判断当前实例是否是某种类型
	public void playWithPet(Pet pet) {
		if (pet instanceof Duck) {
			Duck duck = new Duck();
			duck.swingming();
			System.out.println("管理员和鸭一起游泳");
		} else if (pet instanceof Pig) {
			Pig pig = new Pig();
			pig.sleep();
			System.out.println("管理员和猪一起睡觉");
		} else if (pet instanceof Dog) {
			Dog dog = new Dog();
			dog.shouMen();
			System.out.println("管理员狗一起守门");
		}

	}
//主函数
Manager manager=new Manager();
		Pig pig=new Pig();
		manager.playWithPet(pig);
		Dog dog=new Dog();
		manager.playWithPet(dog);

七.instanceof与类型转换

package com.gongsi.cn.oa.work729.test2;

public class TestTypeChange {
	public static void main(String[] args) {
		 
		//由小变大  子类的特有功能丢失,子类的特有属性丢失
		//狗的类型变成宠物类型
		Pet pet=new Dog();
		pet.eat(); //eat()方法被子类重写,所以调用的是子类的eat
		
		//由大变小  可以调用子类的特有功能和特有属性
		//宠物类型变成狗类型
		Dog dog=(Dog)pet;
		dog.eat();
		dog.shouMen();
		
		Pet pet1=new Pig();
		Pig pig=(Pig)pet1;
		pig.eat();
		pig.sleep();
		
		
		
		
		
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值