[連載]Java程式設計(04)---任務驅動的方法:工資結算系統

來源:互聯網
上載者:User

標籤:

任務:或在公司,該公司將其分為三類人員:部門經理、銷售人員。在發工資的時候,部門經理拿固定月薪8000元。技術人員按每小時100元領取月薪。銷售人員依照500元底薪加當月銷售額的4%進行提成。設計並實現一個工資結算系統。

分析:無論是部門經理、技術員還是銷售人員都具有員工的共同特徵。能夠先設計一個員工類(Employee)。並將結算工資的方法設計為抽象方法,由於不同的員工有不同的結算工資的方式,須要進行多態實現。所謂的抽象方法就是沒有方法體並被abstract修飾符修飾的方法。假設一個類中有抽象方法,這個類就要被聲明為抽象類別。抽象類別不能執行個體化,也就是說不能建立抽象類別的對象。接下來能夠在員工類的基礎上派生出經理類(Manager)、技術員類(Technician)和銷售人員類(Salesman),這三個類要對員工類中的抽象方法進行重寫(override),給出自己的結算工資的方法的實現,這個過程稱為繼承(inheritance),這是物件導向程式設計的三大支柱之中的一個。接下來,在須要進行工資結算時。能夠將全部的員工對象都賦值給Employee類型的引用(由於無論是部門經理、技術員還是銷售人員都是員工,父類型的引用能夠引用子類型的對象,這是上轉型不須要強制的類型轉換)。再用相同的引用調用相同的結算工資的方法。這樣相同的引用調用相同的方法卻做了不同的事(每種員工結算工資的方式全然不一樣),這就是物件導向最精髓的東西——多態(polymorphism),它和封裝(encapsulation)、繼承一起構成了物件導向的三大支柱。

以下是該系統的UML類圖。


UML(Unified Modeling Language)稱為整合模組化語言,。UML是一種開放的方法,用於說明、可視化、構建和編寫一個正在開發的、物件導向的、軟體密集系統的製品的開發方法。UML展現了一系列最佳project實踐,這些最佳實務在對大規模。複雜系統進行建模方面,特別是在軟體架構層次已經被驗證有效。

簡單的說,UML是一種圖形化的語言,提供了繪製軟體project圖紙的標準符號。

上面的圖是UML中的類圖,它描寫敘述了系統中的類以及類與類之間的關係,當中空心的三角型箭頭表示繼承關係。類與類之間的關係除了繼承(IS-A關係)外,還有關聯(HAS-A關係)和依賴(USE-A關係)。

該系統的代碼例如以下所看到的:

Employee.java

package com.lovo.salsys;/** * 員工類 * @author 駱昊 */public abstract class Employee {private String name; // 姓名/** * 構造器 * @param name 員工姓名 */public Employee(String name) {this.name = name;}/** * 結算工資 * @return 當月月薪 */public abstract double getSalary();/** * 獲得員工姓名 * @return 姓名 */public String getName() {return name;}@Overridepublic String toString() {return name;}}

Manager.java

package com.lovo.salsys;/** * 部門經理類 * @author 駱昊 */public class Manager extends Employee {public Manager(String name) {super(name);}public double getSalary() {return 8000.0;}public String toString() {return "[部門經理]" + super.toString();}}

Technician.java

package com.lovo.salsys;/** * 技術工類 * @author 駱昊 */public class Technician extends Employee {private int workingHour;// 工作時間public Technician(String name) {super(name);}public void setWorkingHour(int workingHour) {this.workingHour = workingHour;}public double getSalary() {return 100 * workingHour;}public String toString() {return "[技 術 工]" + super.toString();}}

Salesman.java

package com.lovo.salsys;/** * 銷售人員類 * @author 駱昊 */public class Salesman extends Employee {private double sales;// 銷售額public Salesman(String name) {super(name);}public void setSales(double sales) {this.sales = sales;}public double getSalary() {return 500 + sales * 0.04;}public String toString() {return "[銷 售 員]" + super.toString();}}

以下是工資結算系統的執行程式SalarySystemRunner.java

package com.lovo.salsys;import java.util.Scanner;class SalarySystemRunner {public static void main(String[] args) {Scanner sc = new Scanner(System.in);String[] names = {"張飛", "關羽", "馬超", "黃忠", "趙雲"};Employee[] emps = new Employee[names.length];for(int i = 0; i < emps.length; i++) {int empType = (int) (Math.random() * 3);switch(empType) {case 0: emps[i] = new Manager(names[i]); break;case 1: emps[i] = new Technician(names[i]); break;case 2: emps[i] = new Salesman(names[i]); break;}System.out.println(emps[i]);}for(Employee e : emps) {if(e instanceof Technician) {System.out.print("請輸入" + e.getName() + "的本月工作時間: ");((Technician) e).setWorkingHour(sc.nextInt());}else if(e instanceof Salesman) {System.out.print("請輸入" + e.getName() + "的本月銷售額: ");((Salesman) e).setSales(sc.nextDouble());}System.out.println(e.getName() + "本月工資為: $" + e.getSalary());}sc.close();}}

在此,我們能夠為多態下一個更為高大上的定義。其實。類中的執行個體方法就是對象能夠向外界提供的服務,假設站在服務的角度來理解多態,能夠這樣解釋多態:當A系統訪問B系統提供的服務時,B系統有多種提供服務的方式,可是對A系統來說是透明的。上面範例中,A系統就是工資結算系統的執行程式,B系統就是員工系統,員工系統中的結算工資的方法就是B系統向A系統提供的服務。每種員工結算工資的方式都不同,可是A系統僅僅知道員工有結算工資的方法。並不瞭解B系統中部門經理、技術工和銷售人員都對該方法做出了不同的實現版本號碼(多態實現),因此這些對A系統就是透明的(看不見的)。

實現多態有兩個關鍵點:方法重寫(子類在繼承過程中重寫父類方法)和對象造型(將子類對象賦值給父類引用)。這裡事實上涉及到了物件導向程式設計兩個很重要的原則。一是依賴倒轉原則(Dependency Inversion Principle),二是裡氏代換原則(Liskov Substitution Principal)。依賴倒轉原則講的是要面向介面編程,而不要面向實現編程。詳細的說就是,當定義方法的參數類型、方法的傳回型別、對象的參考型別時,有抽象類別型儘可能使用抽象類別型。上面的範例中,我們將各種不同類型的員工對象對裝在Employee類型的數組中就是將對象的參考型別定義為抽象類別型。裡氏代換原則講的是不論什麼時候都能夠用子類對象替換父類對象。也就是說能使用父類型的地方就一定能使用子類型。這樣假設一個方法的參數是父類型對象。傳入它的不論什麼一個子類型都沒有問題。假設子類對父類中的方法給出了不同的實現的版本號碼。那在用父類型的引用調用該方法時就會表現出多態行為。相同的道理,假設一個方法的傳回型別是父類型。則在方法中能夠返回該父類型的不論什麼一個子類型對象,這種話我們在建立對象的時候能夠編寫一個Factory 方法,從而從建立出不同的子類對象,這就是GoF靜態設計模式原廠模式。讓我們來解釋一下在下一章這種設計通過執行個體。

著作權聲明:本文部落格原創文章,部落格,未經同意,不得轉載。

[連載]Java程式設計(04)---任務驅動的方法:工資結算系統

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.