20220727-Java中多态总结


格言:我亦无他,唯手熟尔!


多态polymorphism:方法或者对象具有多种形态

1.方法的多态

1) 方法的重载可以体现多态

代码示例

// 通过方法重载,展现同一种方法的不同形态
public class PolyMethod {
    public static void main(String[] args) {
        AA aa = new AA();
        aa.f();
        aa.f(1);
        aa.f(1, 2);
    }
}
class AA {
    public void f() {
        System.out.println("f()");
    }
    public void f(int i) {
        System.out.println("f(i)");
    }
    public void f(int i, int j) {
        System.out.println("f(i,j)");
    }
}

2) 方法的重写可以体现多态

代码示例

// 通过子类继承父类并重写父类中的方法,体现同一个方法的不同形态
public class PolyMethod02 {
    public static void main(String[] args) {
        BB bb = new BB();
        bb.f();
        BBB bbb = new BBB();
        bbb.f();
    }
}
class BB {
    public void f() {
        System.out.println("BB f()");
    }
}
class BBB extends BB {
    @Override
    public void f() {
        System.out.println("BBB f()");
    }
}

2.对象的多态

  1. 对象的编译类型与运行类型可以不同
  2. 对象的编译类型在定义对象的时候就确定了不能更改
  3. 对象的运行类型可以改变
  4. 对象的编译类型看创建对象时=的左边,运行类型看=的右边
    • Animal animal = new Dog();
    • animal = new Cat();

代码示例

public class PolyObject {
    public static void main(String[] args) {
        People people = new Student();
        //people编译类型为People,运行类型为Student
        //System.out.println(people.id);
        //people.f2();
        System.out.println("name=" + people.name);
        System.out.println(people.show());
    }
}
class People {
    String name = "jack";
    int age = 18;
    public void f1() {
        System.out.println("People f1()");
    }
    public String show() {
        return "name=" + name + ",age=" + age;
    }
}
class Student extends People {
    int id = 1;
    double score = 100;
    @Override
    public String show() {
        return super.show() + ",id=" + id + ",score=" + score;
    }
    public void f2() {
        System.out.println("Student f2()");
    }
}

3.多态的注意事项和细节

  1. 使用父类对象引用可以调用父类中的所有成员(遵守访问权限)
  2. 使用父类对象引用不能调用子类的特有成员(编译阶段,只能按编译类型访问)
  3. 最终的运行效果,看运行类型
  4. !!!属性没有多态之说,属性的值直接看编译类型
  5. instanceof比较操作符,用于判断对象的运行类型是否为XX类型或者XX类型的子类型

代码示例

public class PolyDetail02 {
    public static void main(String[] args) {
        A a = new B();
        System.out.println(a.count);
        //System.out.println(a.x);
    }
}
class A{
    int count = 10;
}
class B extends A{
    int count = 20;
    int x = 100;
}

代码示例

public class PolyDetail03 {
    public static void main(String[] args) {
        C c = new D();
        System.out.println(c instanceof C);
        System.out.println(c instanceof D);
        System.out.println(c instanceof Object);
        D d = new D();
        System.out.println(d instanceof C);
        System.out.println(d instanceof D);
        C cc = new C();
        System.out.println(cc instanceof C);
        System.out.println(cc instanceof D);
    }
}
class C {}
class D extends C {}

4.向下转型

  1. 语法:子类类型 变量=(子类类型)父类引用;
  2. 只能强转父类的引用,而不能强转父类的对象
  3. 要求父类的引用必须指向当前目标类型的对象
  4. 当向下转型后,可以调用子类类型中所有的成员

5.Java动态绑定机制

  1. 当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定
  2. 当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用

代码示例

public class DynamicBinding {
    public static void main(String[] args) {
        A a = new B();
        System.out.println(a.sum());
        System.out.println(a.sum1());
    }
}
class A {
    public int i = 10;
    public int sum() {
        return getI() + 10;
    }
    public int sum1() {
        return i + 10;
    }
    public int getI() {
        return i;
    }
}
class B extends A {
    public int i = 20;
    @Override
    public int sum() {
        return getI() + 20;
    }
    @Override
    public int sum1() {
        return i + 10;
    }
    @Override
    public int getI() {
        return i;
    }
}

6.动态数组

  • 数组类型为父类类型,实际存放的数组元素为父类类型或者子类类型对象

代码示例

public class PolyArray {
    public static void main(String[] args) {
        // 创建Person类型的数组
        // 数组中存放Person类对象和其子类对象
        // 数组p的编译类型为Peron,运行类型动态绑定
        Person[] p = new Person[5];
        p[0] = new Person("A", 1);
        p[1] = new Student("B", 2, 100);
        p[2] = new Student("C", 3, 200);
        p[3] = new Teacher("D", 4, 20000);
        p[4] = new Teacher("E", 5, 30000);
        for (Person pp : p) {
            System.out.println(pp.say());
            //当调用子类的特有方法时,使用instanceof
            if (pp instanceof Student) {
                ((Student) pp).study();
            }
            if (pp instanceof Teacher) {
                ((Teacher) pp).teach();
            }
        }
    }
}
class Person {
    private String name;
    private int age;
    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 String say() {
        return "name=" + name + " age=" + age;
    }
}
class Student extends Person {
    private int score;
    public Student(String name, int age, int score) {
        super(name, age);
        this.score = score;
    }
    public int getScore() {
        return score;
    }
    public void setScore(int score) {
        this.score = score;
    }
    @Override
    public String say() {
        return super.say() + " score=" + score;
    }
    public void study() {
        System.out.println("学生 " + getName() + " 正在上课");
    }
}
class Teacher extends Person {
    private int salary;
    public Teacher(String name, int age, int salary) {
        super(name, age);
        this.salary = salary;
    }
    public int getSalary() {
        return salary;
    }
    public void setSalary(int salary) {
        this.salary = salary;
    }
    @Override
    public String say() {
        return super.say() + " salary=" + salary;
    }
    public void teach() {
        System.out.println("老师 " + getName() + "正在授课");
    }
}

7.动态参数

  • 方法定义的形参类型为父类类型,实参类型允许为子类类型

代码示例

public class PolyParameter {
    public static void main(String[] args) {
        PolyParameter p = new PolyParameter();
        Employee[] e = new Employee[3];
        e[0] = new Employee("A", 100);
        e[1] = new Worker("B", 1000);
        e[2] = new Manager("C", 10000, 5000);
        for (Employee ee : e) {
            p.showEmpAnnual(ee);
            p.testWork(ee);
        }
    }
    public void showEmpAnnual(Employee e) {
        System.out.println(e.getName() + "的工资为:" + e.getAnnual());
    }
    public void testWork(Employee e) {
        if (e instanceof Worker) {
            ((Worker) e).work();
        } else if (e instanceof Manager) {
            ((Manager) e).manage();
        } else if (e instanceof Employee) {
        } else {
            System.out.println("类型有误");
        }
    }
}
class Employee {
    private String name;
    private double salary;
    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public double getAnnual() {
        return getSalary();
    }
}
class Worker extends Employee {
    public Worker(String name, double salary) {
        super(name, salary);
    }
    public void work() {
        System.out.println("普通员工 " + getName() + " 正在工作");
    }
    @Override
    public double getAnnual() {
        return super.getAnnual();
    }
}
class Manager extends Employee {
    private double bonus;
    public Manager(String name, double salary, double bonus) {
        super(name, salary);
        this.bonus = bonus;
    }
    public double getBonus() {
        return bonus;
    }
    public void setBonus(double bonus) {
        this.bonus = bonus;
    }
    public void manage() {
        System.out.println("经理 " + getName() + " 正在进行管理");
    }
    @Override
    public double getAnnual() {
        return super.getAnnual() + getBonus();
    }
}
posted @ 2022-07-28 08:44  淡忘的江南  阅读(86)  评论(0)    收藏  举报