10.2. 多态

10.2.1. 多态概念

发生多态要有三个前提条件:

1. 继承。多态发生一定要子类和父类之间。
2. 覆盖。子类覆盖了父类的方法。
3. 声明的变量类型是父类类型,但实例则指向子类实例。

代码示例

父类:Figure.java

package duotai01_Class;

public class Figure {
 public void onDraw() {
  System.out.println("绘制Figure......");
 }

}

子类:Ellipse.java

package duotai01_Class;

public class Ellipse extends Figure {

// 绘制集合图形方法
 @Override
 public void onDraw() {
  System.out.println("绘制椭圆形...........");
 }
}

子类:Ttiangle.java

package duotai01_Class;

public class Ttiangle extends Figure {
 // 绘制几何图形方法
 @Override
 public void onDraw() {
  System.out.println("绘制三角形........");
 }
}

调用主代码

package duotai01_Class;

public class HelloWorld {

 public static void main(String[] args) {
  // TODO 自动生成的方法存根
//  实例化父类
  Figure f1 = new Figure();
  f1.onDraw();

//  实例化子类Ttiangle
  Ttiangle f2 = new Ttiangle();
  f2.onDraw();

//  实例化子类Ellipse
  Ellipse f3 = new Ellipse();
  f3.onDraw();
 }

}

/*
绘制Figure......
绘制三角形........
绘制椭圆形...........
*/

10.2.2. 引用类型检查

有时候需要在运行时判断一个对象是否属于某个引用类型,这时可以使用instanceof运算符, instanceof运算符语法格式如下:

obj instanceof type

代码示例 父类 Person.java

package duotai02_Class;

public class Person {
 String name;
 int age;

 public Person(String name, int age) {
  this.name = name;
  this.age = age;
 }

 @Override
 public String toString() {
  return "Person [name=" + name + ", age=" + age + "]";
 }
}

子类 Worker.java

package duotai02_Class;

public class Worker extends Person {
 String factory;

 public Worker(String name, int age, String factory) {
  // TODO 自动生成的构造函数存根
  super(name, age);
  this.factory = factory;
 }

 @Override
 public String toString() {
  // TODO 自动生成的方法存根
  return "Worker [factory=" + factory
    + ", name=" + name
    + ", age=" + age + "]";
 }
}

子类 Student.java

package duotai02_Class;

public class Student extends Person {
 String school;

 public Student(String name, int age,String school) {
  // TODO 自动生成的构造函数存根
  super(name, age);
  this.school = school;
 }

 @Override
 public String toString() {
  // TODO 自动生成的方法存根
  return "Student [school=" + school
    + ", name=" + name
    + ", age=" + age + "]";
 }
}

调用代码

package duotai02_Class;

public class HelloWorld {
 public static void main(String[] args) {
  Student student1 = new Student("胡建力1", 17, "清华大学");
  Student student2 = new Student("胡建力2", 20, "西安电子科技大学");
  Student student3 = new Student("胡建力", 21, "中山大学");

  Worker worker1 = new Worker("TOM", 19, "电子厂");
  Worker worker2 = new Worker("TOMNI", 20, "钢材厂");

  Person[] people = { student1, student2, student3, worker1, worker2 };

  int studentCount = 0;
  int workerCount = 0;

  for (Person person : people) {
   if (person instanceof Worker) {
    workerCount++;
   } else if (person instanceof Student) {
    studentCount++;
   }
  }
  System.out.printf("工人人数: %d. \n 学生人数:%d", workerCount, studentCount);
 }

}

/*
工人人数: 2.
 学生人数:3
 */

10.2.3. 引用类型转换

只有属于同一棵继承层次树中的引用类型才可以转换。

类型转换有两个方向:

将父类引用类型变量转换为子类类型,这种转换称为向下转型(downcast);
将子类引用类型变量转换为父类类型,这种转换称为向上转型(upcast)。
向下转型需要强制转换,而向上转型是自动的。

代码示例

package duotai02_Class;

public class HelloWorld {
 public static void main(String[] args) {
  Person p1 = new Student("Tom", 18, "清华大学");
  Person p2 = new Worker("Tom", 18, "钢材厂");

  Person p3 = new Person("Tom", 20);
  Student p4 = new Student("Ben", 30, "清华大学");
  Worker p5 = new Worker("Tony", 22, "钢材厂");

  // 向上转型
  Person p = (Person) p4;
  System.out.println(p.toString());

  // 向下转型
  Student p11 = (Student) p1;
  System.out.println(p11.toString());

  Worker p12 = (Worker) p2;
  System.out.println(p12.toString());

  if (p2 instanceof Student) {
   Student p111 = (Student) p2;
   System.out.println(p111.toString());
  }else {
   System.out.println("False");
  }

  if (p1 instanceof Worker) {
   Worker p121 = (Worker) p1;
   System.out.println(p121.toString());

  }else {
   System.out.println("False");
  }

  if (p3 instanceof Student) {
   Student p131 = (Student) p3;
   System.out.println(p131.toString());

  }else {
   System.out.println("False");
  }

 }
}

/*
Student [school=清华大学, name=Ben, age=30]
Student [school=清华大学, name=Tom, age=18]
Worker [factory=钢材厂, name=Tom, age=18]
False
False
False
 */