More Related Content
Similar to Object-Oriented Programming Design with Greenfoot 01 (14)
Object-Oriented Programming Design with Greenfoot 01
- 5. 物件導向程式設計的特色
「物件導向程式設計」的設計單位是「物
件」,貼近我們對實體世界的概念理解。
「程序性程式設計 Procedural
Programming 」的設計單位是「程序
Procedures 」:
流程 Flow
函式 Functions
副程式 Subroutines
Pokkunuri, B. P. (1989, November). Object oriented programming. ACM
SIGPLAN Notices, 24(11), 96-101. doi:10.1145/71605.71612
- 27. 步驟二:加上撲克牌疊
import greenfoot.*; // ( World 、 Actor 、 GreenfootImage 、 GreenfootSound 、 Greenfoot 及 MouseInfo )
import java.util.ArrayList;
/**
* 牌桌。
*
* @author 依瑪貓
* @version 2012/6/15
*/
public class Table extends World
{
/** 未翻開的撲克牌疊。 */
public UnflippedPile unflippedPile = null;
/** 已翻開的撲克牌疊。 */
public FlippedPile flippedPile = null;
/** 暫放區的撲克牌疊。 */
public ArrayList<WorkingPile> workingPiles = new ArrayList<WorkingPile>();
/** 歸整區的撲克牌疊。 */
public ArrayList<ResultPile> resultPiles = new ArrayList<ResultPile>();
- 28. 步驟二:加上撲克牌疊(續)
public Table() {
// 建立 600x400 方格的新世界,方格大小為 1x1 像素。
super(600, 400, 1);
unflippedPile = new UnflippedPile(); // 加上未翻開的撲克牌疊。
addObject(unflippedPile, 48, 60);
flippedPile = new FlippedPile(); // 加上已翻開的撲克牌疊。
addObject(flippedPile, 132, 60);
workingPiles = new ArrayList<WorkingPile>(); // 加上暫放區的撲克牌疊。
for (int i = 1; i <= 7; i++) {
WorkingPile pile = new WorkingPile();
workingPiles.add(pile);
addObject(pile, -36 + 84 * i, 168);
}
resultPiles = new ArrayList<ResultPile>(); // 加上歸整區的撲克牌疊。
for (int i = 1; i <= 4; i++) {
ResultPile pile = new ResultPile();
resultPiles.add(pile);
addObject(pile, 216 + i * 84, 60);
}
}
}
- 35. 步驟三:加上撲克牌
import greenfoot.*; // ( World 、 Actor 、 GreenfootImage 、 GreenfootSound 、 Greenfoot 及 MouseInfo )
import java.util.ArrayList;
import java.util.Collections;
……
public Table() {
……
// 加上撲克牌。
ArrayList<Card> cards = new ArrayList<Card>(); // 建立撲克牌
for (Card.Suit suit : Card.Suit.values()) {
for (int value = 1; value <= 13; value++) {
cards.add(new Card(suit, value));
}
}
Collections.shuffle(cards); // 洗牌
for (Card card : cards) { // 放在未翻開的牌疊上
unflippedPile.addCard(card);
}
}
}
- 40. 步驟四:發牌到下面的暫放區
public Table() {
……
// 發牌到暫放區。
for (int i = 1; i <= workingPiles.size(); i++)
{
WorkingPile pile = workingPiles.get(i - 1);
for (int j = 1; j <= i; j++) // 第幾疊,就發幾張牌。
{
Card card = unflippedPile.takeTopCard();
pile.addCard(card);
}
Card card = pile.getTopCard(); // 最後一張牌要翻開。
card.turnFaceUp();
}
}
- 45. 繼承 (Inheritance) 和覆寫
(Override)
子類別 (subclass) 要是沒有覆寫掉父類別
(superclass) 的方法,就會繼承 (inherit)
父類別的方法。
我們原來在 WorkingPile 沒有覆寫
addCard() ,所以會繼承自 Pile 的
addCard() ,新加的牌會放到牌疊的正上方。
- 46. 繼承 (Inheritance) 和覆寫
(Override)
子類別可以覆寫 (override) 父類別的方法。
這樣可以在不改寫呼叫者程式的情況下,
子類別做一些自己特有的調整。
現在我們要在 WorkingPile 覆寫 addCard() ,
來蓋掉父類別 Pile 的 addCard() 方法,把新
加的牌往下面放一點,露出前面的牌。
- 47. 繼承 (Inheritance) 和覆寫
(Override)
覆寫時,子類別 (subclass) 可以呼叫
super ,呼叫父類別 (superclass) 中被覆
寫掉的方法,例如 super.addCard() 。
要呼叫父類別 (superclass) 的父類別
(superclass) 時,則用
super.super.addCard() 。
super() 則是指父類別的建構子。
super(600,400,1) 為 World 的建構子,可查
World 的 API 文件說明。
- 48. 步驟五:覆寫 addCard() 方法
/**
* 暫存區的撲克牌疊。
*/
public class WorkingPile extends Pile
{
/**
* 加一張撲克牌。覆寫(蓋掉)繼承的方法。
*
* @param card 要加上去的撲克牌
*/
public void addCard(Card card)
{
super.addCard(card);
// 把新加上的牌放下面一點,露出前面的牌。
card.setLocation(card.getX(), card.getY() + (getSize() - 1) * 16);
}
}