一.多态定义
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();
}
}