När du vet metoderna för varje formtyp kan du definiera själva formklasserna. När det gäller hur många metoder du måste implementera är klassen Circle den enklaste formen och den visas här:
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;
}
}
}
Med klassen Circle implementeras gränssnittet IGeometricShape och den måste tillhandahålla kod för både metoden
getArea()
och för
describe()
. Den definierar dessutom metoden
getCircumference()
som är unik för klassen Circle. Klassen Circle deklarerar också egenskapen
diameter
som inte finns i andra polygonklasser.
De andra två formtyperna, fyrkanter och liksidiga trianglar, har andra saker gemensamt: de har sidor som är lika långa och det finns gemensamma formler du kan använda för att beräkna perimetern och summan av bådas inre vinklar. Dessa gemensamma formler gäller också för alla andra vanliga polygoner som du definierar i framtiden.
Klassen RegularPolygon är superklassen för både klassen Square och klassen EquilateralTriangle. Med en superklass kan du definiera gemensamma metoder på ett enda ställe, och du behöver alltså inte definiera dem separat i varje underklass. Här är koden för klassen 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;
}
}
}
Klassen RegularPolygon deklarerar två egenskaper som är gemensamma för alla vanliga polygoner: längden på varje sida (egenskapen
sideLength
) och antalet sidor (egenskapen
numSides
).
Klassen RegularPolygon implementerar gränssnittet IPolygon och deklarerar alla fyra IPolygon-gränssnittsmetoderna. Klassen implementerar två av dessa, metoderna
getPerimeter()
och
getSumOfAngles()
, med hjälp av vanliga formler.
Eftersom formeln för metoden
getArea()
skiljer sig från form till form, kan basklassversionen av metoden inte innehålla normalt logiskt beteende som kan ärvas av underklassmetoderna. I stället returneras standardvärdet 0 vilket anger att arean inte beräknats. Om arean för varje form ska beräknas på rätt sätt måste underklasserna för klassen RegularPolygon åsidosätta metoden
getArea()
.
I följande kod för klassen EquilateralTriangle visas hur metoden
getArea()
åsidosätts:
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;
}
}
}
Nyckelordet
override
anger att metoden
EquilateralTriangle.getArea()
avsiktligt åsidosätter metoden
getArea()
från superklassen RegularPolygon. När metoden
EquilateralTriangle.getArea()
anropas beräknas arean med hjälp av formeln i föregående kod, och koden i metoden
RegularPolygon.getArea()
körs aldrig.
Klassen EquilateralTriangle definierar däremot inte sin egen version av metoden
getPerimeter()
. När metoden
EquilateralTriangle.getPerimeter()
anropas, går anropet uppåt i arvskedjan och koden körs i metoden
getPerimeter()
för superklassen RegularPolygon.
Konstruktorn
EquilateralTriangle()
använder programsatsen
super()
för att starta konstruktorn
RegularPolygon()
för sin superklass. Om båda konstruktorerna har samma uppsättning parametrar kunde du ha uteslutit konstruktorn
EquilateralTriangle()
helt och hållet och konstruktorn
RegularPolygon()
kunde ha körts i stället. Konstruktorn
RegularPolygon()
måste ha en extra parameter,
numSides
. Konstruktorn
EquilateralTriangle()
anropar
super(len, 3)
som skickar indataparametern
len
och värdet 3 för att ange att triangeln har 3 sidor.
Metoden
describe()
använder också programsatsen
super()
, men på ett annat sätt. Den används där för att anropa superklassen RegularPolygons version av
describe()
-metoden. Metoden
EquilateralTriangle.describe()
anger först strängvariabeln
desc
till en programsats om typen av form. Därefter får den resultatet av metoden
RegularPolygon.describe()
genom att anropa
super.describe()
, och resultatet läggs till i strängen
desc
.
Klassen Square beskrivs inte här, men den liknar klassen EquilateralTriangle, som tillhandahåller en konstruktor och egna implementeringar av metoderna
getArea()
och
describe()
.