第十一章

繼承


11.1 簡介繼承

繼承圖


添加子類別方法

public class SavingsAccount extends BankAccount
{
   public SavingsAccount(double rate)
   {
      interestRate = rate;
   }

   public void addInterest()
   {
      double interest = getBalance() * interestRate / 100;
      deposit(interest);
   }

   private double interestRate;
}

子類別物件Layout


SavingsAccount 的個體變數 balance 是繼承自 BankAccount 類別, 個體變數 interestRate 則是新增的。

Syntax 11.1: 繼承

  class SubclassName extends SuperclassName {
   methods
   instance fields

}

例:

 
public class SavingsAccount extends BankAccount
{
   public SavingsAccount(double rate)
   {
      interestRate = rate;
   }

   public void addInterest()
   {
      double interest = getBalance() * interestRate / 100;
      deposit(interest);
   }

   private double interestRate;
}

用途:

To define a new class that inherits from an existing class, and define the methods and instance fields that are added in the new class.

11.2 繼承階層

銀行帳戶階層

例如銀行提供下列兩種帳戶:
  1. 支票帳戶沒有利息, 每月基本的來往次數是免費的, 額外的來往每次都要付費。
  2. 儲蓄帳戶有利息, 每月複利計息。

類別階層設計

11.3 繼承個體資料和方法

繼承方法

繼承個體資料

CheckingAccount 類別

繼承的個體資料是私有的

啟用父類別的方法

Syntax 11.2: 呼用父類別的方法

  super.methodName(parameters)

例:

 
  public void deposit(double amount)
  {
    transactionCount++;
    super.deposit(amount);
  }

用途:

To call a method of the superclass instead of the method of the current class

11.4 父類別的建構

public class CheckingAccount extends BankAccount
{
   public CheckingAccount(double initialBalance)
   {
      // construct superclass 
      super(initialBalance); 
      // initialize transaction count 
      transactionCount =0;
   }
   ...
}

Syntax 11.3: 呼用父類別的建構式

  ClassName(parameters)
{
   super(parameters);
   . . .
}

例:

 
public CheckingAccount(double initialBalance)
{
   super(initialBalance);
   transactionCount =0;
}

用途:

To invoke a constructor of the superclass. Note that this statement must be the first statement of the subclass constructor.

11.5 子類別換成父類別

多型

File AccountTest.java


/**
   This program tests the BankAccount class and
   their subclasses.
*/
 public class AccountTest
{
   public static void main(String[] args)
   {
      SavingsAccount momsSavings
         = new SavingsAccount(0.5);

      CheckingAccount harrysChecking
         = new CheckingAccount(100);

      momsSavings.deposit(10000);

      momsSavings.transfer(harrysChecking, 2000);
      harrysChecking.withdraw(1500);
      harrysChecking.withdraw(80);

      momsSavings.transfer(harrysChecking, 1000);
      harrysChecking.withdraw(400);

      // simulate end of month
      momsSavings.addInterest();
      harrysChecking.deductFees();

      System.out.println("Mom's savings balance = $"
         + momsSavings.getBalance());

      System.out.println("Harry's checking balance = $"
         + harrysChecking.getBalance());
   }
}


File BankAccount.java


/**
   A bank account has a balance that can be changed by
   deposits and withdrawals.
*/
public class BankAccount
{
   /**
      Constructs a bank account with a zero balance
   */
   public BankAccount()
   {
      balance = 0;
   }

   /**
      Constructs a bank account with a given balance
      @param initialBalance the initial balance
   */
   public BankAccount(double initialBalance)
   {
      balance = initialBalance;
   }

   /**
      Deposits money into the bank account.
      @param amount the amount to deposit
   */
   public void deposit(double amount)
   {
      balance = balance + amount;
   }

   /**
      Withdraws money from the bank account.
      @param amount the amount to withdraw
   */
   public void withdraw(double amount)
   {
      balance = balance - amount;
   }

   /**
      Gets the current balance of the bank account.
      @return the current balance
   */
   public double getBalance()
   {
      return balance;
   }

   /**
      Transfers money from the bank account to another account
      @param other the other account
      @param amount the amount to transfer
   */
   public void transfer(BankAccount other, double amount)
   {
      withdraw(amount);
      other.deposit(amount);
   }

   private double balance;
}


File CheckingAccount.java


/**
   A checking account that charges transaction fees.
*/
public class CheckingAccount extends BankAccount
{
   /**
      Constructs a checking account with a given balance
      @param initialBalance the initial balance
   */
   public CheckingAccount(int initialBalance)
   {
      // construct superclass
      super(initialBalance);

      // initialize transaction count
      transactionCount = 0;
   }

   public void deposit(double amount)
   {
      transactionCount++;
      // now add amount to balance 
      super.deposit(amount);
   }

   public void withdraw(double amount)
   {
      transactionCount++;
      // now subtract amount from balance 
      super.withdraw(amount);
   }

   /**
      Deducts the accumulated fees and resets the
      transaction count.
   */
   public void deductFees()
   {
      if (transactionCount > FREE_TRANSACTIONS)
      {
         double fees = TRANSACTION_FEE *
            (transactionCount - FREE_TRANSACTIONS);
         super.withdraw(fees);
      }
      transactionCount = 0;
   }

   private int transactionCount;

   private static final int FREE_TRANSACTIONS = 3;
   private static final double TRANSACTION_FEE = 2.0;
}


File SavingsAccount.java


/**
   An account that earns interest at a fixed rate.
*/
public class SavingsAccount extends BankAccount
{
   /**
      Constructs a bank account with a given interest rate
      @param rate the interest rate
   */
   public SavingsAccount(double rate)
   {
      interestRate = rate;
   }

   /**
      Adds the earned interest to the account balance.
   */
   public void addInterest()
   {
      double interest = getBalance() * interestRate / 100;
      deposit(interest);
   }

   private double interestRate;
}


11.6 存取控制層次

建議使用的存取控制層次

11.7 Object: 無所不包的父類別

Object 類別是每一 Java 類別的父類別


覆寫 toString 方法

覆寫 equals 方法

指到兩個內容相同的物件的兩個參考

指到同一物件的兩個參考


覆寫 clone 方法