第6周Java學習任務

1. 閱讀ManagerTest目錄中的代碼。

import java.util.*;

/**
 * This program demonstrates inheritance.
 * @version 1.21 2004-02-21
 * @author Cay Horstmann
 */
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;
}
  • 1)繪製UML類圖,要體現類之間的關係。
    java

  • 2)文件第26行e.getSalary(),究竟是調用Manager類的仍是Employee類的getSalary方法?
    staff[0] 調用的是Manager類的getSalary方法;
    staff[1] 和 staff[2] 調用的是Employee類的getSalary方法。
    由於 staff[0] 被幅值爲 Manager 類,子類會覆蓋父類的方法,因此 staff[0] 優先調用Manager類的getSalary方法。函數

  • 3)Manager類的構造函數使用super調用父類的構造函數實現了代碼複用,這樣有什麼好處?爲何不把父類構造函數中的相關代碼複製粘貼到Manager的構造函數中,這樣看起來不是更直觀嗎?
    採用super關鍵字調用父類的構造函數能夠減小重複代碼,同時由於子類繼承父類,會繼承到父類中的數據,因此必需要調用父類中的構造函數看父類是如何對本身的數據進行初始化的。因此子類在進行對象初始化時,先調用父類的構造函數,這就是子類的實例化過程。
    注意:
    一、子類中全部的構造函數都會默認訪問父類中的空參數的構造函數,由於每個子類構造內第一行都有默認的語句super();
    二、若父類中沒有空參數的構造函數,那麼子類的構造函數內,必須經過super語句指定要訪問的父類中的構造函數;
    三、若子類構造函數中用this來指定調用子類本身的構造函數,那麼被調用的構造函數也同樣會訪問父類中的構造函數。this

  • 4)該代碼中哪裏體現了多態的好處?請說明。
    如下代碼體現了多態性,調用e.getName() 和 e.getSalary() 時不須要設置 if 語句進行判斷,提升了代碼的維護性(繼承保證)和可拓展性(由多態保證)
for (Employee e : staff)
         System.out.println("name=" + e.getName() + ",salary=" + e.getSalary());
   }

2.閱讀GuessGame抽象類的設計與使用源代碼

  • 2.1 Guess改造前代碼很簡單,而改造後的代碼使用了抽象類、抽象方法,看起來更復雜,這樣的改造到底有什麼好處呢?

抽象類是爲了把相同的但不肯定的東西的提取出來 ,在Game中都要實行經過循環猜數字這一段代碼,抽象類GuessGame實現了這一方法,那麼遊戲的其餘部分只要直接繼承這個抽象類,再實現其餘方法就能夠了,抽象類構造出一個固定的一組行爲的抽象描述,可是這組行爲卻可以有任意個可能的具體實現方式,這樣改造有利於實現決多重繼承問題。spa

  • 2.2 GuessGame(改造後).java中有抽象方法與非抽象方法,你以爲抽象類中什麼樣的方法應該聲明爲abstract,什麼方法不須要聲明爲abstract直接實現便可。

若是繼承自這個抽象類的全部子類都存在這個方法並其的實現都是同樣的時候,則這個方法不須要聲明爲abstract直接實現便可。相反,若是子類存在這一行爲但具體實現是不同的,則應該聲明爲abstract來讓子類實現。
例如:
作一個接口叫作飛行FlyAnimalAction,裏面定義一個方法叫作flying,再定義一個方法叫作eat
作一個類叫作蚊子實現接口,蚊子要實現flying方法,實現本身的eat方法
作一個類叫作蒼蠅實現接口,蒼蠅也要實現flying方法,實現本身的eat方法
你發現全部會飛的動物都要實現這個接口,很麻煩,不如
作一個抽象類FlyAnimal,而後實現上面的接口
在裏面實現flying這個方法,由於大部分的飛行動做是同樣的,而eat方法則繼續寫成抽象方法,由於大部分的動物吃東西是不同的設計

  • ** 2.3 重要:在這個例子中,變化的是什麼,不變的是什麼?嘗試結合abstract等概念進行說明。**
    變化的是結果輸出函數,即抽象類中未被實現的抽象方法
public abstract void print(String text);
    public abstract void println(String text);
    public abstract int nextInt();

不變的是go函數,即抽象類中直接實現的方法。code

相關文章
相關標籤/搜索