Una volta a conoscenza dei metodi comuni a ogni tipo di figura, potete passare alla definizione delle classi delle figure geometriche. In termini di quantità di metodi che è necessario implementare, la figura geometrica più semplice corrisponde alla classe Circle visualizzata di seguito:
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;
}
}
}
La classe Circle implementa l'interfaccia IGeometricShape, di conseguenza essa deve fornire codice sia per il metodo
getArea()
che per il metodo
describe()
. Inoltre, essa definisce il metodo
getCircumference()
, univoco per la classe Circle. Nella classe Circle viene infine dichiarata una proprietà,
diameter
, che non si trova nelle altre classi dei poligoni.
Gli altri due tipi di due figure geometriche, quadrato e triangolo equilatero, presentano altre somiglianze: entrambe hanno lati di pari lunghezza e vi sono formule comuni utilizzabili per calcolarne il perimetro e la somma degli angoli interni. In realtà, tali formule comuni sono applicabili a qualsiasi altro poligono regolare definito in futuro.
La classe RegularPolygon è la superclasse sia della classe Square che della classe EquilateralTriangle. Una superclasse consente di definire metodi comuni in una sola posizione, quindi non sarà necessario definirli separatamente in ogni sottoclasse. Segue il codice per la classe 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;
}
}
}
In primo luogo, la classe RegularPolygon dichiara due proprietà comuni a tutti i poligoni
regolari: la lunghezza di ciascun lato (proprietà
sideLength
) e il numero di lati (proprietà
numSides
).
La classe RegularPolygon implementa l'interfaccia IPolygon e dichiara tutti e quattro i metodi dell'interfaccia IPolygon. Essa implementa inoltre due di essi (i metodi
getPerimeter()
e
getSumOfAngles()
) utilizzando formule comuni.
Poiché la formula del metodo
getArea()
è diversa in base al tipo di figura geometrica, la versione della classe base del metodo non può includere logica comune ereditabile dai metodi delle sottoclassi. Al contrario, restituisce semplicemente un valore 0 predefinito a indicare che l'area non è stata calcolata. Per calcolare correttamente l'area di ogni figura geometrica, le sottoclassi della classe RegularPolygon devono sostituire il metodo
getArea()
.
Il codice seguente della classe EquilateralTriangle mostra come è possibile sostituire il metodo
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;
}
}
}
La parola chiave
override
indica che il metodo
EquilateralTriangle.getArea()
sostituisce intenzionalmente il metodo
getArea()
dalla superclasse RegularPolygon. Quando viene chiamato, il metodo
EquilateralTriangle.getArea()
calcola l'area utilizzando la formula del codice precedente, mentre il codice del metodo
RegularPolygon.getArea()
non viene mai eseguito.
Al contrario, la classe EquilateralTriangle non definisce una propria versione del metodo
getPerimeter()
. Quando il metodo
EquilateralTriangle.getPerimeter()
viene chiamato, la chiamata risale la catena di ereditarietà e viene eseguito il codice del metodo
getPerimeter()
della superclasse RegularPolygon.
La funzione di costruzione
EquilateralTriangle()
impiega l'istruzione
super()
per chiamare esplicitamente la funzione di costruzione
RegularPolygon()
della sua superclasse. Se entrambe le funzioni di costruzione presentano la stessa serie di parametri, anche se la funzione
EquilateralTriangle()
venisse omessa, la funzione di costruzione
RegularPolygon()
verrebbe eseguita al suo posto. Tuttavia, la funzione di costruzione
RegularPolygon()
richiede un parametro aggiuntivo,
numSides
. Quindi, la funzione di costruzione
EquilateralTriangle()
chiama
super(len, 3)
, che trasmette il parametro di input
len
e il valore 3 per indicare che il triangolo ha tre lati.
Anche il metodo
describe()
utilizza l'istruzione
super()
, ma in una maniera differente, cioè per chiamare la versione della superclasse RegularPolygon del metodo
describe()
. Il metodo
EquilateralTriangle.describe()
imposta in primo luogo la variabile di stringa
desc
in modo che indichi un'istruzione relativa al tipo di figura. Quindi, ottiene il risultato del metodo
RegularPolygon.describe()
chiamando
super.describe()
e aggiunge tale risultato alla stringa
desc
.
La classe Square non viene descritta dettagliatamente in questa sezione, tuttavia essa è simile alla classe EquilateralTriangle, in quanto fornisce una funzione di costruzione e modalità proprie di implementazione dei metodi
getArea()
e
describe()
.