Transcript 下載/瀏覽
第7章 巢狀類別、多重繼承和套件
7-1 巢狀類別
7-2 多重繼承 – Java的介面
7-3 Java的套件
7-1 巢狀類別
7-1-1 巢狀類別
7-1-2 內層類別的使用
7-1-1 巢狀類別-說明
在Java類別之中可以擁有其它類別的成員,
這種類別稱為「巢狀類別」(Nested
Classes)。
巢狀類別強調類別之間的關係,成員類別
稱為「內層類別」(Inner Classes)。
例如:Employee巢狀類別擁有成員類別
Phone的內層類別,Employee是巢狀類別
的「外層類別」(Enclosing Class)。
7-1-1 巢狀類別-範例
class Employee // Employee外層類別
{
…………
class Phone // Phone內層類別
{
……………
}
…………
}
7-1-1 巢狀類別-特點
巢狀類別強調類別間的關係,例如:員工擁有連
絡電話的資料,所以Phone類別屬於Employee
類別的一部分。
巢狀類別的內層類別也屬於外層類別的成員,所
以其它成員可以存取或呼叫內層類別的成員變數
和方法,就算是宣告成private的都一樣可以存取,
反之內層類別的方法也可以直接存取其它成員變
數和呼叫成員方法。
在Java程式檔案只允許一個宣告成public的類別,
如果巢狀類別宣告成public,內層類別也能夠擁
有public的存取權限。
7-1-1 巢狀類別-圖例
Employee物件的圖例,如下圖所示:
7-1-2 內層類別的使用-說明
巢狀類別的內層類別屬於外層類別的成員
物件,所以不能宣告成static的類別變數和
方法,而且只有外層類別的物件存在時,
內層類別才會存在。
7-1-2 內層類別的使用-範例1
例如:Customer巢狀類別,如下所示:
class Customer // Customer外層類別
{
………
class Address // Address內層類別
{
………
}
7-1-2 內層類別的使用-範例2
在Java程式需要先建立Customer物件,才能建
立Address物件,如下所示:
Customer joe = new Customer("陳會安",
29001234);
Customer.Address home = joe.new Address();
上述程式碼先使用new運算子建立joe參考的
Customer物件,接著使用Customer.Address
宣告物件變數home,然後使用joe.new建立
Address物件,最後指定成員變數值,如下所示:
home.address = "台北縣五股鄉成泰路一段";
home.zip = 248;
7-2 多重繼承 – Java的介面
7-2-1 宣告與使用介面
7-2-2 介面的繼承
7-2-3 實作多個介面
7-2 多重繼承 – Java的介面(圖例)
「多重繼承」(Multiple Inheritance)
是指一個類別能夠繼承多個父類別,如下
圖所示:
7-2 多重繼承 – Java的介面(說明)
類別C繼承類別A和B,類別E繼承類別C和
D,分別擁有2個父類別,一個類別繼承多
個父類別稱為多重繼承。
不過Java並不支援多重繼承(C++語言支
援),但是提供相同目的的多重繼承 「介面」(Interface)。
7-2-1 宣告與使用介面-說明
介面(Interface)是在類別繼承架構中定
義類別行為,內含常數和方法宣告,但是
並沒有實作程式碼,它和抽象類別的差異,
如下所示:
• 抽象類別的方法可能只有宣告,但是仍然可以
擁有一般方法,介面的方法都只有宣告,而且
一定沒有實作的程式碼。
• 介面不屬於類別的繼承架構,就算亳無關係的
類別也一樣可以實作同一個介面。
• 類別只能繼承一個抽象類別,但是可以同時實
作多個介面。
7-2-1 宣告與使用介面-介面的宣告
語法
Java語言的介面和類別都屬於參考資料型態,一
種介面資料型態,介面宣告方法屬於抽象方法,
在實作介面的類別需要實作「所有」的抽象方法,
其宣告的語法,如下所示:
public interface 介面名稱
{
final 資料型態 常數=值;
……….
傳回值型態 介面方法( 參數列 );
……
}
7-2-1 宣告與使用介面-類別實作介
面的語法
類別宣告可以實作一個或多個介面,其宣
告語法,如下所示:
class 類別名稱 implements 介面名稱1, 介面
名稱2
{
// 實作的介面方法
}
上述類別使用implements關鍵字實作介面,
如果實作的介面不只一個,請使用”,”逗號
分隔,在類別宣告內需要實作這些方法。
7-2-1 宣告與使用介面-範例1
例如:AreaInterface介面,如下所示:
interface AreaInterface
{
final double PI = 3.1415926;
void area();
}
7-2-1 宣告與使用介面-範例2
接著Circle類別可以實作這個介面,如下所示:
class Circle extends Shape implements
AreaInterface
{
………
public void area()
{ System.out.println("X座標: " + x);
System.out.println("Y座標: " + y);
System.out.println("圓半徑: " + r);
System.out.println("圓面積: " + PI*r*r);
}
}
7-2-1 宣告與使用介面-UML類別圖
UML類別圖,如下圖所示:
7-2-2 介面的繼承-說明
Java的介面並不允許隨便新增方法,因為
實作介面的類別需要實作所有的介面方法,
如果新增介面方法,換句話說,需要修改
所有實作此介面的類別方法。
不過,如果需要增加介面的抽象方法,我
們可以使用繼承方式來擴充介面。
7-2-2 介面的繼承-宣告
介面繼承的宣告語法,如下所示:
interface 介面名稱 extends 繼承的介面1, 繼
承的介面2
{
…… // 額外的常數和方法
}
上述語言宣告一個新介面繼承其它介面的
所有常數和方法,而且介面支援多重繼承,
各介面是使用","逗號分隔。
7-2-2 介面的繼承-範例
例如:繼承上一節的AreaInterface介面,
如下所示:
interface ShapeInterface extends
AreaInterface
{
void perimeter();
}
上述介面ShapeInterface繼承自
AreaInterface,新增方法perimeter()。
7-2-2 介面的繼承-UML類別圖
UML類別圖,如下圖所示:
7-2-3 實作多個介面-介面宣告
interface ShapeInterface
{
final double PI = 3.1415926;
void area();
void perimeter();
}
interface ShapeInfo
{
void show();
}
7-2-3 實作多個介面-實作介面
現在我們可以宣告Circle類別繼承自Shape抽象
類別,並且實作ShapeInterface和ShapeInfo
兩個介面,如下所示:
class Circle extends Shape implements
ShapeInterface, ShapeInfo
{
………
public void area() { ……… }
public void perimeter() { ……… }
public void show() { ……… }
}
7-3 Java的套件
7-3-1
7-3-2
7-3-3
7-3-4
7-3-5
Java API的套件
類別與介面檔案的管理
package和import指令敘述的使用
protected存取修飾子的使用
Java存取修飾子的使用
7-3 Java的套件
Java語言的「套件」(Package)是一組
相關類別和介面的集合,套件能夠提供存
取保護,如同其它程式語言的「函式庫」
(Library),稱為Java API
(Applications Programming
Interface)。
在這一節筆者準備說明如何建立自己的套
件、在Java程式匯入其它套件和存取修飾
子protected。
7-3-1 Java API的套件
API是一種軟體的工具箱,Java標準API是
一個名為java的大型套件,擁有數個子套
件lang、awt和io等,每個子套件擁有許多
的類別,如下圖所示:
7-3-2 類別與介面檔案的管理-說
明
在本節前的Java程式範例都是將類別和介
面宣告放在同一個程式檔案,如果覺得程
式碼太長,可以將每一個類別和介面都獨
立成副名為.java的檔案,並且將它放置於
同一個資料夾。
例如:將上一節的Java程式範例分割成數
個Java程式檔案,都儲存在「Ch07」資料
夾。
7-3-2 類別與介面檔案的管理-檔
案清單
Java 程式檔案
說明
Shape.java
抽象類別 Shape
ShapeInterface.java
ShapeInterface 介面
Circle.java
繼承 Shape 抽象類別和實作 ShapeInterface 介面的
圓形
Rectangle.java
繼承 Shape 抽象類別和實作 ShapeInterface 介面的
長方形
7-3-2 類別與介面檔案的管理-範例
每個Java程式檔案的類別都是宣告成
public,以便其它類別可以使用,例如:
Shape.java的內容,如下所示:
/* 程式範例: Shape.java */
public abstract class Shape // Shape類別
宣告
{ // 成員資料
public double x; // X座標
public double y; // y座標
}
7-3-3 package和import指令敘述的
使用-建立套件
建立套件:package指令敘述
將類別和介面宣告的檔案建立成套件,我
們需要在每一個欲組成套件的Java程式檔
案前加上package指令敘述,如下所示:
/* 程式範例: Shape.java */
package Ch7_3_3;
public abstract class Shape
{
………
}
7-3-3 package和import指令敘述的
使用-匯入套件
匯入套件:import指令敘述
在建立好套件後,如果其它Java程式需要
使用此套件,就可以使用import指令敘述
匯入套件,如下所示:
import Ch7_3_3.Circle;
import Ch7_3_3.Rectangle;
如果Java程式需要匯入整個Ch7_3_3套件,
可以在import指令敘述後使用”*”符號表
示所有類別,如下所示:
import Ch7_3_3.*;
7-3-4 protected存取修飾子的使用說明
Java語言的存取修飾子protected是指宣
告的成員方法或變數可以在同一類別、其
子類別或同一套件存取,其存取權限介於
public和private之間。
7-3-4 protected存取修飾子的使用範例
例如:在Ch7_3_4套件的Point類別宣告
座標的成員變數x和y,其存取修飾子為
protected,如下所示:
protected double x;
protected double y;
此時,在同一個套件繼承Point類別的Line
類別可以存取x和y,單純匯入此套件的類
別並無法存取x和y。不屬於同一套件,繼
承Point類別的子類別ColorPoint,仍然可
以存取x和y。
7-3-5 Java存取修飾子的使用-存取
範圍
Java語言的存取修飾子public、private和
protected擁有不同的存取權限範圍,筆者整理
如下所示:
• public:擁有全域範圍,任何類別都可以存取,包含
子類別。
• private:只可以在同一個類別存取,不可以在子類
別存取。
• protected:可以在同一個類別、其子類別或同一套
件中存取。
• 沒有使用修飾子:預設範圍是同一個類別和套件中存
取,但不包含不同套件的子類別,protected包含不同
套件的子類別,所以其存取範圍比protected小。
7-3-5 Java存取修飾子的使用-使用
地方
存取修飾子在Java程式可以使用的地方,
筆者整理如下表所示:
修飾子
public
private
protected
abstract
final
類別
可
可(巢狀)
可(巢狀)
可
可
成員變數
可
可
可
否
可
成員方法
可
可
可
可
可
建構子
可
可
可
否
否