作为面向对象语言的四大核心特性之一,继承(inheritance)占据着举足轻重的地位,从一段代码开始:
import java.util.*;
/**
* This program demonstrates inheritance.
* @version 1.21
* @author LiMing
*/
public class ManagerTest
{
public static void main(String[] args)
{
// construct a Manager object
Manager boss = new Manager("Carl Cracker", 80000, 1987, 12, 15);
boss.setBonus(5000);
Employee[] staff = new Employee[3];
// fill the staff array with Manager and Employee objects
staff[0] = boss;
staff[1] = new Employee("Harry Hacker", 50000, 1989, 10, 1);
staff[2] = new Employee("Tommy Tester", 40000, 1990, 3, 15);
// print out information about all Employee objects
for (Employee e : staff)
System.out.println("name=" + e.getName() + ",salary=" + e.getSalary());
}
}
class Employee
{
public Employee(String n, double s, int year, int month, int day)
{
name = n;
salary = s;
GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day);
hireDay = calendar.getTime();
}
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public Date getHireDay()
{
return hireDay;
}
public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / 100;
salary += raise;
}
private String name;
private double salary;
private Date hireDay;
}
class Manager extends Employee
{
/**
* @param n the employee's name
* @param s the salary
* @param year the hire year
* @param month the hire month
* @param day the hire day
*/
public Manager(String n, double s, int year, int month, int day)
{
super(n, s, year, month, day);
bonus = 0;
}
public double getSalary()
{
double baseSalary = super.getSalary();
return baseSalary + bonus;
}
public void setBonus(double b)
{
bonus = b;
}
private double bonus;
}
- 在Java中所有的继承均为公有继承,以extends 关键字来表示。我们可以发现,子类是父类的细化,子类拥有更丰富的功能
- 在使用继承机制的时候,只需要在子类中指出与父类不同之处即可,父类的数据域以及方法会被自动继承,因此在设计继承关系的时候,应该将通用的方法放置于父类之中,将具有特殊用途的方法放置于子类之中
- 在本程序中,我们发现Manager类覆盖了了父类Employee的getSalary方法,然而调用方法的时候却发现调用的仍然是Manager类的方法,在Java中动态绑定是默认的。并且需要记住,只有父类的非private方法才可以被覆盖
- super是Java特有的表示用于调用父类方法的关键字。在调用父类构造函数的时候需要将super关键字放置在子类构造函数的首句。
- 在继承中我们可以实用final关键字来禁止子类继承父类的方法或者数据域
- protected关键字表明“就类用户而言,这是private的,而对于继承与此类的导出类或者其他任何一个位于同包中的类而言是public的”
当然关于继承的特点还有很多不再一一详述
下面列举《Java核心技术》一书中提到的关于继承的设计技巧:
- 将公有操作和域放在超类
- 不要使用受保护的域
- 使用继承实现“is-a”关系
- 除非所有继承的方法都有意义,否则不要使用继承
- 在覆盖方法时不要改变预期的行为
- 使用多态而非类型信息
- 不要过多的使用反射