一旦掌握了各種形狀都有的共通方法,就可以定義形狀類別本身了。就必須實作的方法數目而言,最簡單的形狀是 Circle 類別,如下所示:
package com.example.programmingas3.geometricshapes
{
public class Circle implements IGeometricShape
{
public var diameter:Number;
public function Circle(diam:Number = 100):void
{
this.diameter = diam;
}
public function getArea():Number
{
// The formula is Pi * radius * radius.
var radius:Number = diameter / 2;
return Math.PI * radius * radius;
}
public function getCircumference():Number
{
// The formula is Pi * diameter.
return Math.PI * diameter;
}
public function describe():String
{
var desc:String = "This shape is a Circle.\n";
desc += "Its diameter is " + diameter + " pixels.\n";
desc += "Its area is " + getArea() + ".\n";
desc += "Its circumference is " + getCircumference() + ".\n";
return desc;
}
}
}
Circle 類別會實作 IGeometricShape 介面,因此它必須同時為
getArea()
方法和
describe()
方法提供程式碼。此外,它也定義
getCircumference()
方法,這是 Circle 類別特有的方法;Circle 類別也宣告屬性
diameter
,也是其它多邊形類別中不會有的屬性。
另外兩種形狀 - 方形和等邊三角形,卻另外有一些共通特性:它們都各有等長的邊,而且兩者都有共通的公式可用來計算周長和內角總和。事實上,這些共通的公式也適用於以後您會定義的任何其它正多邊形。
RegularPolygon 類別同時是 Square 類別和 EquilateralTriangle 類別的父類別。父類別可以讓您在一處定義共通的方法,而不必分別在各個子類別中定義。下面是 RegularPolygon 類別的程式碼:
package com.example.programmingas3.geometricshapes
{
public class RegularPolygon implements IPolygon
{
public var numSides:int;
public var sideLength:Number;
public function RegularPolygon(len:Number = 100, sides:int = 3):void
{
this.sideLength = len;
this.numSides = sides;
}
public function getArea():Number
{
// This method should be overridden in subclasses.
return 0;
}
public function getPerimeter():Number
{
return sideLength * numSides;
}
public function getSumOfAngles():Number
{
if (numSides >= 3)
{
return ((numSides - 2) * 180);
}
else
{
return 0;
}
}
public function describe():String
{
var desc:String = "Each side is " + sideLength + " pixels long.\n";
desc += "Its area is " + getArea() + " pixels square.\n";
desc += "Its perimeter is " + getPerimeter() + " pixels long.\n";
desc += "The sum of all interior angles in this shape is " + getSumOfAngles() + " degrees.\n";
return desc;
}
}
}
首先,RegularPolygon 類別宣告所有正多邊形都有的兩個屬性:各邊的長度 (
sideLength
屬性) 和邊的數目 (
numSides
屬性)。
RegularPolygon 類別實作 IPolygon 介面,然後將 IPolygon 介面的四個方法都一起宣告。它使用共通的公式,實作其中兩個方法:
getPerimeter()
和
getSumOfAngles()
方法。
由於
getArea()
方法的公式,每一種形狀都不同,因此方法的基底類別版本不能包括子類別方法可繼承的共通邏輯。而只是傳回 0 預設值,指出並未計算面積。若要正確計算各圖形的面積,RegularPolygon 類別的子類別便需要覆寫
getArea()
方法本身。
下列 EquilateralTriangle 類別的程式碼示範
getArea()
方法是如何覆寫的:
package com.example.programmingas3.geometricshapes
{
public class EquilateralTriangle extends RegularPolygon
{
public function EquilateralTriangle(len:Number = 100):void
{
super(len, 3);
}
public override function getArea():Number
{
// The formula is ((sideLength squared) * (square root of 3)) / 4.
return ( (this.sideLength * this.sideLength) * Math.sqrt(3) ) / 4;
}
public override function describe():String
{
/* starts with the name of the shape, then delegates the rest
of the description work to the RegularPolygon superclass */
var desc:String = "This shape is an equilateral Triangle.\n";
desc += super.describe();
return desc;
}
}
}
override
關鍵字指出
EquilateralTriangle.getArea()
方法會刻意從 RegularPolygon 父類別覆寫
getArea()
方法。呼叫
EquilateralTriangle.getArea()
方法時,它會使用上一個程式碼中的公式計算面積,而
RegularPolygon.getArea()
方法中的程式碼則永遠不會執行。
對照之下,EquilateralTriangle 類別不會定義其本身版本的
getPerimeter()
方法。呼叫
EquilateralTriangle.getPerimeter()
方法時,呼叫會順著繼承鏈往上,並執行 RegularPolygon 父類別之
getPerimeter()
方法中的程式碼。
EquilateralTriangle()
建構函式則會使用
super()
陳述式,以明確叫用其父類別的
RegularPolygon()
建構函式。若兩個建構函式都有相同的一組參數,您可以完全省略
EquilateralTriangle()
建構函式,而改為執行
RegularPolygon()
建構函式。但是
RegularPolygon()
建構函式需要額外的參數
numSides
。因此
EquilateralTriangle()
建構函式呼叫
super(len, )
,跟
len
輸入參數和值 3 一起傳遞,指出三角形會有 3 個邊。
describe()
方法也使用
super()
敘述式,不過方式不同。這種方式會使用這個敘述句來呼叫
describe()
方法的 RegularPolygon 父類別版本。
EquilateralTriangle.describe()
方法先將
desc
字串變數設定至有關形狀類型的陳述式。然後,它會呼叫
super.describe()
,以取得
RegularPolygon.describe()
方法的結果,而且將該結果附加至
desc
字串。
這裡不會詳細描述 Square 類別,但它與 EquilateralTriangle 類別類似,可提供建構函式及其本身
getArea()
和
describe()
方法的實作。