# 範例：抽象類別

抽象類別如同父類別一般，透過本篇了解 抽象類別的用法 及 抽象類別與父類別的不同處。

一個簡單的整理：

* 抽象類別 不能直接建立物件
* 抽象函數 不定義其處理方式

有了前一篇的基本概念後，再透過以下更加完整的實例來了解 abstract 的用法：

```
abstract class CShape               // 定義抽象類別 CShape
{
   protected String color;
   public void setColor(String str)    // 一般的函數
   {
      color=str;
   }
   public abstract void show(); // 只定義函數名稱的 抽象函數
}

class CRectangle extends CShape    // 子類別 矩形 CRectangle
{
   protected int width,height;
   public CRectangle(int w,int h)  //建構元
   {
      width=w;
      height=h;
   }
   public void show()      // 定義繼承而來的抽象函數 show() 的處理方式
   {
      System.out.print("color="+color+",  ");
      System.out.println("area="+width*height);
   }
}
class CCircle extends CShape     // 子類別 圓形CCircle
{
   protected double radius;
   public CCircle(double r)   //建構元
   {
      radius=r;
   }
   public void show()      // 定義繼承而來的抽象函數 show() 的處理方式
   {
      System.out.print("color="+color+",  ");
      System.out.println("area="+3.14*radius*radius);
   }
}
public class abstract_01
{
   public static void main(String args[])
   {
      CRectangle rect=new CRectangle(5,10);  //透過子類別建立物件
      rect.setColor("Yellow");   // 呼叫父類別函數 setColor()
      rect.show();         // 呼叫子類別函數 show() method

      CCircle cir=new CCircle(2.0);
      cir.setColor("Green");     // 呼叫父類別函數 setColor()
      cir.show();         // 呼叫子類別函數 show()
   }
}
```

在每個幾何圖形的類別，設計用來顯示顏色與面積的函數；\
但因為每種形狀的面積計算公式不同，因此在父類別也無法很恰當的將處理方式描述出。

```
public abstract void show(); // 只定義函數名稱的 抽象函數
```

因為每種幾何圖形 都會繼承來自父類別的函數，所以我們直接在父類別定義名稱後，\
直接將處理方式分別寫在子類別繼承的函數中即可。

```
矩形：
public void show()      // 定義繼承而來的抽象函數 show() 的處理方式
   {
      System.out.print("color="+color+",  ");
      System.out.println("area="+width*height);
   }
```

```
圓形：
public void show()      // 定義繼承而來的抽象函數 show() 的處理方式
   {
      System.out.print("color="+color+",  ");
      System.out.println("area="+3.14*radius*radius);
   }
```

再來注意到 main() 中，前面提到 抽象類別不能建立物件，因此透過子類別來建立：

```
CRectangle rect=new CRectangle(5,10);
CCircle cir=new CCircle(2.0);
```

再使用建立的物件 呼叫父類別一般函數 setColor() 設定顏色：

```
rect.setColor("Yellow");
cir.setColor("Green");
```

最後是呼叫子類別中改寫後的函數 show() 用來印出顏色以及面積：

```
rect.show();
cir.show();
```

程式執行結果：\
color=Yellow, area=50\
color=Green, area=12.56

## 整理

* 抽象類別 可定義「一般函數」與「抽象函數」
* 抽象類別 不能用來建立物件
* 抽象函數 不定義其處理方式
* 子類別繼承而來的抽象函數 與改寫overriding 技術相同
* 針對子類別會使用到的條件，可以在父類別中定義抽象函數來使用

## 注意

抽象函數 只能宣告為 公有public 或 保護protected，\
因為子類別必須取用，所以不能宣告成 私有private！


---

# 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://java.4-x.tw/java-12/java-12-2.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.
