Klaso (programifo)
En objekt-orientizita programifo, klaso deklaras propraji komuna a ensemblo di objekti. La klaso deklaras atributi reprezentanta la stando dil objekti e dil metodi reprezentanta lia konduto.
Do, klaso reprezentas kategorio di objekti. Lu aparas anke kom "modelo" o "fabrikerio" de qua es posibla krear objekti (lu es un-maniere "instrumentaro" qua permisas fabrikar objekto). On parolas do pri objekto kom instanco (instance) di klaso (kreo di objekto havanta la propraji dil klaso).
Es posibla restriktar la ensemblo di objekti reprezentata da klaso A pro mekanismo di heredo. En ica kazo, on kreas nova klaso B ligata al klaso A e qua adjuntas nova propraji. En ica kazo, diversa termini uzesas:
- A es generaliguro di B e B es specaliguro di A;
- A es superklaso di B e B es subklaso di A;
- A es la matrala klaso di B e B es filiala klaso di A.
Exempli di klaso
redaktarEn la exempli infre es definata en diversa lingui klaso Point
kun du atributi x
e y
. Ica klaso kontenas un konstrukto-metodo (constructor), du metodi retrodonanta la valoro dil atributi (getX()
e getY()
), un metodo determinanta se la punto reprezentas l'origino (isOrigin()
) e un metodo efektiganta translaco.
class Point
{
private:
int x;
int y;
public:
Point(int x, int y) : x(x), y(y) {}
int getX() const { return x; }
int getY() const { return y; }
bool isOrigin() const { return x == 0 && y == 0; }
Point translate(const Point& point) const
{
return Point(x + point.getX(), y + point.getY());
}
};
class Point
{
public Point(int x, int y)
{
X = x;
Y = y;
}
public int Y { get; private set; }
public int X { get; private set; }
public bool IsOrigin()
{
return X == 0 && Y == 0;
}
public Point Translate(Point p)
{
return new Point(X + p.X, Y + p.Y);
}
}
public class Point
{
private int x;
private int y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public boolean isOrigin()
{
return (x == 0) && (y == 0);
}
public Point translate(Point pt)
{
return new Point(x + pt.getX(), y + pt.getY());
}
}
unit Point;
interface
type
TPoint = class
protected
fX, fY: integer;
function GetY : integer;
public
property X : integer read fX; //Kun implicita aceso-metodo
property Y : integer read GetY; //Sen implicita aceso-metodo
constructor Create(X, Y: integer); overload;
constructor Create; overload;
function IsOrigin: Boolean;
function Translate(Pt: TPoint): TPoint;
end;
implementation
function TPoint.GetY: integer;
begin
Result := fY;
end;
constructor TPoint.Create(X, Y: integer);
begin
fX := X;
fY := Y;
end;
constructor TPoint.Create;
begin
Create(0,0);
end;
function TPoint.IsOrigin: Boolean;
begin
Result := (fX = 0) and (fY = 0);
end;
function TPoint.Translate(Pt: TPoint): TPoint;
begin
Result := TPoint.Create(fX + Pt.X, fY + Pt.Y);
end;
end.
class Point {
private $x;
private $y;
public function __construct($x, $y) {
$this->x = (int) $x;
$this->y = (int) $y;
}
public function getX() { return $this->x; }
public function getY() { return $this->y; }
public function isOrigin() { return ($this->x == 0) && ($this->y == 0); }
public function translate(Point $point) {
return new Point($this->x + $point->getX(), $this->y + $point->getY());
}
}
class Point
attr_reader :x, :y
def initialize(x, y)
@x = x.to_i
@y = y.to_i
end
def origin?
@x.zero? and @y.zero?
end
def translate p
Point.new(@x + p.x, @y + p.y)
end
end
class Point(object):
def __init__(self, x, y):
super(Point, self).__init__()
self._x = x
self._y = y
@property
def x(self):
return self._x
@property
def y(self):
return self._y
def is_origin(self):
return (self._x == 0) and (self._y == 0)
def __add__(self, point):
return Point(self._x + point.x, self._y + point.y)
Public class Point
Protected intX As Integer, intY As Integer
Public Sub New(ByVal pX As Integer, ByVal pY As Integer)
Me.intX = pX
Me.intY = pY
End Sub
Public ReadOnly Property X() As Integer
Get
Return Me.intX
End Get
End Property
Public ReadOnly Property Y() As Integer
Get
Return Me.intY
End Get
End Property
Public Function IsOrigine() As Boolean
Return ((Me.intX = 0) And (Me.intY = 0))
End Function
Public Function Translate(ByVal pP As Point) As Point
Return New Point(Me.intX + pP.x, Me.intY + pP.y)
End Function
package Point_Pack is
-- klaso en Ada es tipo nomita "etiketizata"
-- hike on decidas pluse celar la contenajo dil tipo (privata parto)
type Point is tagged private;
-- la metodi deklaresas exter la tipo
function Get_X (P : Point) return Integer;
function Get_Y (P : Point) return Integer;
function Is_Origin (P : Point) return Boolean;
function Translate (P, Vector : Point) return Point;
-- nula konstrukto-metodo "integrigita"
function New_Point (X, Y : Integer) return Point;
private
-- defini neacesebla al uzanto dil tipo
type Point is tagged record
X, Y : Integer;
end record;
end Point_Pack;
-- la serio kontenas la implementaciono dil klaso: en Ada es importanta separar
-- la kodexo (la korpo) e la deklari "videbla" (la specigo): generale en 2 diversa faili
package body Point_Pack is
-- la metodi nomas explicite l'objekto en argumento
function Get_X (P : Point) return Integer is
begin
return P.X;
end Get_X;
function Get_Y (P : Point) return Integer is
begin
return P.Y;
end Get_Y;
function Is_Origin (P : Point) return Boolean is
begin
return P.X = 0 and then P.Y = 0;
end Is_Origin;
function Translate (P, Vector : Point) return Point is
begin
return Point'( X => P.X + Vector.X, Y => P.Y + Vector.Y );
end Translate;
function New_Point (X, Y : Integer) return Point is
begin
return Point'(X => X, Y => Y);
end New_Point;
end Point_Pack;
Partikulara kazi di klaso
redaktarNechanjebla klaso
redaktarKlaso nomesas nechanjebla se ne es posibla modifikar objekto di ica klaso pos lua kreo. Exemple, la klaso Point, deskriptita supre en diversa lingui, es nechanjebla pro ke lu expozas nula metodo permisanta di modifikar la valoro di lua membro-variebli. La metodo translate
retrodonas un nova objekto vice modifikar l'objekto ipsa. La klaso java.lang.String
dil cirkumaji Java es altra exemplo di klaso nechanjebla, e anke la klaso System.String
dil framework Microsoft .NET.
Abstraktala klaso
redaktarEn certa lingui, klaso povas esar partale definata. Partikulare, certa metodi di ica klaso havas nula korpo o implementaciono. Ica metodi nomesas "abstraktala" (o virtuala en C++).
La klasi posedanta adminime un abstraktala metodo anke nomizesas abstraktala (o virtuala) klasi e on ne povas krear la exemplo direte ecepte ke kreante ne abstraktala subklaso.
- Exemplo
- On deziras modelar la relati objektala di vektorala desegno. On povas dicar ke desegno-objekto es ensemblo di geometrio-figuri (la abstraktala klaso) e singla geometrio-figuro povas esar punto, poligono o lineo ruptita (ica tri klasi heredas de geometrio-figuro). L'abstraktala klaso ne es do nekarebla en lu ipsa, ma lu es nekarebla[1] por apta, generala e simpligita modelo.
Interkonekto
redaktarKlaso posedanta nur abstraktala metodi nomizesas interkonekto (interface) o pure virtuala klaso (en C++) o protokolo (en Objective C).
Metaklaso
redaktarLa klaso di klaso es metaklaso. La metaklasi permisas realigar la strukturala reflekto.
Manipulo dil membr-donaji
redaktarAceso al membri di klaso
redaktarKlaso, quale definita antee, es ensemblo di membri kun tipi (metodi ed atributi) quon on necese guidesas a manipular.
Se p
es instanco di Point(a,b)
ube a
e b
es di tipo int
, on acesas al membri di p
simile ad ico:
p.x = a
ep.y = b
(aceso al atributi)p.getX()
ep.getY()
(aceso al metodi)
La questiono qua venas al mento es la sequanta: pro quo definar metodo getX()
, se on povas acesar direte al feldi x
e y
dil klaso Point
?
Fakte, kande on guidesas a manipular multa klasi a anke multa relati entre ica klasi (cf. heredo), la skemo, la donaji e la operaci povas divenar tre komplexa (specale por individu ne konceptinta la kodexo). On havas do rekurso a mekanismo quon on nomizas enkapsulaciono dil donaji, qua direktas celar a certa parti dil programo la feldi dil klaso en sucio di integreso. L'uzanto do goudesas a manipular nur metodi qua aprobesabas :) e qua teorie satisfacas bone lia rolo.
Segun la principo di enkapsulaciono, la metodi havas publika (public) aceso - ico signifikas ke ula elemento di programo povas uzar metodo. Pri l'atributi kompozanta la stando, li havas aceso privata (private) - nur l'objekto ipsa (e do la metodi quin lu kontenas) havas direta aceso a lua atributi. En ica kazo, la sola maniero di acesar a ica atributi es uzar la metodi dil objekto. La atributi ne povas uzesar direte da altra elemento dil programo nek mem altra objekto, mem se ica objekto es dil sama klaso. Altra punto: la omna atributi di objekto qua heredesas es direte acesebla da l'altra membri di ica objekto.
Relate al lasta dici, esas ofte konfuzeso pri la semantiko dil privata aceso. Le principo di enkapsulaciono implikas protekto dil atributi quan ni nomizas vertikala (nur l'objekto ipsa e la objekti di subklaso havas aceso). Ni trovas ica semantiko en lingui quale Smalltalk, Oz o OCaml. Tamen certa lingui, quale C++, Pascal o Java, pledas por protekto dil atributi quan ni nomizas horizontala (la objekti di sama klaso havas aceso, ma la objekti dil subklasi ne havas).
Kontrolo dil aceso al membri di klaso e videbleso
redaktarCerta lingui propozas chanjar la tipo di aceso dil membri di objekto. Ica operaco plenigesas interne dil klasi di ica objekti. Exemple, la C++ e la Pascal propozas la sequanta videblesi:
- publika: la membri povas uzesar en/e da irga parto dil programo (la metodi definita icamaniere es videbla e uzebla da la uzanto).
- privata (private): la privata membri di klaso es acesebla nur da la objekti di ica klaso, e non da ici di filiala klaso o di altra klaso.
- protektata (protected): quale la privata membri, ma li povas uzesar da la filiala klasi.
La semantiko de ica videblesi e lia nombro varias segun la linguo. Exemple, Java propozas defino poke diferante pri la protektata membri (lu extensesas al ensemblo dil objekti dil sama klaso, dil filiala klasi e dil klasi dil sama paketo). Python propozas anke la posibleso di modifikar la videbleso dil membri di klaso, prefixigante la nomo dil membro kun la signo substrekizata ('_'). Exemple, getX()
es publika metodo, _getX()
es sole uzebla da la elemento dil sama modulo e __getX()
es privata.
Supercharjo di operatoro
redaktarKande on guidesas a manipular donaji di sama tipo (lu es exemplo la kazo di punti en marko), on povas dezirar aplikar operaci ad ica objekti (en senco dil OOP). Tale, la fuzo di du arei (poligoni) donas bone nova areo, quale l'adiciono di du punti donas un nova punto.
- Por adiciono di punti, unesma metodo esus kreinda un membr-metodo dil klaso Point quan on nominus
translate(Point)
e qua retrodonus novaPoint
subisinta l'adiciono. On havas:
...
p=Point(6,2)
q=Point(6,3)
m=Point(0,0)
m=p.translate(q) // p+q
...
- Fakte, plu naturala e multe plu simplacha notizo esus por reprezentar l'adiciono simple per
m = p+q
. Por ico on utilise mekanismo nomizata supercharjo di operatoros, qua ridefinas donita operatoro por donita ago [2].
Durez pri nia klaso Point. La sequanta exemplo Python es tre parolanta:
class Point: (...) def __add__(self,point): # Supercharjo de '+' return Point(self.x + point.x, self.y + point.y) p=Point(0,0) q=Point(2,3) r=p+q
Tale r.getX()
retrodonos 2.
Noti e referi
redaktar- ↑ On tre bone povabus dicar ke vektorala desegno es ensemblo di poligoni, di linei e di punti. Ma on parkomprenas ke, se on deziras adjuntar un plu komplexa geometrio-figuro, oportas modifikar la strukturo ipsa dil matrala klaso, ed ico es ridinda.
- ↑ On povas bone kompreneble supercharjar l'operatoro '+' por ke lu realigez altra kozo kam l'adiciono di punti. Tamen multigo di supercharji male selektita kontributus ad opresar la kodexo ed ad igar lu nelektebla.
Ica pagino uzas kontenajo de la Wikipedio en la Franca. On povas trovar la originala artiklo ye fr:Classe (informatique); ol uzesas segun la GFDL-reguli. |