多态----->解决代码复用性问题
方法或对象有多种形态
方法的重载体现出多态:功能相同的方法,因为传入的参数不一样,所以调用了不同的方法
方法的重写体现出多态:相同名字的方法,调用的对象不同,就执行的方法不同(父类的对象调用,就执行父类里面的方法,子类的对象调用就执行子类的方法)
对象的多态:
1.对象的编译类型和引用类型可以不一样
2.编译类型在定义对象的时候就确定了,不能改变
3.运行类型可以改变
4.编译类型看=左边,运行类型看=右边
【Amimal animal = new Dog()】animal的编译类型是Animal,运行类型是Dog。dog是animal的子类 animal父类的引用指向了子类的对象
package polymorphic_.improve;
public class Master {
private String name;
//构造器
public Master(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void feed(Animal animal,Food food){
System.out.println("主人 " + name + " 给 " + animal.getName() + " 吃 " + food.getName());
}
}
package polymorphic_.improve;
public class Food {
private String name;
public Food(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package polymorphic_.improve;
public class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package polymorphic_.improve;
public class poly1 {
public static void main(String[] args) {
Animal animal = new Animal("dog");
Food food = new Food("鱼");
Master master = new Master("小明");
master.feed(animal,food);
}
}
(运用多态就可以很好的解决主人喂食的问题,我们只需要把喂的食物的名字和吃食物的动物的名字写出来就能用一个food方法来喂食,这样就不用把每一个食物,动物再单独写一个类,提升了代码的复用性)
多态细节:
1.前提:两个对象(类)是继承关系
向上转型:
父类的引用指向了子类的对象【父类类型 引用名 = new 子类类型() 】
Animal animal = new Cat();
Object obj = new Cat();【这种写法也是对的,Object也是父类】
可以调用父类的所有成员(遵循访问权限)
不可以调用子类的成员(编译阶段能调用那些成员是由编译类型来决定的)
最终运行效果看子类的具体实现(调用方法时,从子类开始查找方法然后调用)
向下转型:
子类类型 引用名 = (子类类型)父类引用
Cat cat = (Cat) animal;
只能强转父类的引用,不能强转父类的对象(对象是在堆里面放着的,只能改这个栈里面的对象的引用,相当于改了一下地址值,不能把堆里面的东西改了)
父类的引用必须指向当前目标类型的对象[animal原来就是指向猫这个类]
向下转型后,可以调用子类类型的所有成员
//向下转型(animal原本指向的就是cat对象,相当于把父类的引用强转成子类的引用)
Cat cat = (Cat) animal;
cat.cry();
//这时候就可以通过对象访问子类的方法了(子类对象有两个引用,他们都指向堆里面的cat对象)
animal.cry();