# 2019/0520/繼承&存取權特性+java作業四+字符串格式化+多形+抽象類別

前情提要&#x20;繼承特性
----------

類別變數改為protected 保護

就不用用方法存取變數

但壞處就是沒辦法用商業邏輯驗證變數

且子類父類會相依性提高

## 存取權 & 繼承特性

#### 接著實作CommissionEmployeeExtV3&#xD;

![](/files/-LfP1pUY2IQ2qZ_rX7TL)

![](/files/-LfP1tdEnBeYJN4PdPcE)

可以跟V2比較

把V2變數改為

然後需要變數屬性的部分都運存取方法得到

![](/files/-LfP2OonkeLzh6-Axwd4)

維護修改的範圍限制在建構式與存取方法

![](/files/-LfP2deVQgm-Dhv8dIT_)

用呼叫的就會達到上述維護修改範圍限制的好處

super() 是一種連鎖方法 能夠呼叫直接父類別的建構式

才能在子類別繼續執行變數檢查等等的內容

Google search java se 8 object

{% embed url="<https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html>" %}

新增一個CommissionEmployeeExtV3Test 測試V3改完後功能是否正常

#### ###BasePlusCommissionEmployeeExtV3.java&#xD;

```
package com.example.java;

public class BasePlusCommissionEmployeeExtV3 extends CommissionEmployeeExtV3 {

	private double baseSalary; // 底薪

	public BasePlusCommissionEmployeeExtV3(String firstName, String lastName, String idNumber, double grossSales,double commissionRate, double baseSalary) {
		super(firstName, lastName, idNumber, grossSales, commissionRate);

		if (baseSalary < 0.0)
			throw new IllegalArgumentException("底薪金額必須 >= 0.0");

		this.baseSalary = baseSalary;
	}

	public void setBaseSalary(double baseSalary) {
		if (baseSalary < 0.0)
			throw new IllegalArgumentException("底薪金額必須 >= 0.0");

		this.baseSalary = baseSalary;
	}

	public double getBaseSalary() {
		return baseSalary;
	}

	@Override
	public double earnings() {
//		grossSales = -5000.0;
		return getBaseSalary() + (super.getCommissionRate() * super.getGrossSales());
	}

	@Override
	public String toString() {
	      return String.format("%s %n %s: %.2f" ,    
	 	         super.toString(),
	 	         "底薪金額", getBaseSalary());
	}

}

```

#### ###BasePlusCommissionEmployeeTestExtV3.java&#xD; ???

```
檔案不確定有沒有上傳但其實就是測試以上類別的方法 set 與get
```

### #繼承設計類別總結&#xD;

特殊性邏輯往子類丟

通用性邏輯往父類丟

![](/files/-LfP3nBFZe0Z9WywwPBx)

#### ##作業四

![](/files/-LfP92roVSGfi1f08Vdq)

\#作業四 繼承特性
------

#### ###Shape.java&#xD;

```
package com.example.java;

//實作Shape形狀類別

//公開存取 繼承於 Class Object 
//https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
public class Shape extends Object {
//私有存取 雙精度浮點數 double 型態變數表示 area 面積
	private double area;
//公開存取 shape(無參數) 建構子 
//this指建構式自身
//https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/this
//https://openhome.cc/Gossip/Java/This.html
//http://peimei0808.pixnet.net/blog/post/125557313-%5Bjava%5D-java%E4%B8%AD%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E3%80%8Cthis%E3%80%8D%E5%8F%8A%E5%85%B6%E5%8A%9F%E7%94%A8%E4%B9%8B%E4%BB%8B%E7%B4%B9
	public Shape() {
		this.area = 0;
	}
//公開存取 shape(double型態area參數) 建構式
//當area參數小於0時拋出錯誤訊息物件參數為 "面積必須 >=0"
	public Shape(double area) {
		if (area < 0)
			throw new IllegalArgumentException("面積必須  >= 0");
		this.area = area;
	}
//公開存取 反傳值double型態 getArea(無參數) 方法
//回傳 area變數
	public double getArea() {
		return area;
	}
//公開存取 沒有反傳值 getArea(double型態area參數) 方法
//當area參數小於0時拋出錯誤訊息物件參數為 "面積必須 >=0"
	public void setArea(double area) {
		if (area < 0)
			throw new IllegalArgumentException("\"面積必須為大於或等於0\"");
		this.area = area;
	}

//覆載Override object.toString 靜態類別方法
//https://wayne265265.pixnet.net/blog/post/115533452-%E3%80%90%E6%95%99%E5%AD%B8%E3%80%91override-%E8%88%87-overload-%E7%9A%84%E5%B7%AE%E5%88%A5
//%s : %.2f%n 為字符串格式
	@Override
	public String toString() {
		return String.format("%s : %.2f%n", "此形狀的面積為", getArea());
	}

}

```

#### ###Rectangle.java

```
package com.example.java;
//實作Rectangle長方形類別

//公開存取 繼承於 Class Shape
public class Rectangle extends Shape {
//私有存取 雙精度浮點數 double 型態變數 表示 length 長度
//私有存取 雙精度浮點數 double 型態變數 表示 width 寬度
	private double length;
	private double width;
	
//公開存取 shape(double型態length長度, double型態width寬度) 建構子 
//當Rectangle的參數小於0時拋出錯誤訊息物件參數為"長度 、寬度皆必須大於等於0"
//並將建構式帶入的參數指給私有存取的域外變數
	public Rectangle(double length, double width) {
		if ((length < 0) || (width < 0))
			throw new IllegalArgumentException("長度 、寬度皆必須大於等於0");
		this.length = length;
		this.width = width;
		ComputeArea();
	}
//公開存取 double型態反傳值  getLength(無參數) 方法
	public double getLength() {
		return length;
	}
//公開存取 無反傳值 setLength(double型態length參數) 方法
//當長度小於零時反傳"長度必須大於等於 0"
	public void setLength(double length) {
		if (length < 0)
			throw new IllegalArgumentException("長度必須大於等於 0");
		this.length = length;
	}
//公開存取 double型態反傳值 getWidth(無參數) 方法
	public double getWidth() {
		return width;
	}
//公開存取 無反傳值 setWidth(double型態width參數) 方法
//當長度小於零時反傳"寬度必須大於 0"
	public void setWidth(double width) {
		if (width < 0)
			throw new IllegalArgumentException("寬度必須大於 0");
		this.width = width;
	}
//公開存取 double型態反傳值 ComputeArea(無參數) 方法
//用getLength方法取得長度與getWidth方法取得寬度做*乘法運算將運算值傳入直接父輩方法super.setArea中
	public double ComputeArea() {
		super.setArea(getLength() * getWidth());
		return getArea();
	}
//覆載
	@Override
	public String toString() 
	{
		return String .format("%s : %.2f%n","形狀為矩形，面積為",getArea() );
	}
}

```

#### ###Triangle.java

```
package com.example.java;
//實作Triangle三角形類別

//公開存取 繼承於 Class Shape
public class Triangle extends Shape {
//私有存取 雙精度浮點數 double 型態變數 表示 base 底邊長度
//私有存取 雙精度浮點數 double 型態變數 表示 height 高度
	private double base;
	private double height;

//公開存取 Triangle(double型態base底邊長度, double型態height高度) 建構子 
//當Triangle的參數小於0時拋出錯誤訊息物件參數為"底邊 、高度皆必須大於等於0"
//並將建構式帶入的參數指給私有存取的域外變數
	public Triangle(double base, double height) {
		if ((base < 0) || (height < 0))
			throw new IllegalArgumentException("底邊 、高度皆必須大於等於0");
		this.base = base;
		this.height = height;
		ComputeArea();
	}
//公開存取 double型態反傳值  getBase(無參數) 方法
	public double getBase() {
		return base;
	}
//公開存取 無反傳值 setBase(double型態base參數) 方法
//當長度小於零時反傳"底邊必須大於0"
	public void setBase(double base) {
		if (base < 0)
			throw new IllegalArgumentException("底邊必須大於0");
		this.base = base;
	}
//公開存取 double型態反傳值 getHeight(無參數) 方法
	public double getHeight() {
		return height;
	}
//公開存取 無反傳值 getHeight(double型態height參數) 方法
//當長度小於零時反傳"高度必須大於等於0"
	public void getHeight(double height) {
		if (height < 0)
			throw new IllegalArgumentException("高度必須大於等於0");
		this.height = height;
	}
//公開存取 double型態反傳值 ComputeArea(無參數) 方法
//用getBase方法取得底邊長度與getHeight方法取得高度做*乘法後除與2運算將運算值傳入直接父輩方法super.setArea中
	public double ComputeArea() {
		setArea(getBase() * getHeight() / 2);
		return getArea();
	}
//覆載
	@Override
	public String toString() 
	{
		return String .format("%s : %.2f%n","形狀為三角形，面積為",getArea() );
	}
}

```

Hw4Test.java ( 使用上述類別與方法 且有多型?

宣告物件變數 建構式初始化時順便給予參數

接著印出

接著宣告一個物件陣列塞剛剛的物件進去

For印不同參數版本的物件值出來

#### ###Hw4Test.java

```
package com.example.java;
import com.example.java.Shape;

public class Hw4Test {

	public static void main(String[] args) {
		// TODO 自動產生的方法 Stub
		
//建構三個物件並給予參數
		Shape sp1 = new Shape(11);
		Rectangle rt1 = new Rectangle(6,0);
		Triangle ta1 = new Triangle(6, 5.0);
//利用物件使用方法並給予參數
		sp1.setArea(5);
//		rt1.ComputeArea();
//利用靜態方法印出以上物件
		System.out.println(sp1);
		System.out.println(rt1);
		System.out.println(ta1);
		
		
//      以下為多型示範 ( 結果如同以上 )
		
//		Shape[] shapeArray = new Shape[3];
//		shapeArray[0] = sp1;
//		shapeArray[1] = rt1;
//		shapeArray[2] = ta1;
//		
//		for(int i=0;i<shapeArray.length;i++)
//		{
//			System.out.println(shapeArray[i]);
//		}
	}

}

```

\#字符串格式化字符串函数

<https://ctf-wiki.github.io/ctf-wiki/pwn/linux/fmtstr/fmtstr\\_intro/>

<https://www.google.com/search?q=java+tostring+%E6%A0%BC%E6%98%AF\\&oq=java+tostring+%E6%A0%BC%E6%98%AF\\&aqs=chrome..69i57.9777j0j4\\&sourceid=chrome\\&ie=UTF-8>

## #多型

![](/files/-LfPANmrG-8SNRe4zxDJ)

雇員更上層的父類別?

![](/files/-LfPAT2x8xMgwRJ-wpph)

#### ##擴充性&#xD;

直接間接處理相同父類別的物件

![](/files/-LfPAYvnK5VPXb8LQ62R)

![](/files/-LfPAbwJh62qosVEluPj)

子可以參考父但父不可參考子

子類別物件可以拿去父用

![](/files/-LfPApr3voC74YDJQALR)

但父不可以參考子 除非向下轉型 ( 整數轉換成浮點數

![](/files/-LfPAxvPE7jLAmH2wwHg)

強制型別轉換 向下轉型 父轉子 在塞到子類別物件變數

得到呼叫子類別方法能力

子類別是一種父類別 但父類別不是一種子類別

![](/files/-LfPB3MKkC0dKZL8dHqG)

一個父類別有很多個子類別的話，會呼叫出正確的版本ex

xxxx.toString()

不會呼叫到

Object.toString

### ##接著實作剛剛看到的觀念由以下幾個實例&#xD;

#### ###CommissionEmployee.java&#xD;

```
package polymorphism;

public class CommissionEmployee extends Object{
	
	   private final String firstName;                        
	   private final String lastName;                         
	   private final String idNumber;             
	   private double grossSales; 
	   private double commissionRate; // 佣金，抽庸的比例
	                                
	   public CommissionEmployee(String firstName, String lastName, String idNumber, double grossSales, double commissionRate)
	   {                                                                  
	      super();
		   
		  if (grossSales < 0.0) 
	         throw new IllegalArgumentException("銷售金額必須 >= 0.0");

	      if (commissionRate <= 0.0 || commissionRate >= 1.0)
	         throw new IllegalArgumentException("佣金比例必須 > 0.0 and < 1.0");

	      this.firstName = firstName;                                     
	      this.lastName = lastName;                                    
	      this.idNumber = idNumber;         
	      this.grossSales = grossSales;
	      this.commissionRate = commissionRate;
	   } 

	   public String getFirstName()
	   {
	      return firstName;
	   }

	   public String getLastName()
	   {
	      return lastName;
	   } 

	   public String getIdNumber()
	   {
	      return idNumber;
	   } 

	   public void setGrossSales(double grossSales)
	   {
	      if (grossSales < 0.0) 
	         throw new IllegalArgumentException("銷售金額必須 >= 0.0");

	      this.grossSales = grossSales;
	   } 

	   public double getGrossSales()
	   {
	      return grossSales;
	   } 

	   public void setCommissionRate(double commissionRate)
	   {
	      if (commissionRate <= 0.0 || commissionRate >= 1.0)
	         throw new IllegalArgumentException("佣金比例必須 > 0.0 and < 1.0");

	      this.commissionRate = commissionRate;
	   } 

	   public double getCommissionRate()
	   {
	      return commissionRate;
	   } 
	        
	   public double earnings()              
	   {                                     
	      return getCommissionRate() * getGrossSales();
	   } 

	   @Override
	   public String toString()                                             
	   {                                                                    
	      return String.format("%s: %s %s%n%s: %s%n%s: %.2f%n%s: %.2f %n%s: %.2f" ,    
	         "領佣金的員工姓名", getFirstName(), getLastName(),                    
	         "身分證字號", getIdNumber(),                
	         "每周銷售金額", getGrossSales(),                                     
	         "佣金比例", getCommissionRate(),
	         "總佣金",getCommissionRate() * getGrossSales());                           
	   } 

}

```

#### ###BasePlusCommissionEmployee.java

```
package polymorphism;

public class BasePlusCommissionEmployee extends CommissionEmployee {

	private double baseSalary; // 底薪

	public BasePlusCommissionEmployee(String firstName, String lastName, String idNumber, double grossSales,double commissionRate, double baseSalary) {
		super(firstName, lastName, idNumber, grossSales, commissionRate);

		if (baseSalary < 0.0)
			throw new IllegalArgumentException("底薪金額必須 >= 0.0");

		this.baseSalary = baseSalary;
	}

	public void setBaseSalary(double baseSalary) {
		if (baseSalary < 0.0)
			throw new IllegalArgumentException("底薪金額必須 >= 0.0");

		this.baseSalary = baseSalary;
	}

	public double getBaseSalary() {
		return baseSalary;
	}

	@Override
	public double earnings() {
//		grossSales = -5000.0;
		return getBaseSalary() + (super.getCommissionRate() * super.getGrossSales());
	}

	@Override
	public String toString() {
	      return String.format("%s %n %s: %.2f" ,    
	 	         super.toString(),
	 	         "底薪金額", getBaseSalary());
	}

}

```

#### ###WeekSalaryPlusCommissionEmployee

```
package polymorphism;

public class WeekSalaryPlusCommissionEmployee extends CommissionEmployee {

	private double weekSalary; // 周薪

	public WeekSalaryPlusCommissionEmployee(String firstName, String lastName, String idNumber, double grossSales,double commissionRate, double weekSalary) {
		super(firstName, lastName, idNumber, grossSales, commissionRate);

		if (weekSalary < 0.0)
			throw new IllegalArgumentException("周薪金額必須 >= 0.0");

		this.weekSalary = weekSalary;
	}

	public void setWeekSalary(double weekSalary) {
		if (weekSalary < 0.0)
			throw new IllegalArgumentException("周薪金額必須 >= 0.0");

		this.weekSalary = weekSalary;
	}

	public double getWeekSalary() {
		return weekSalary;
	}

	@Override
	public double earnings() {
		return getWeekSalary() + (super.getCommissionRate() * super.getGrossSales());
	}

	@Override
	public String toString() {
	      return String.format("%s%n %s %n %s: %.2f" , "領周薪加獎金的員工",   
	 	         super.toString(),  "周薪金額", getWeekSalary() );
	}

}

```

#### ###PolymorphismTest.java

```
package polymorphism;

public class PolymorphismTest {

	public static void main(String[] args) {
		// TODO 自動產生的方法 Stub

//		BasePlusCommissionEmployee employee01 = new BasePlusCommissionEmployee("劉", "德華", "A123456789", 10000, .06,1000);
//		CommissionEmployee employee02 = new CommissionEmployee("陳", "立農", "A123456789", 5000, .1);
//		CommissionEmployee employee03 = new CommissionEmployee("周", "子瑜", "A111111111", 6000, .06);
//		BasePlusCommissionEmployee employee04 = new BasePlusCommissionEmployee ("吳", "奕帆", "A222222222", 1000, .08,5000);
//		
//		System.out.printf("%n%s:%n%n%s%n", "第 1 位員工薪資資料", employee01.toString());
//		System.out.printf("%n%s:%n%n%s%n", "第 2 位員工薪資資料", employee02.toString());
//		System.out.printf("%n%s:%n%n%s%n", "第 3 位員工薪資資料", employee03.toString());
//		System.out.printf("%n%s:%n%n%s%n", "第 4 位員工薪資資料", employee04.toString());

		CommissionEmployee employeeArray[] = new CommissionEmployee[5];
		employeeArray[0] = new BasePlusCommissionEmployee("劉", "德華", "A123456789", 10000, .06, 1000);
		employeeArray[1] = new CommissionEmployee("陳", "立農", "A123456789", 5000, .1);
		employeeArray[2] = new CommissionEmployee("周", "子瑜", "A111111111", 6000, .06);
		employeeArray[3] = new BasePlusCommissionEmployee("吳", "奕帆", "A222222222", 1000, .08, 5000);
		employeeArray[4] = new WeekSalaryPlusCommissionEmployee("韓", "國魚", "A333333333", 2000, .05, 500);
		
		for(int i = 0; i < employeeArray.length ;i++)
		{
			System.out.printf("%n%s%d%s:%n%n%s%n", "第 ",i+1," 位員工薪資資料", employeeArray[i].toString());		
		}

	}

}

```

父類別子用與多參數型

就算再設計設備的時候也要考慮未來可能擴充元件與特定控制方法，所以一定要有多型，ex 薪水計算方法現行公司指有兩種，難道未來不會有別種或是更多種?

\#抽象類別 ( 繼承階層的提升?&#x20;( 待補下級待續
--------------

指拿來定義 無法用new配置實體物件

![](/files/-LfPB_J5HqkjTDKhBpU4)

抽象類別的 子類別一定要實作屬於子類別版本的方法

讓子符合父的一定規範

![](/files/-LfPBdIRCO9hWY9D3sTd)

規範架構 擴展的範圍


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://johch3n611u.gitbook.io/c50108/ju-li-cheng-bei/201905/2019-0520.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
