多态

多态的定义、条件及案例

  1. 多态:同一个方法调用,由于对象不同会产生不同的行为
  2. 一个对象的实际类型是确定的,但可以指向对象的引用的类型很多
  3. 多态存在的条件:
  • 有继承关系;
  • 子类重写父类方法;
  • 父类引用指向子类对象
Pig p = new Pig();
Animal an = p;
//等价于Animal an = new Pig()
//=左侧:编译器的类型
//=右侧:运行期的类型
  1. 多态是方法的多态(static,final,private方法无法被重写),属性没有多态
  2. 多态的好处:多态能够提高代码的拓展性,符合面向对象的设计原则:开闭原则,即扩展是开放的,修改是关闭的。
  3. 案例
public class Animal {//父类,动物
    //喊叫
    public void shout(){
        System.out.println("我是小动物,我可以叫");
    }
}
public class Cat extends Animal{//子类 Cat
    //喊叫
    //子类重写父类的方法
    public void shout(){
        System.out.println("我是小猫,我可以喵喵叫");
    }

    public void scratch(){
        System.out.println("我是小猫,我可以挠人");
    }
}
public class Dog extends Animal{//子类 Dog
    //喊叫
    public void shout(){
        System.out.println("我是小狗,我可以汪汪叫");
    }

    public void guard(){
        System.out.println("我是小狗,我可以看家护院");
    }
}
public class Pig extends Animal{//子类 Pig
    //喊叫
    public void shout(){
        System.out.println("我是小猪,我可以哼哼叫");
    }

    public void eat(){
        System.out.println("我是小猪,我喜欢吃东西");
    }
}
public class Girl {
    //跟猫玩耍
    /*public void play(Cat cat){
        cat.shout();
    }*/
    //跟狗玩耍
    /*public void play(Dog dog){
        dog.shout();
    }*/
    //跟小动物玩耍
    public void play(Animal an){
        an.shout();
    }
}
public class Test {
    //main方法,程序的入口
    public static void main(String[] args) {
        Girl g = new Girl();
        //父类的引用指向子类的类型
        Animal an = new Cat();
        g.play(an);
    }
}

多态内存分析

两种解释

public class Pig extends Animal{   
    double weight;
    //喊叫
    public void shout(){
        System.out.println("我是小猪,我可以哼哼叫");
    }

    public void eat(){
        System.out.println("我是小猪,我喜欢吃东西");
    }
}
public class Animal {//父类,动物
    int age;
    //喊叫
    public void shout(){
        System.out.println("我是小动物,我可以叫");
    }
}

java多态 作用 java多态的意义_System

转型

java多态 作用 java多态的意义_java_02


多态的应用场合

应用场合一:父类作为方法的形参传入方法中

将父类作为方法的形参传入方法中,真实传入类型可以是该类的任意一个子类对象

public class Girl {
    //跟猫玩耍
    /*public void play(Cat cat){
        cat.shout();
    }*/
    //跟狗玩耍
    /*public void play(Dog dog){
        dog.shout();
    }*/
    //跟小动物玩耍
    public void play(Animal an){
        an.shout();
    }
}

应用场合二:父类作为方法的返回值类型

父类作为方法的返回值类型,真实返回的对象可以是该类的任意一个子类对象

  • 简单工厂模式
    它是解决大量对象创建问题的一个解决方案。将创建和使用分开,工厂负责创建,使用者直接调用即可。
  • 简单工厂模式的基本要求
  • 定义一个static方法,通过类名直接调用
  • 返回值类型是父类类型,返回的可以是其任意子类类型
  • 传入一个字符串类型的参数,工厂根据参数创建对应的子类产品
public class PetStore {//宠物店
    //方法:提供动物
    public static Animal getAnimal(String petName){//把父类当作方法的返回值
        Animal an = null;
        switch (petName){
            case "猫":
                an = new Cat();
                break;
            case "狗":
                an = new Dog();
                break;
            case "猪":
                an = new Pig();
                break;
            default:
                System.out.println("请选择合适的小动物");
        }
        return an;
    }
}
public class Test {
    //main方法,程序的入口
    public static void main(String[] args) {
        Girl g = new Girl();
        //父类的引用指向子类的类型
        Animal an = PetStore.getAnimal("狗");
        g.play(an);
    }
}