浅析Java的up casting和down casting

先上示例代码:

(1)抽象类Person

public abstract class Person {
	private String name;
	
	public Person(String name) {
		this.name = name;
	}
	
	public abstract String getDescription();
	
	public String getName() {
		return this.name;
	}
}

(2)子类Employee

import java.time.*;

public class Employee extends Person{
	private double salary;
	private LocalDate hireDay;
	
	public Employee(String name, double salary, int year, int month, int day) {
		super(name);
		this.salary = salary;
		hireDay = LocalDate.of(year, month, day);
	}
	
	public double getSalary() {
		return this.salary;
	}
	
	public LocalDate getHireDay() {
		return this.hireDay;	
	}
	
	public String getDescription() {
		return String.format("an employee with salary of $%.2f", this.salary);
	}
	
	public void raiseSalary(double byPercent) {
		double raise = this.salary * byPercent / 100;
		this.salary += raise;
	}
}

(3)子类Student

public class Student extends Person{
	private String major;
	
	public Student(String name, String major) {
		super(name);
		this.major = major;
	}
	
	public String getDescription() {
		return "a student majoring in " + major;
	}
}

(4)程序入口

public class Test {
	public static void main(String[] args) {
		Person[] people = new Person[2];
		
		people[0] = new Employee("Joe Wong", 50000, 1989, 10, 1); // up-casting
		people[1] = new Student("Maria Morris", "Computer Science"); // up-casting
		
		
		for(Person p: people) {
			// can only access getName and getDescription
			System.out.println(p.getName() + "," + p.getDescription());
		}
		
		Employee ref = (Employee)people[0]; // down-casting, because people[0] already refers to an instance of child, OK 
		System.out.println(ref.getHireDay()); // can now access child's own method, e.g. getHireDay
  }  
}

比起C++的xxx_cast,Java真是友好多了。简单来讲,子类可以直接被赋给父类(up casting),但是此时该引用只能访问到父类的方法。如果要down casting,前提是父类的引用已经指向了一个子类的实例,例如例子中people[0]已经指向了一个Employee的实例,则cast成功,否则编译器会抛出ClassCastException异常。

进行down casting之前比较好的习惯是先用instancof进行检查:

if(people[0] instanceof Employee) {
    Employee ref = (Employee) people[0]; // down-casting, because people[0] already refers to an instance of child, OK 
    System.out.println(ref.getHireDay()); // can now access child's own method, e.g. getHireDay
}

 

你可能感兴趣的:(Java)