In-depth analysis of Java polymorphism advanced learning

Table of contents
  • 1. Dynamic binding mechanism
    • Example A
    • Example B
    • Example C
  • 2. Polymorphic array
  • 3. Advanced usage of polymorphic arrays
  • 4. Polymorphic parameters
  • 5. Advanced usage of polymorphic parameters

1. Dynamic binding mechanism

Java's dynamic binding mechanism is very important

Example A

Let's look at an example:

Reading the above code, please explain what the following program will output:

The program will output 40 and 30. This example is very simple, just look at the running type. The running type of the code is B, so the method of class B will be called

Example B

Let's modify the above code and log out the following code block in the subclass:

Then the inheritance mechanism will access the sum method of the parent class:

So here is a question, will getI() here execute the subclass or the parent class?

When calling an object method, the method will be bound to the memory address/running type of the object

The running type of the code is still B, so the getI() method of the subclass will be executed here, and the result output is 30

Example C

Now let's modify the above code as follows

Then cancel the following code block in the subclass:

The inheritance mechanism will execute the sum1 method of the parent class:

So here is a question, will the i here use the subclass or the parent class?

There is no dynamic binding mechanism for attributes, where they are declared and where they are used (using the current class)

The i here is declared in the parent class, so the i attribute of the parent class will be selected, and the result is 20

2. Polymorphic array

definition:

The definition type of the array is the parent class type, but the actual element type saved is the subclass type

Person parent class:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

/**

 * 多态数组父类

 */

public 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 + '\t' + age;

    }

}

Student subclass:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

/**

 * 多态数组学生子类

 */

public class Student extends Person{

    private double score;

    public Student(String name, int age, double score) {

        super(name, age);

        this.score = score;

    }

    // 重写父类的say方法

    public String say() {

        return super.say() + '\t' + score;

    }

}

Teacher subclass:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

/**

 * 多态数组教师子类

 */

public class Teacher extends Person {

    private double sal;

    public Teacher(String name, int age, double sal) {

        super(name, age);

        this.sal = sal;

    }

    public double getSal() {

        return sal;

    }

    public void setSal(double sal) {

        this.sal = sal;

    }

    public String say() {

        return super.say() + '\t' + sal;

    }

}

Test the use of polymorphic arrays:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

public class Test {

    public static void main(String[] args) {

        // 多态数组的使用

        Person[] persons = new Person[5];

        persons[0] = new Person("dahe",20);

        persons[1] = new Student("wangwei",11,100);

        persons[2] = new Student("zhangsan",12,60);

        persons[3] = new Teacher("wang",33,15000);

        persons[4] = new Teacher("li",55,25000);

        // 循环遍历多态数组,调用say方法

        for (int i = 0; i < persons.length; i++) {

            String out = persons[i].say(); // 动态绑定机制,编译类型永远都是Person

            // 运行类型是根据实际情况由JVM机决定

            System.out.println(out);

        }

    }

}

output:

dahe 20
wangwei 11 100.0
zhangsan 12 60.0
wang 33 15000.0
li 55 25000.0

3. Advanced usage of polymorphic arrays

The Teacher subclass now has a new teaching method:

?

1

2

3

public void teach() {

    System.out.println("老师:" + getName() + "正在讲课!");

}

The student subclass has a new learning method:

?

1

2

3

public void study() {

    System.out.println("学生:" + getName() + "正在学习!");

}

So, is there a way to access the unique methods corresponding to their subclasses through polymorphic arrays? In fact, it can be solved by clever use of instanceof:

As a workaround, change the loop operation for polymorphic arrays:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

// 循环遍历多态数组,调用say方法

for (int i = 0; i < persons.length; i++) {

    String out = persons[i].say(); // 动态绑定机制,编译类型永远都是Person

    // 运行类型是根据实际情况由JVM机决定

    System.out.println(out);

    if (persons[i] instanceof Student) {

        // 向下转型

        Student student = (Student) persons[i];

        student.study();

    } else if (persons[i] instanceof Teacher) {

        Teacher teacher = (Teacher) persons[i];

        teacher.teach();

    }

}

output:

dahe 20
wangwei 11 100.0
students: wangwei is studying!
Zhangsan 12 60.0
Student: Zhangsan is learning!
Wang 33 15000.0
Teacher: Wang is giving a lecture!
li 55 25000.0
Teacher: li is giving a lecture!

You're done! Polymorphic arrays are powerful and perfect!

4. Polymorphic parameters

The formal parameter type of the method definition is the parent class type, and the actual parameter type is allowed to be the subclass type

Next, let's demonstrate the use of the following polymorphic parameters:

father:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

/**

 * 多态参数 - 父类

 */

public class Employee {

    private String name;

    private double sal;

    public Employee(String name, double sal) {

        this.name = name;

        this.sal = sal;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public double getSal() {

        return sal;

    }

    public void setSal(double sal) {

        this.sal = sal;

    }

    // 得到年工资的方法

    public double getAnnual() {

        return 12 * sal;

    }

}

Employee Subclass:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

/**

 * 多态参数 - 子类员工

 */

public class Worker extends Employee{

    public Worker(String name, double sal) {

        super(name, sal);

    }

    public void work() {

        System.out.println("普通员工:" + getName() + "正在工作!");

    }

    public double getAnnual() {

        return super.getAnnual();

    }

}

Manager subclass:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

/**

 * 多态参数 - 经理子类

 */

public class Manager extends Employee{

    private double bonus; // 奖金

    public Manager(String name, double sal, double bonus) {

        super(name, sal);

        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() + bonus;

    }

}

Let's test it and find the annual salary of employees in different positions:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

/**

 * 多态参数测试类

 */

public class Test {

    public static void main(String[] args) {

        Worker zhang = new Worker("张工",1000);

        Manager milan = new Manager("milan", 5000, 2000);

        Test test = new Test();

        test.showEmpAnnual(zhang);

        test.showEmpAnnual(milan);

    }

    // 获取员工的年薪,采用多态参数

    public void showEmpAnnual(Employee e) {

        System.out.println(e.getAnnual());

    }

}

output:

12000.0
62000.0

5. Advanced usage of polymorphic parameters

Let's improve the polymorphic parameter code above. If the input is an employee, call your own work method, and if the input is a manager, call your own manage method

Add the following method:

?

1

2

3

4

5

6

7

public void testWork(Employee e) {

    if (e instanceof Worker) {

        ((Worker) e).work(); // 向下转型

    } else if (e instanceof Manager) {

        ((Manager) e).manage();

    }

}

test:

?

1

2

test.testWork(zhang);

test.testWork(milan);

output:

Ordinary employees: Mr. Zhang is working!
Manager: milan is managing!

Guess you like

Origin blog.csdn.net/qq_15509251/article/details/131549506