数组的定义类型为父类型,里面保存的实际元素类型为子类型。

应用案例:

  • 要求创建一个Person对象,2个Student对象和2个Teacher对象,统一放在数组中,并调用每个对象的say方法。
  • 如何调用子类特有的方法,比如Teacher有一个teach,Student有一个study,怎么调用?

image.pngimage.png

Person

  1. package test;
  2. public class Main {
  3. public static void main(String[] args) {
  4. //应用实例:现有一个继承结构如下:要求创建1个Person对象、
  5. // 2个Student 对象和2个Teacher对象, 统一放在数组中,并调用每个对象say方法
  6. //父类的引用可以指向子类的对象
  7. Person[] persons = new Person[5];
  8. persons[0] = new Person("jack", 20);
  9. persons[1] = new Student("mary", 18, 100);
  10. persons[2] = new Student("smith", 19, 30.1);
  11. persons[3] = new Teacher("scott", 30, 20000);
  12. persons[4] = new Teacher("king", 50, 25000);
  13. //循环遍历多态数组,调用say
  14. for (int i = 0; i < persons.length; i++) {
  15. // person[i] 编译类型是 Person ,运行类型是是根据实际情况由JVM来判断
  16. System.out.println(persons[i].say());//动态绑定机制
  17. //编译类型Person中不含有这两个方法
  18. // persons[i].teach();//报错!!!
  19. // persons[i].study();//报错!!!
  20. //解决方案: 使用 类型判断 + 向下转型.
  21. if (persons[i] instanceof Student) {//判断person[i] 的运行类型是不是Student
  22. Student student = (Student) persons[i];//向下转型
  23. student.study();
  24. //也可以使用一条语句 ((Student)persons[i]).study();
  25. } else if (persons[i] instanceof Teacher) {
  26. Teacher teacher = (Teacher) persons[i];
  27. teacher.teach();
  28. } else if (persons[i] instanceof Person) {
  29. //就是Person类型,不做处理
  30. } else {
  31. System.out.println("你的类型有误, 请自己检查...");
  32. }
  33. }
  34. }
  35. }

Student

  1. package test;
  2. public class Student extends Person {
  3. private double score;
  4. public Student(String name, int age, double score) {
  5. super(name, age);
  6. this.score = score;
  7. }
  8. public double getScore() {
  9. return score;
  10. }
  11. public void setScore(double score) {
  12. this.score = score;
  13. }
  14. //重写父类say
  15. @Override
  16. public String say() {
  17. return "学生 " + super.say() + " score=" + score;
  18. }
  19. //特有的方法
  20. public void study() {
  21. System.out.println("学生 " + getName() + " 正在学java...");
  22. }
  23. }

Teacher

  1. package test;
  2. public class Teacher extends Person {
  3. private double salary;
  4. public Teacher(String name, int age, double salary) {
  5. super(name, age);
  6. this.salary = salary;
  7. }
  8. public double getSalary() {
  9. return salary;
  10. }
  11. public void setSalary(double salary) {
  12. this.salary = salary;
  13. }
  14. //写重写父类的say方法
  15. @Override
  16. public String say() {
  17. return "老师 " + super.say() + " salary=" + salary;
  18. }
  19. //特有方法
  20. public void teach() {
  21. System.out.println("老师 " + getName() + " 正在讲java课程...");
  22. }
  23. }

Main

  1. package test;
  2. public class Main {
  3. public static void main(String[] args) {
  4. //应用实例:现有一个继承结构如下:要求创建1个Person对象、
  5. // 2个Student 对象和2个Teacher对象, 统一放在数组中,并调用每个对象say方法
  6. //父类的引用可以指向子类的对象
  7. Person[] persons = new Person[5];
  8. persons[0] = new Person("jack", 20);
  9. persons[1] = new Student("mary", 18, 100);
  10. persons[2] = new Student("smith", 19, 30.1);
  11. persons[3] = new Teacher("scott", 30, 20000);
  12. persons[4] = new Teacher("king", 50, 25000);
  13. //循环遍历多态数组,调用say
  14. for (int i = 0; i < persons.length; i++) {
  15. // person[i] 编译类型是 Person ,运行类型是是根据实际情况由JVM来判断
  16. System.out.println(persons[i].say());//动态绑定机制
  17. //编译类型Person中不含有这两个方法
  18. // persons[i].teach();//报错!!!
  19. // persons[i].study();//报错!!!
  20. //解决方案: 使用 类型判断 + 向下转型.
  21. if (persons[i] instanceof Student) {//判断person[i] 的运行类型是不是Student
  22. Student student = (Student) persons[i];//向下转型
  23. student.study();
  24. //也可以使用一条语句 ((Student)persons[i]).study();
  25. } else if (persons[i] instanceof Teacher) {
  26. Teacher teacher = (Teacher) persons[i];
  27. teacher.teach();
  28. } else if (persons[i] instanceof Person) {
  29. //就是Person类型,不做处理
  30. } else {
  31. System.out.println("你的类型有误, 请自己检查...");
  32. }
  33. }
  34. }
  35. }

image.png