5. Objekte
5.1. Jede Variable kann zu einem Objekt mit Attributen werden (Beispiel_14)
<?php
// any variable can have attributes by construction
$obj1->attr1 = "un";
$obj1->attr2 = 100;
// displays the
print "objet1=[$obj1->attr1,$obj1->attr2]\n";
// modify object
$obj1->attr2+=100;
// displays the
print "objet1=[$obj1->attr1,$obj1->attr2]\n";
// assigns the value of object1 to object2
$obj2 = $obj1;
// modify obj2
$obj2->attr2 = 0;
// displays both objects
print "objet1=[$obj1->attr1,$obj1->attr2]\n";
print "objet2=[$obj2->attr1,$obj2->attr2]\n";
// assigns the reference from object1 to object3
$obj3 = &$obj1;
// modify obj3
$obj3->attr2 = 10;
// displays both objects
print "objet1=[$obj1->attr1,$obj1->attr2]\n";
print "objet3=[$obj3->attr1,$obj3->attr2]\n";
// is an object a dictionary?
print count($obj1)."\n";
while (list($attribut, $valeur) = each($obj1))
print "obj1[$attribut]=$valeur\n";
// end
exit;
?>
Ergebnisse:
objet1=[un,100]
objet1=[un,200]
objet1=[un,0]
objet2=[un,0]
objet1=[un,10]
objet3=[un,10]
1
obj1[attr1]=un
obj1[attr2]=10
Kommentare
- Zeile 4: Die Notation $obj->attr bezieht sich auf das Attribut attr der Variablen $obj. Falls es nicht existiert, wird es erstellt, wodurch die Variable $obj zu einem Objekt mit Attributen wird.
- Zeile 13: Der Ausdruck $obj2 = $obj1 ist, wenn $obj1 ein Objekt ist, eine Kopie der Objekte per Referenz. Somit sind $obj2 und $obj1 Referenzen auf dasselbe Objekt. Das Objekt selbst kann über jede der beiden Referenzen geändert werden.
- Zeile 20: Der Ausdruck $obj3=&$obj1 weist die Referenz (Adresse) der Variablen $obj1 der Variablen $obj3 zu. Wenn $obj1 ein Objekt ist, wie es hier der Fall ist, entspricht der vorstehende Ausdruck $obj3=$obj1.
- Zeilen 28–29: zeigen, dass ein Objekt wie ein Wörterbuch durchlaufen werden kann. Die Schlüssel des Wörterbuchs sind die Namen der Attribute, und die Werte des Wörterbuchs sind die Werte dieser Attribute.
- Zeile 27: Die Funktion „count“ kann auf ein Objekt angewendet werden, gibt jedoch nicht, wie man erwarten könnte, die Anzahl der Attribute zurück. Daher weist ein Objekt Ähnlichkeiten mit einem Wörterbuch auf, ist aber keines.
5.2. Eine Person-Klasse ohne deklarierte Attribute (Beispiel_15)
<?php
class Personne {
// class attributes
// undeclared - can be created dynamically
// method
function identité() {
// a priori, uses non-existent attributes
return "[$this->prénom,$this->nom,$this->âge]";
}
}
// test
// attributes are public and can be created dynamically
$p = new Personne();
$p->prénom = "Paul";
$p->nom = "Langevin";
$p->âge = 48;
// method call
print "personne=" . $p->identité() . "\n";
// end
exit;
?>
Ergebnisse:
Kommentare
- Zeilen 3–13: Definieren Sie eine Klasse „Person“. Eine Klasse ist eine Vorlage, die zum Erstellen von Objekten verwendet wird. Eine Klasse ist eine Sammlung von Attributen und Funktionen, die als Methoden bezeichnet werden. Attribute müssen nicht deklariert werden.
- Zeilen 9–12: Die Methode identity zeigt die Werte von drei Attributen an, die nicht in der Klasse deklariert sind. Das Schlüsselwort $this bezieht sich auf das Objekt, auf das die Methode angewendet wird.
- Zeile 17: Ein Objekt $p vom Typ Person wird erstellt. Das Schlüsselwort new wird verwendet, um ein neues Objekt zu erstellen. Die Operation gibt eine Referenz auf das erstellte Objekt zurück (d. h. eine Adresse). Verschiedene Schreibweisen sind möglich: new Person(), new Person, new person. Bei dem Klassennamen wird die Groß-/Kleinschreibung nicht berücksichtigt.
- Zeilen 18–20: Die drei von der identity-Methode benötigten Attribute werden im Objekt $p angelegt.
- Zeile 22: Die identity-Methode der Klasse Person wird auf das Objekt $p angewendet. Im Code (Zeilen 9–11) der identity-Methode bezieht sich $this auf dasselbe Objekt wie $p.
5.3. Die Klasse „Person“ mit deklarierten Attributen (Beispiel_16)
<?php
class Personne {
// class attributes
var $prénom;
var $nom;
var $âge;
// method
function identité() {
return "[$this->prénom,$this->nom,$this->âge]";
}
}
// test
// attributes are public
$p = new Personne();
$p->prénom = "Paul";
$p->nom = "Langevin";
$p->âge = 48;
// method call
print "personne=" . $p->identité() . "\n";
// end
exit;
?>
Ergebnisse:
Kommentare
5.4. Die Person-Klasse mit einem Konstruktor (Beispiel_17)
Die vorherigen Beispiele zeigten exotische Person-Klassen, wie sie in PHP 4 anzutreffen waren. Es wird nicht empfohlen, diesen Beispielen zu folgen. Wir stellen nun eine Person-Klasse vor, die den Best Practices von PHP 5 entspricht:
<?php
class Personne {
// class attributes
private $prénom;
private $nom;
private $âge;
// getters and setters
public function getPrénom() {
return $this->prénom;
}
public function getNom() {
return $this->nom;
}
public function getAge() {
return $this->âge;
}
public function setPrénom($prénom) {
$this->prénom = $prénom;
}
public function setNom($nom) {
$this->nom = $nom;
}
public function setAge($age) {
$this->âge = $age;
}
// manufacturer
function __construct($prénom, $nom, $âge) {
// we go through sets
$this->setPrénom($prénom);
$this->setNom($nom);
$this->setAge($âge);
}
// method toString
function __toString() {
return "[$this->prénom,$this->nom,$this->âge]";
}
}
// test
// creation of a person object
$p = new Personne("Paul", "Langevin", 48);
// identity of this person
print "personne=$p\n";
// we change the age
$p->setAge(14);
// identity of the person
print "personne=$p\n";
// end
exit;
?>
Ergebnisse:
Kommentare
- Zeilen 3–48: die Klasse „Person“
- Zeilen 6–8: die privaten Attribute der Klasse. Diese Attribute sind nur innerhalb der Klasse sichtbar. Weitere Schlüsselwörter, die verwendet werden können, sind:
- public: macht das Attribut zu einem öffentlichen Attribut, das von außerhalb der Klasse sichtbar ist
- protected: macht das Attribut zu einem geschützten Attribut, das innerhalb der Klasse und ihrer abgeleiteten Klassen sichtbar ist.
- Da die Attribute privat sind, kann von außerhalb der Klasse nicht auf sie zugegriffen werden. Daher können wir den folgenden Code nicht schreiben:
Hier befinden wir uns außerhalb der Klasse „Person“. Da das Attribut „name“ privat ist, ist Zeile 2 falsch. Um die privaten Felder des Objekts $p zu initialisieren, gibt es zwei Möglichkeiten:
- (Fortsetzung)
- Verwenden Sie die öffentlichen Set- und Get-Methoden (die Namen dieser Methoden können beliebig sein) aus den Zeilen 11–33. Wir können dann schreiben:
- (Fortsetzung)
- Verwenden Sie den Konstruktor aus den Zeilen 36–41. Wir würden dann schreiben:
Der obige Code ruft automatisch die Klassenmethode __construct der Klasse Person auf.
- Zeile 54: Diese Zeile gibt die Person $p als Zeichenkette aus. Dazu wird die Klassenmethode __toString der Person-Klasse verwendet.
5.5. Die Person-Klasse mit Gültigkeitsprüfungen im Konstruktor (Beispiel_18)
Der Konstruktor einer Klasse ist der richtige Ort, um zu überprüfen, ob die Initialisierungswerte des Objekts korrekt sind. Ein Objekt kann jedoch auch über seine Set-Methoden oder Äquivalente initialisiert werden. Um zu vermeiden, dass dieselben Prüfungen an zwei verschiedenen Stellen doppelt durchgeführt werden, platzieren wir sie innerhalb der Set-Methoden. Wenn festgestellt wird, dass der Initialisierungswert eines Objekts falsch ist, wird eine Ausnahme ausgelöst. Hier ist ein Beispiel:
<?php
class Personne {
// class attributes
private $prénom;
private $nom;
private $âge;
// getters and setters
public function getPrénom() {
return $this->prénom;
}
public function getNom() {
return $this->nom;
}
public function getAge() {
return $this->âge;
}
public function setPrénom($prénom) {
// first name must be non-empty
if (!preg_match("/^\s*(.+?)\s*$/", $prénom, $champs)) {
throw new Exception("Le prénom doit être non vide");
} else {
$this->prénom = $champs[1];
}
}
public function setNom($nom) {
// name must be non-empty
if (!preg_match("/^\s*(.+?)\s*$/", $nom, $champs)) {
throw new Exception("Le nom doit être non vide");
} else {
$this->nom = $champs[1];
}
}
public function setAge($âge) {
// age must be valid
if (!preg_match("/^\s*(\d+)\s*$/", $âge, $champs)) {
throw new Exception("L'âge doit être un entier positif ou nul");
} else {
$this->âge = $champs[1];
}
}
// manufacturer
function __construct($prénom, $nom, $âge) {
// we go through sets
$this->setPrénom($prénom);
$this->setNom($nom);
$this->setAge($âge);
}
// method toString
function __toString() {
return "[$this->prénom,$this->nom,$this->âge]";
}
}
// test
// creation of a Personne object
$p = new Personne("Paul", "Langevin", 48);
// identity of this person
print "personne=$p\n";
// creation of an erroneous Person object
try {
$p = new Personne("xx", "yy", "zz");
} catch (Exception $e) {
print $e->getMessage();
}
// end
exit;
?>
Ergebnisse:
Kommentare
- Zeilen 23–30: Initialisierung des Attributs „first_name“ und Überprüfung des Initialisierungswerts
- Zeile 25: Verwendung eines regulären Ausdrucks. Der Vorname ist eine Folge aus einem oder mehreren Zeichen, der möglicherweise Leerzeichen vorangestellt oder nachgestellt sind.
- Zeile 26: Ist der Nachname leer, wird eine Ausnahme ausgelöst; andernfalls wird der Vorname gespeichert (Zeile 28)
- Zeile 66: Verwendung des Konstruktors der Klasse „Person“
- Zeile 68: Verwendung der Methode __toString der Klasse „Person“
- Zeilen 70–74: Behandlung aller vom Konstruktor der Klasse „Person“ ausgelösten Ausnahmen.
5.6. Hinzufügen einer Methode, die als zweiter Konstruktor fungiert (Beispiel_19)
In PHP 5 ist es nicht möglich, mehrere Konstruktoren mit unterschiedlichen Parametern zu haben, die es ermöglichen würden, ein Objekt auf verschiedene Arten zu konstruieren. Wir können daher Methoden verwenden, die als Konstruktoren fungieren:
<?php
class Personne {
// class attributes
private $prénom;
private $nom;
private $âge;
// getters and setters
public function getPrénom() {
return $this->prénom;
}
….
// manufacturer
function __construct($prénom, $nom, $âge) {
// we go through sets
$this->setPrénom($prénom);
$this->setNom($nom);
$this->setAge($âge);
}
// method
public function initWithPersonne($p) {
// initializes the current object with a person $p
$this->__construct($p->prénom, $p->nom, $p->âge);
}
// method toString
function __toString() {
return "[$this->prénom,$this->nom,$this->âge]";
}
}
// test
// creation of a Personne object
$p = new Personne("Paul", "Langevin", 48);
// identity of this person
print "personne=$p\n";
// creation of a second person
$p2 = new Personne("Laure", "Adeline", 67);
// initialization of the first with the values of the second
$p->initWithPersonne($p2);
// check
print "personne=$p\n";
// end
exit;
?>
Ergebnisse:
Kommentare
- Zeilen 26–29: Mit der Methode initWithPerson können Sie die Attributwerte eines anderen Person-Objekts dem aktuellen Objekt zuweisen. Hier wird der Konstruktor __construct aufgerufen, dies ist jedoch nicht zwingend erforderlich.
5.7. Ein Array von Person-Objekten (Beispiel_20)
Das folgende Beispiel zeigt, dass Sie Arrays von Objekten haben können.
<?php
class Personne {
// class attributes
private $prénom;
private $nom;
private $âge;
// getters and setters
public function getPrénom() {
return $this->prénom;
}
...
// manufacturer
function __construct($prénom, $nom, $âge) {
// we go through sets
$this->setPrénom($prénom);
$this->setNom($nom);
$this->setAge($âge);
}
// method
public function initWithPersonne($p) {
….
}
// method toString
function __toString() {
...
}
}
// test
// create an array of Personne objects
$groupe = array(new Personne("Paul", "Langevin", 48), new Personne("Sylvie", "Lefur", 70));
// identity of these persons
for ($i = 0; $i < count($groupe); $i++)
print "groupe[$i]=$groupe[$i]\n";
// end
exit;
?>
Ergebnisse:
Kommentare
- Zeile 39: Erstellung eines Arrays mit 2 Personen
- Zeile 42: Durchlaufen des Arrays
- Zeile 43: $group[$i] ist ein Objekt vom Typ Person. Die Methode __toString wird verwendet, um es anzuzeigen.
5.8. Erstellen einer von der Klasse Person abgeleiteten Klasse (Beispiel_21)
<?php
class Personne {
// class attributes
private $prénom;
private $nom;
private $âge;
// getters and setters
public function getPrénom() {
return $this->prénom;
}
...
// manufacturer
function __construct($prénom, $nom, $âge) {
// we go through sets
$this->setPrénom($prénom);
$this->setNom($nom);
$this->setAge($âge);
}
// method
public function initWithPersonne($p) {
// initializes the current object with a person $p
$this->__construct($p->prénom, $p->nom, $p->âge);
}
// method toString
function __toString() {
return "[$this->prénom,$this->nom,$this->âge]";
}
}
// a class derived from Personne
class Enseignant extends Personne {
// attributes
private $discipline; // d// subject taught
// getter and setter
public function getDiscipline() {
return $this->discipline;
}
public function setDiscipline($discipline) {
$this->discipline = $discipline;
}
// manufacturer
public function __construct($prénom, $nom, $âge, $discipline) {
// parent attributes
parent::__construct($prénom, $nom, $âge);
// other attributes
$this->setDiscipline($discipline);
}
// overloads the __toString function of the parent class
public function __toString() {
return "[" . parent::__toString() . ",$this->discipline]";
}
}
// test
// creation of an array of Personne and derived objects
$groupe = array(new Enseignant("Paul", "Langevin", 48, "anglais"), new Personne("Sylvie", "Lefur", 70));
// identity of these persons
for ($i = 0; $i < count($groupe); $i++)
print "groupe[$i]=$groupe[$i]\n";
// end
exit;
?>
Ergebnisse:
Kommentare
- Zeilen 3–35: Die Klasse „Person“
- Zeile 38: Die Klasse „Teacher“ erweitert die Klasse „Person“. Die abgeleitete Klasse „Teacher“ erbt die Attribute und Methoden ihrer übergeordneten Klasse.
- Zeile 41: Die Klasse „Teacher“ fügt ein neues, für sie spezifisches Attribut „subject“ hinzu
- Zeile 55: Der Konstruktor der Klasse „Teacher“ benötigt 4 Parameter
- 3 zur Initialisierung ihrer übergeordneten Klasse (Vorname, Nachname, Alter)
- 1 für ihre eigene Initialisierung (subject)
- Zeile 57: Die abgeleitete Klasse hat über das Schlüsselwort parent:: Zugriff auf die Methoden und Konstruktoren ihrer übergeordneten Klasse. Hier übergeben wir die Parameter (first_name, last_name, age) an den Konstruktor der übergeordneten Klasse.
- Zeile 64: Die Methode __toString der abgeleiteten Klasse verwendet die Methode __toString der übergeordneten Klasse.
- Zeile 71: Ein Array, das ein Teacher-Objekt und ein Person-Objekt enthält.
- Zeile 74: Wir durchlaufen die Elemente des Arrays
- Zeile 75: Die Methode __toString jedes Elements $group[$i] wird aufgerufen. Die Klasse „Person“ verfügt über eine __toString-Methode. Die Klasse „Teacher“ verfügt über zwei: die ihrer übergeordneten Klasse und ihre eigene. Man könnte sich fragen, welche davon aufgerufen wird. Die Ausführung zeigt, dass die Methode der Klasse „Teacher“ aufgerufen wurde. Dies ist immer der Fall: Wenn eine Methode für ein Objekt aufgerufen wird, wird in der folgenden Reihenfolge danach gesucht: im Objekt selbst, in seiner übergeordneten Klasse, falls vorhanden, dann in der übergeordneten Klasse der übergeordneten Klasse und so weiter… Die Suche wird beendet, sobald die Methode gefunden wurde.
5.9. Erstellen einer zweiten Klasse, die von der Klasse „Person“ abgeleitet ist (Beispiel_22)
Das folgende Beispiel erstellt eine Klasse „Student“, die von der Klasse „Person“ abgeleitet ist:
<?php
class Personne {
// class attributes
private $prénom;
private $nom;
private $âge;
// getters and setters
public function getPrénom() {
return $this->prénom;
}
...
// manufacturer
function __construct($prénom, $nom, $âge) {
// we go through sets
$this->setPrénom($prénom);
$this->setNom($nom);
$this->setAge($âge);
}
// method
public function initWithPersonne($p) {
// initializes the current object with a person $p
...
}
// method toString
function __toString() {
return "[$this->prénom,$this->nom,$this->âge]";
}
}
// a class derived from personne
class Enseignant extends Personne {
// attributes
private $discipline; // d// subject taught
// getter and setter
...
// manufacturer
public function __construct($prénom, $nom, $âge, $discipline) {
// parent attributes
parent::__construct($prénom, $nom, $âge);
// other attributes
$this->setDiscipline($discipline);
}
// overloads the _identité__toString function of the parent class
public function __toString() {
return "[" . parent::__toString() . ",$this->discipline]";
}
}
// a class derived from Personne
class Etudiant extends Personne {
// attributes
private $formation; // d// subject taught
// getter and setter
public function getFormation() {
return $this->formation;
}
public function setFormation($formation) {
$this->formation = $formation;
}
// manufacturer
public function __construct($prénom, $nom, $âge, $formation) {
// parent attributes
parent::__construct($prénom, $nom, $âge);
// other attributes
$this->setFormation($formation);
}
// overloads the __toString function of the parent class
public function __toString() {
return "[" . parent::__toString() . ",$this->formation]";
}
}
// test
// creation of a table of person objects and derivatives
$groupe = array(new Enseignant("Paul", "Langevin", 48, "anglais"), new Personne("Sylvie", "Lefur", 70), new Etudiant("Steve", "Boer", 23, "iup2 qualité"));
// identity of these persons
for ($i = 0; $i < count($groupe); $i++)
print "groupe[$i]=$groupe[$i]\n";
// end
exit;
?>
Ergebnisse:
groupe[0]=[[Paul,Langevin,48],anglais]
groupe[1]=[Sylvie,Lefur,70]
groupe[2]=[[Steve,Boer,23],iup2 qualité]
5.10. Schnittstellen (Beispiel_23)
Eine Schnittstelle ist eine Struktur, die Methodenprototypen definiert. Eine Klasse, die eine Schnittstelle implementiert, definiert den Code für alle Methoden der Schnittstelle.
<?php
// an interface
interface IExemple {
function ajouter($i, $j);
function soustraire($i, $j);
}
// interface implementation 1
class Classe1 implements IExemple {
public function ajouter($a, $b) {
return $a + $b + 10;
}
public function soustraire($a, $b) {
return $a - $b + 20;
}
}
// interface implementation 2
class Classe2 implements IExemple {
public function ajouter($a, $b) {
return $a + $b + 100;
}
public function soustraire($a, $b) {
return $a - $b + 200;
}
}
// function
function calculer($a, $b, IExemple $interface) {
print $interface->ajouter($a, $b)."\n";
print $interface->soustraire($a, $b)."\n";
}
// ------------------- hand
// creation of 2 objects of type Class1 and Class2
$c1 = new Classe1();
$c2 = new Classe2();
// call the calculate function
calculer(4, 3, $c1);
calculer(14, 13, $c2);
?>
Ergebnisse
Kommentare
- Zeilen 4–8: Die Schnittstelle IExample definiert zwei Methoden: die Funktion add (Zeile 5) und die Funktion subtract (Zeile 7). Die Schnittstelle definiert keinen Code für diese Methoden. Dies übernehmen die Klassen, die die Schnittstelle implementieren.
- Zeile 11: Die Klasse „Class1“ implementiert die Schnittstelle „IExample“. Sie definiert daher den Code für die Methode „add“ (Zeile 13) und die Methode „subtract“ (Zeile 17).
- Zeilen 24–34: Dasselbe gilt für die Klasse Class2.
- Zeile 37: Die Methode
*calculernimmt drei Parameter entgegen: zwei Ganzzahlen,*$a*und$b*, sowie ein Objekt*$interface, das die Schnittstelle*IExampleimplementiert. Wir hättenfunction calculate($a, $b, $interface)schreiben können, ohne den TypIExampledes Parameters*$interface*anzugeben. Durch die Angabe ermöglichen wir es dem PHP-Interpreter zu überprüfen, ob der tatsächliche Parameter tatsächlich ein Objekt ist, das die Schnittstelle*IExample* implementiert. - Zeilen 38–39: Verwendung der Methoden „add“ und „subtract“ des Objekts $interface. Da es die Schnittstelle IExample implementiert, wissen wir, dass es über diese beiden Methoden verfügt.
- Zeilen 44–45: Erstellung von zwei Objekten unterschiedlicher Typen, die beide die IExample-Schnittstelle implementieren.
- Zeile 47: Wir übergeben das Objekt $c1 vom Typ Class1, das die IExample-Schnittstelle implementiert, an die Funktion calculate.
- Zeile 48: Das Objekt $c2 vom Typ Class2, das die Schnittstelle IExample implementiert, wird an die Funktion calculate übergeben.