Chapter 13 翻譯 (Abstact Classes and Interfaces)

13.1 Introduction p1492

父類定義相關子類的共同行爲。接口可以用來多個類的共同行爲(包括不相關類)。

你可以使用 java.util.Arrays.sort 方法去排序一個數字數組或者字符數組。你可以依然用 sort 方法去排序一個幾何數組?爲了寫出這樣的代碼,你必須知道接口。一個接口定義類的行共同爲。在討論接口前,我們引入一個相關主題:抽象類。

13.2 Abstract classes

一個抽象類不能去創建對象。一個抽象類可以包含抽象方法,抽象方法會實現於實子類 concrete subclasses

inheritance hierarchy 繼承體系 中,隨着新類的出現,類變得越來越具體,並且變得越來越實。如果你從子類返到父類,類會越來越通用越來越不具體。類的設計應該確保父類包含子類的共同功能。有時候,一個父類係好抽象,抽象到不可以建立具體實例。噉嘅類 被人叫作 is referred to as 抽象類 abstract class

在 charpter 11 里,GeometricObject 定義成一個父類,CircleRectangle 的父類。GeometricObject 方法將幾何對象的共同特徵造成模型(model 將...做成模型)。兩者 CircleRecangle 包含咗 getArea()getPerimeter() 方法來計算圓同方型嘅面積和 週長 perimeter

因爲你可以計算所有幾何圖形的面積同週長,最好定義 getArea()getPerimeter() 方法在幾何對象類之中。但是這些方法不能被實現在幾何對象類中,因爲這些實現要基於特定的幾何對象類型。這樣的方法被稱作抽象類,並且用 abstract 修改器表示。當你定義了多個抽象方法於 GeometricObject 後,個類變成抽象類。

抽象類用 abstract 修改器標識。在 UML 圖上,抽象類同抽象方法的名字都會是斜體。

GeometricObject
|__ getArea(): double

GeometricObject.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
public abstract class GeometricObject {
private String color = "white";
private boolean filled;
private java.util.Date dateCreated;

/** Construct a default geometric object */
protected GeometricObject() {
dateCreated = new java.util.Date();
}

/** Construct a geometric object with color and filled value */
protected GeometricObject(String color, boolean filled) {
dateCreated = new java.util.Date();
this.color = color;
this.filled = filled;
}

/** Return color */
public String getColor() {
return color;
}

/** Set a new color */
public void setColor(String color) {
this.color = color;
}

/** Return filled. Since filled is boolean,
* the get method is named isFilled */
public boolean isFilled() {
return filled;
}

/** Set a new filled */
public void setFilled(boolean filled) {
this.filled = filled;
}

/** Get dateCreated */
public java.util.Date getDateCreated() {
return dateCreated;
}

@Override
public String toString() {
return "created on " + dateCreated +
"\ncolor: " + color +
" and filled: " + filled;
}

/** Abstract method getArea */
public abstract double getArea();

/** Abstract method getPerimeter */
public abstract double getPerimeter();
}

抽象類就好似普通的類,但係不可以用 new 來創建抽象類的實例。一個抽象方法只有定義,沒有實現。實現是它的子類的事情。一個類包含抽象方法,就必須定義成抽象類啦!

abstract class 的構建器被定義成 protected ,因爲只會它的子類會使用它。當你創建一個實子類的實例,是包含了它的父類構造器。

GeometricObject 抽象類定義了幾何對象的共同功能,並且提供了適當的構造器。因爲你不知道如何去計算幾何對象的面積和週長,所以 getArea()getPerimeter() 定義成抽象。這些方法會在它的子類實現。 CircleRectangle 的實現都一樣,除了他們延伸 GeometricObject 類不一樣。

Circle.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class Circle extends GeometricObject {
private double radius;

public Circle() {
}

public Circle(double radius) {
this.radius = radius;
}

/** Return radius */
public double getRadius() {
return radius;
}

/** Set a new radius */
public void setRadius(double radius) {
this.radius = radius;
}

@Override /** Return area */
public double getArea() {
return radius * radius * Math.PI;
}

/** Return diameter */
public double getDiameter() {
return 2 * radius;
}

@Override /** Return perimeter */
public double getPerimeter() {
return 2 * radius * Math.PI;
}

/* Print the circle info */
public void printCircle() {
System.out.println("The circle is created " + getDateCreated() +
" and the radius is " + radius);
}
}

Rectangle.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class Rectangle extends GeometricObject {
private double width;
private double height;

public Rectangle() {
}

public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}

/** Return width */
public double getWidth() {
return width;
}

/** Set a new width */
public void setWidth(double width) {
this.width = width;
}

/** Return height */
public double getHeight() {
return height;
}

/** Set a new height */
public void setHeight(double height) {
this.height = height;
}

@Override /** Return area */
public double getArea() {
return width * height;
}

@Override /** Return perimeter */
public double getPerimeter() {
return 2 * (width + height);
}
}

13.2.1 Why Abstract Methods?

你可以奇怪有什麼好處,在 GeometricObject 類裡去定義 getArea()getPerimeter() 抽象方法。下面的例子顯示了定義 GeometricObject 類的好處,包括 equalArea方法檢查是否兩者面積相等,包括 displayGeometricObject 方法去顯示它們。

TestGeometricObject.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

public class TestGeometricObject {
/** Main method */
public static void main(String[] args) {
// Declare and initialize two geometric objects
GeometricObject geoObject1 = new Circle(5);
GeometricObject geoObject2 = new Rectangle(5, 3);

System.out.println("The two objects have the same area? " +
equalArea(geoObject1, geoObject2));

// Display circle
displayGeometricObject(geoObject1);

// Display rectangle
displayGeometricObject(geoObject2);
}

/** A method for comparing the areas of two geometric objects */
public static boolean equalArea(GeometricObject object1,
GeometricObject object2) {
return object1.getArea() == object2.getArea();
}

/** A method for displaying a geometric object */
public static void displayGeometricObject(GeometricObject object) {
System.out.println();
System.out.println("The area is " + object.getArea());
System.out.println("The perimeter is " + object.getPerimeter());
}
}

方法 getArea()getPerimeter() 定義在 GeometricOjbect 類度,這些方法會被 CircleRectangle 類所覆蓋。下面 statement表達式:

1
2
GeometricObject geoObject1 = new Circle(5);
GeometricObject geoObject2 = new Rectangle(5, 3);

創建一個新的圓形同新的長方形,之後 指向到 assign to 變量 geoObject1geoObject2。這兩個變量都是 GeometricObject 類。

調用invoke equalArea(geoObject1, geoObject2)getArea() 方法定義在 Recrangle 類中,個類係用於 object2.Area() 裡,因爲 goeObject2 係一個長方形。`

同樣,當提及 displayGeometricObject(geoObject1)CirclegetArea()getPerimeter 就會被使用。 displayGeometricObject(geoObject2) 就係 Rectangle 相應的類。JVM 動態地決定哪一個方法被調用,具體係基於真實的對象調用了變一個方法。

Note 注意,如果 getArea 方法沒有被定義在 GeometricObject 類,你就不能定義比較兩個幾何對象是否有相同的面積的 equalArea 方法。你已經見到定義個抽象方法係“共同”類的好處。

13.2.2 Interesting Points about Abstract classes

如下幾點關於抽象類 is worth noting 是值得注意的

  • 抽象方法不能包含在非抽象類度。如果一個子類屬於抽象父類,未能實現所有的抽象方法,那麼子類必須成抽象。換句話說,在一個非抽象子類,個類延伸於抽象父類,所有的抽象方法必須被實現。也要注意抽象方法不能係靜態
  • 使用 new 操作符不能初始化一個抽象類,但係你仍然可以定義佢嘅構造器,某某被調用在子類的構造器上。例如,GeometricObject 的構造器會被調用在 CircleRectangle 類裡面。
  • 一個類包含抽象方法,一定要係抽象。但係可以定義一個抽象類不包含任何抽象方法。 這個抽象類可以作爲定義後面子類的基礎類。
  • 一個子類可以覆蓋來自父類類的方法,子類定義個方法成抽象。這樣是非常不正常,但是當實現父類的方法成爲無效,就幾有用。這種情況,子類必須定義成抽象。—— 實體方法被覆蓋成抽象
  • 一個子類可以是抽象,even if 即使 父類是真實方法。例如,object 類是實體方法,但是它的子類 GeometricObject 是抽象。
  • 你不能使用 new 操作符從抽象類創建一個實例,但是一個抽象類可以作爲一個抽象類。因此,如下的語句,創建一個數組,數組的元素是 GeometricObject 類。
    1
    GeometricObject[] objects = new GeometricObject[10];
  • 你可以創建一個實例, GeometricObject 的實例 (Circle),並且 assign a to b 將a配給b 將 Circle 的引配到數組上。
    1
    object[0] = new Circle();

13.2 Check Point p1506

1.

13.3 Case Study: the Abstract Number Class

詞彙

  • geometric 幾何的
  • subject 話題

概念

  • 一個 superclass(超類) 定義相關 subclasses(子類) 的共同行爲
  • 一個 interface(接口) 定義多個類的共同行爲(包括不相關的類)

13.2 Abstract Classes 1493

  • abstract class (抽象類) 不能用去創建對象
  • abstract class 可以包括 abstract method (抽象方法)
  • abstract method (抽象方法) 會被 concrte(真實的) 子類所實現
  • perimeter 週長
  • are referred to as
  • denote
  • modifier
  • appropriate

    13.2.2

  • is worth noting 是值得注意的

Hexo使用

配置

啓用附件Asset(圖片etc)

  • 啓用:_config.yml文件 set post_asset_folder:true
  • 使用:放圖片入同 md 文件同名文件夾入邊,md 寫
    1
    {% asset_img tu.jpg This_is_tu %}

9月周計劃

Short Term

Mon-Thu

1
2
3
4
5
6
7
8
9
10
11
1am ~ 8am    sleep
8am ~ 9.30am GoToTKH
9am ~ 10am StudySQL
1pm ~ 2pm StudySQL
7pm ~ 8pm backHome listen what I practice
8pm ~ 9pm Ex
9pm ~ 10pm GT
10pm ~ 12pm Java
0am ~ 1am Summary

CS 8+2=10

SAT/SUN

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1am ~ 8am    sleep
8am ~ 9am eat
9am ~ 0pm Java
<>
1pm ~ 2pm GT
2pm ~ 3pm Ex(GT)
3pm ~ 5pm Java
5pm - 6pm Summary
<>
7pm ~ 8pm Guitar
8pm ~ 9pm Ex(GT)
9pm ~ 12pm Java
0am ~ 1am Summary

SAT/SUN
CS 3+2=5
CS 3+2+5=10