多态的使用

1、认识多态

  • 面向对象三大特征:封装、继承、多态   

什么是多态?

  • 同类型的对象,表现出不同的 形态 。(对象的多种形态。)
  • 同类型的对象,执行同一个行为,会表现出不同的行为 特征
  • 同一个对象,在不同时刻表现出来的不同形态

多态的表现形式?

父类类型      对象名称            =           子类对象;(父类类型    对象名称   =  new  子类构造器)
接口             对象名称            =   new    实现类构造器;

多态的前提?

  • 有  继承 / 实现  关系;
  • 有父类引用指向子类对象
  • 有方法重写

多态的好处?

  • 使用父类型作为参数,可以接收所有子类对象,体现多态的扩展性与便利。
public class Person {
    private String name;
    private int age;
    
    public Person() {
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    public void show() {
        System.out.println(name + "," + age);
    }
}
class Student extends Person {

    @Override
    public void show() {
        System.out.println("学生的信息位:" + getName() + ", " + getAge());
    }
}
class Teacher extends Person {

    @Override
    public void show() {
        System.out.println("老师的信息为:" + getName() + ", " + getAge());
    }
}
class Administrator extends Person {

    @Override
    public void show() {
        System.out.println("管理员的信息为:" + getName() + ", " + getAge());
    }
}

class Test {
    public static void main(String[] args) {
//      创建三个对象,并调用register方法
        Student s = new Student();
        s.setName("张三");
        s.setAge(18);

        Teacher t = new Teacher();
        t.setName("王建国");
        t.setAge(20);

        Administrator admin = new Administrator();
        admin.setName("管理员");
        admin.setAge(35);

        register(s);
        register(t);
        register(admin);
    }
//  这个方法既能接收老师,又能接收学生,还能接收管理员
//  只能把参数写成这三个类型的父类
    public static void register(Person p) {
        p.show();
    }
}
D:\Java\jdk-17\bin\java.exe "-javaagent:D:\BaiduNetdiskDownload\IntelliJ IDEA 2022.2.3\lib\idea_rt.jar=33418:D:\BaiduNetdiskDownload\IntelliJ IDEA 2022.2.3\bin" -Dfile.encoding=UTF-8 -classpath F:\IdeaProjects\JavaSenior\out\production\oop-polymorphism com.itheima.Test
学生的信息位:张三, 18
老师的信息为:王建国, 20
管理员的信息为:管理员, 35

Process finished with exit code 0

2、多态调用成员的特点 

  • 变量调用:编译看左边,运行也看左边。

    编译看左边:javac编译代码的时候,会看左边的父类中有没有这个变量,如果有,编译成功,如果没有编译失败。

    运行看左边:java运行代码的时候,实际获取的就是左边父类中成员变量的值

  • 方法调用:编译看左边,运行看右边。

    编译看左边:javac编译代码的时候,会看左边的父类中有没有这个方法,如果有,编译成功,如果没有编译失败。

    运行看右边:java运行代码的时候,实际上运行的是子类中的方法

    Animal   a  =  new   Dog();

    现在用 a 去调用变量和方法的呀?是的

    而a是Animal类型的,所以默认都会从Animal这个类中去找

    //成员变量:在子类的对象中,会把父类的成员变量也继承下的的。父:name        子:name

    //成员方法:如果子类对方法进行了重写,那么在虚方法表中是会把父类的方法进行覆盖的。             

  • 多态的使用_第1张图片

3、为什么成员变量和成员方法的访问不一样呢? 

  • 因为成员方法有重写,而成员变量没有

4、多态调用成员的内存图解 

首先第一步测试类的字节码文件先加载到方法区当中,然后虚拟机会自动的去调用main方法,然后会先加载父类的字节码文件,然后会再加载子类的字节码文件。

多态的使用_第2张图片

5、多态的优势和弊端

      多态的优势

  • 在多态形式下,右边对象可以实现解耦合,便于扩展和维护。
  • 定义方法的时候,使用 父类型 作为参数,可以接收所有子类对象(该方法就可以接收这父类的一切子类对象),体现多态的扩展性与便利。

多态的使用_第3张图片

      多态的劣势 

  • 多态下不能使用子类的独有功能

多态的使用_第4张图片

6、引用数据类型的类型转换,有几种方式?

  • 自动类型转换、(从子到父):子类对象赋值给父类类型的变量指向。
  • 强制类型转换、(从父到子):
  1. 此时必须进行强制类型转换:子类     对象变量 = (子类)父类类型的变量
  2. 作用:可以解决多态下的劣势,可以实现调用子类独有的功能。
  3. 注意:如果 转型后的类型 和对象真实类型 不是同一种类型 ,那么在转换的时候就会出现 ClassCastException 。
  4. Java建议强制转换前使用instanceof判断当前对象的真实类型,再进行强制转换

7、强制类型转换能解决什么问题? 

  • 可以转换成真正的子类类型,从而调用 子类独有功能
  • 继承关系 / 实现 的2个类型就可以进行强制转换,编译无问题。
  • 转换类型与真实对象类型不一致会报错。(运行时,如果发现强制转换后的类型不是对象真实类型则报错。类型转换异常:ClassCastException)
  • 转换的时候用instanceof关键字进行判断

8、instanceof 在 jak14,语言等级16中的新特性

public class Test {
    public static void main(String[] args) {
        Animal a = new Dog();
        a.eat();
//        ((Dog) a).lookHome();
        /*if (a instanceof Dog) {
            Dog d = (Dog) a;
            d.lookHome();
        } else if (a instanceof Cat) {
            Cat c = (Cat) a;
            c.catchMouse();
        } else {
            System.out.println("没有这个类型,无法转换");
        }*/

        //jdk14新特性,语言等级16
        if (a instanceof Dog d) {
            d.lookHome();
        } else if (a instanceof Cat c) {
            c.catchMouse();
        } else {
            System.out.println("没有这个类型,无法转换");
        }

    }
}
class Animal {
    public void eat() {
        System.out.println("动物在吃东西");
    }
}
class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
    public void lookHome() {
        System.out.println("狗看家");
    }
}
class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃小鱼干");
    }
    public void catchMouse() {
        System.out.println("猫抓老鼠");
    }
}

9、多态的综合练习 

  • 不使用多态完成练习

public class Person {
    private String name;
    private int age;

    public Person() {
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void keepPet(Dog dog, String something) {
        System.out.println("年龄为" + age + "岁的" + name + "养了一只" + dog.getColor() + "颜色的" + dog.getAge() + "岁的狗");
        dog.eat(something);
    }

    public void keepPet(Cat cat, String something) {
        System.out.println("年龄为" + age + "岁的" + name + "养了一只" + cat.getColor() + "颜色的" + cat.getAge() + "岁的猫");
        cat.eat(something);
    }
}
class Animal {
    private int age;
    private String color;
    public Animal() {
    }
    public Animal(int age, String color) {
        this.age = age;
        this.color = color;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public void eat(String something) {
        System.out.println("动物在吃" + something);
    }
}
class Dog extends Animal {
    int age;
    String color;
    public Dog() {
    }
    public Dog(int age, String color) {
        super(age, color);
    }

    @Override
    public void eat(String something) {
        System.out.println(getAge() + "岁的" + getColor() + "颜色的狗两只前腿死死的抱住" + something + "猛吃");
    }
    public void lookHome() {
        System.out.println("狗看家");
    }
}
class Cat extends Animal {
    public Cat() {
    }
    public Cat(int age, String color) {
        super(age, color);
    }
    @Override
    public void eat(String something) {
        System.out.println(getAge() + "岁的" + getColor() + "颜色的猫咪着眼睛侧着吃" + something);
    }
    public void catchMouse(String something) {
        System.out.println("猫抓老鼠");
    }
}
class Test {
    public static void main(String[] args) {
        Person person = new Person("老王", 30);
        Dog dog = new Dog(2, "黑");
        person.keepPet(dog, "骨头");

        Person person1 = new Person("老李",25);
        Cat cat = new Cat(3, "灰");
        person1.keepPet(cat,"鱼");
    }
}
D:\Java\jdk-17\bin\java.exe "-javaagent:D:\BaiduNetdiskDownload\IntelliJ IDEA 2022.2.3\lib\idea_rt.jar=9803:D:\BaiduNetdiskDownload\IntelliJ IDEA 2022.2.3\bin" -Dfile.encoding=UTF-8 -classpath F:\IdeaProjects\JavaSenior\out\production\oop-polymorphism Test
年龄为30岁的老王养了一只黑颜色的2岁的狗
2岁的黑颜色的狗两只前腿死死的抱住骨头猛吃
年龄为25岁的老李养了一只灰颜色的3岁的猫
3岁的灰颜色的猫咪着眼睛侧着吃鱼

Process finished with exit code 0
  • 使用继承关系完成多态练习

public class Person {
    private String name;
    private int age;

    public Person() {
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void keepPet(Animal a, String something) {
        if (a instanceof Dog d) {
            System.out.println("年龄为" + age + "岁的" + name + "养了一只" + d.getColor() + "颜色的" + d.getAge() + "岁的狗");
            d.eat(something);
        } else if (a instanceof Cat c) {
            System.out.println("年龄为" + age + "岁的" + name + "养了一只" + c.getColor() + "颜色的" + c.getAge() + "岁的猫");
            c.eat(something);
        } else {
            System.out.println("没有这种动物");
        }
    }
}
class Animal {
    private int age;
    private String color;
    public Animal() {
    }
    public Animal(int age, String color) {
        this.age = age;
        this.color = color;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public void eat(String something) {
        System.out.println("动物在吃" + something);
    }
}
class Dog extends Animal {
    int age;
    String color;

    public Dog() {
    }
    public Dog(int age, String color) {
        super(age, color);
    }
    @Override
    public void eat(String something) {
        System.out.println(getAge() + "岁的" + getColor() + "颜色的狗两只前腿死死的抱住" + something + "猛吃");
    }
    public void lookHome() {
        System.out.println("狗看家");
    }
}
class Cat extends Animal {
    public Cat() {
    }
    public Cat(int age, String color) {
        super(age, color);
    }
    @Override
    public void eat(String something) {
        System.out.println(getAge() + "岁的" + getColor() + "颜色的猫咪着眼睛侧着吃" + something);
    }

    public void catchMouse() {
        System.out.println("猫抓老鼠");
    }
}
class Test {
    public static void main(String[] args) {
        Person p = new Person("老王", 30);
        Person p2 = new Person("老王", 25);
        Dog d = new Dog(2, "黑");
        Cat c = new Cat(3, "灰");
        p.keepPet(d, "骨头");
        p2.keepPet(c, "鱼");
    }
}
D:\Java\jdk-17\bin\java.exe "-javaagent:D:\BaiduNetdiskDownload\IntelliJ IDEA 2022.2.3\lib\idea_rt.jar=27829:D:\BaiduNetdiskDownload\IntelliJ IDEA 2022.2.3\bin" -Dfile.encoding=UTF-8 -classpath F:\IdeaProjects\JavaSenior\out\production\oop-polymorphism Test
年龄为30岁的老王养了一只黑颜色的2岁的狗
2岁的黑颜色的狗两只前腿死死的抱住骨头猛吃
年龄为25岁的老王养了一只灰颜色的3岁的猫
3岁的灰颜色的猫咪着眼睛侧着吃鱼

Process finished with exit code 0
  • 使用实现关系(接口)完成多态练习

public interface USB {
    void connect();
    void unconnect();
}
class Mouse implements USB {
    private String name;
    public Mouse() {
    }
    public Mouse(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public void connect() {
        System.out.println(name + "成功的接入了设备~~~");
    }
    @Override
    public void unconnect() {
        System.out.println(name + "成功的从设备弹出~~~");
    }
    public void click() {
        System.out.println(name + "双击点亮小红心~~~");
    }
}
class KeyBoard implements USB {
    private String name;
    public KeyBoard() {
    }
    public KeyBoard(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public void connect() {
        System.out.println(name + "成功的接入了设备~~~");
    }
    @Override
    public void unconnect() {
        System.out.println(name + "成功的从设备弹出~~~");

    }
    public void keyDown() {
        System.out.println(name + "写下了:老铁,6666,下次再来哦,老弟~~~~");
    }
}
class Computer {
    public void installUSB(USB u) {
        u.connect();
        if (u instanceof Mouse m) {
            m.click();
        } else if (u instanceof KeyBoard k) {
            k.keyDown();
        } else {
            System.out.println("不符合");
        }
        u.unconnect();
    }
}
class Test1 {
    public static void main(String[] args) {
        Computer c = new Computer();
        USB u = new Mouse("罗技鼠标");
        c.installUSB(u);
        USB k = new KeyBoard("双飞燕键盘");
        c.installUSB(k);
    }
}
D:\Java\jdk-17\bin\java.exe "-javaagent:D:\BaiduNetdiskDownload\IntelliJ IDEA 2022.2.3\lib\idea_rt.jar=32512:D:\BaiduNetdiskDownload\IntelliJ IDEA 2022.2.3\bin" -Dfile.encoding=UTF-8 -classpath F:\IdeaProjects\JavaSenior\out\production\oop-polymorphism com.itheima.poly2.Test1
罗技鼠标成功的接入了设备~~~
罗技鼠标双击点亮小红心~~~
罗技鼠标成功的从设备弹出~~~
双飞燕键盘成功的接入了设备~~~
双飞燕键盘写下了:老铁,6666,下次再来哦,老弟~~~~
双飞燕键盘成功的从设备弹出~~~

Process finished with exit code 0

你可能感兴趣的:(#,面向对象,java,开发语言,多态)