作爲面嚮對象語言的四大核心特性之一,繼承(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”關係
- 除非所有繼承的方法都有意義,否則不要使用繼承
- 在覆蓋方法時不要改變預期的行爲
- 使用多態而非類型信息
- 不要過多的使用反射