Genauso macht man "globale" Klassen-Variablen. Eigentlich sind das sog. Member-Variablen. Sie können entweder
- nur innerhalb der Klasse sichtbar sein (private)
- innerhalb der Klasse und allen abgeleiteten Klassen sein (protected)
- oder öffentlich sein (public)
Hier ein paar Beispiele:
private:
Code php:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| <?php
class klasse1
{
// Diese Klassenmember ist nur innerhalb dieser Klasse verfügbar
private $member;
public function __construct()
{
$this->member = 42;
}
public function printOutMember()
{
echo "In Klasse " .get_class($this) .": " . $this->member . "<br/>";
}
}
class klasse2 extends klasse1
{
// Diese Klassenmember ist nur innerhalb dieser Klasse verfügbar
private $memberKlasse2;
// Konstruktor wird überschrieben
public function __construct()
{
$this->memberKlasse2 = 44;
}
// Print-Out-Methode wird überschrieben
public function printOutMember()
{
// Das hier funktioniert nicht bzw. gibt einen leeren String aus,
// da auf die Elternklassen-private-Member nicht zugegriffen werden kann
// echo $this->member;
echo "In Klasse " .get_class($this) .": " . $this->memberKlasse2 . "<br/>";
}
}
$a = new klasse1();
$a->printOutMember();
$b = new klasse2();
$b->printOutMember(); |
Protected-Member und Methoden:
Code php:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
| class klasse1
{
// Diese Klassenmember ist nur innerhalb dieser Klasse und Kindsklassen verfügbar
protected $member;
public function __construct()
{
$this->member = 42;
}
public function printOutMember()
{
echo "In Klasse " .get_class($this) .": " . $this->member . "<br/>";
}
}
class klasse2 extends klasse1
{
// Diese Klassenmember ist nur innerhalb dieser Klasse verfügbar
private $memberKlasse2;
// Konstruktor wird überschrieben
public function __construct()
{
// Das ist notwendig, damit der Konstruktor in der Eltern-Klasse auch aufgerufen werden kann
parent::__construct();
$this->memberKlasse2 = 44;
}
// Print-Out-Methode wird überschrieben
public function printOutMember()
{
// Das hier funktioniert nicht bzw. gibt einen leeren String aus,
// da auf die Elternklassen-private-Member nicht zugegriffen werden kann
echo "In Klasse " .get_class($this) .": " . $this->member . "<br/>";
// Wir können auch die Methode in der Eltern-Klasse aufrufen:
parent::printOutMember();
echo "In Klasse " .get_class($this) .": " . $this->memberKlasse2 . "<br/>";
}
}
$a = new klasse1();
$a->printOutMember();
// Das funktioniert auch nicht:
//echo $a->member;
$b = new klasse2();
$b->printOutMember();
// Und das funktioniert auch nicht
//echo $b->memberKlasse2; |
Öffentliche Zugriffe
Code php:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
| <?php
class klasse1
{
// Diese Klassenmember ist nur innerhalb dieser Klasse und Kindsklassen verfügbar
protected $member;
public function __construct()
{
$this->member = 42;
}
public function printOutMember()
{
echo "In Klasse " .get_class($this) .": " . $this->member . "<br/>";
}
}
class klasse2 extends klasse1
{
// Diese Klassenmember ist global verfügbar
public $memberKlasse2;
// Konstruktor wird überschrieben
public function __construct()
{
// Das ist notwendig, damit der Konstruktor in der Eltern-Klasse auch aufgerufen werden kann
parent::__construct();
$this->memberKlasse2 = 44;
}
// Print-Out-Methode wird überschrieben
public function printOutMember()
{
// Das hier funktioniert nicht bzw. gibt einen leeren String aus,
// da auf die Elternklassen-private-Member nicht zugegriffen werden kann
echo "In Klasse " .get_class($this) .": " . $this->member . "<br/>";
echo "In Klasse " .get_class($this) .": " . $this->memberKlasse2 . "<br/>";
}
}
$a = new klasse1();
$a->printOutMember();
// Das funktioniert nicht:
//echo $a->member;
$b = new klasse2();
$b->printOutMember();
// Das hier aber schon:
echo "Im globalen Scope: " . $b->memberKlasse2 . "<br/>"; |
Vielleicht hilft es dir ein bisschen 
Wenn du fragen hast, her damit
Geändert von saftmeister (12.12.11 um 07:22 Uhr)
Grund: Kommentare gefixt
Grüße
--
Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)
Das kommt auf den Anwendungsfall an. Ich habe jetzt aus dem Stand kein Beispiel parat, wo man welche Variante einsetzen könnte. Außer vielleicht dem:
Code php:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
| <?php
/**
* Basis-Personen-Klasse
*
* Unveränderliche Werte werden privat sein
* Veränderliche Werte werden protected sein
*
* @author saftmeister
*/
class Person
{
/**
* Die ID in z.B. der Datenbank
*
* @var int
*/
private $id;
/**
* Der Vorname der Person
*
* @var string
*/
private $firstName;
/**
* Der Nachname der Person
*
* @var string
*/
protected $lastName;
/**
* Das Geburtsdatum der Person
*
* @var DateTime
*/
private $birthDate;
/**
* Die Adresse der Person
*
* @var Address
* @todo Adressenklasse schreiben
*/
protected $address;
/**
* Neues Objekt vom Typ Person erzeugen
*
* @param int $id
* @param string $firstname
* @param string $lastname
* @param DateTime $birthdate
* @param Adress $address
* @throws Exception
*/
public function __construct($id, $firstname, $lastname, DateTime $birthdate, $address)
{
$this->id = $id;
if(!$this->id)
{
throw new Exception('Ungültige ID!');
}
$this->firstName = $firstname;
$this->lastName = $lastname;
$this->birthDate = $birthdate;
$this->address = $address;
}
/**
* Gibt die ID des Datensatzes zurück
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Gibt den Vornamen zurück
*
* @return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Gibt das Geburtsdatum zurück
*
* @return DateTime
*/
public function getBirthDate()
{
return $this->birthDate;
}
}
/**
* Mitarbeiter-Klasse
*
* @author jannicars
*/
class Employer extends Person
{
/**
* Art der Mitarbeit
*
* @var string
*/
private $work;
/**
* Ein neues Objekt vom Typ Employer erzeugen
*
* @param int $id
* @param string $firstname
* @param string $lastname
* @param DateTime $birthdate
* @param Adress $address
* @param string $work
*/
public function __construct($id, $firstname, $lastname, $birthdate, $address, $work)
{
// Eltern-Konstruktor aufrufen und Werte übergeben
parent::__construct($id, $firstname, $lastname, $birthdate, $address);
$this->work = $work;
}
/**
* Mitarbeits-Art zurück geben
* @return string
*/
public function getWork()
{
return $this->work;
}
}
$saftmeister = new Employer(1, 'saft', 'meister', new DateTime('1970-01-01'), '127.0.0.1', 'Coder');
echo "ID: " . $saftmeister->getId() . "<br/>";
echo "Work: " . $saftmeister->getWork() . "<br/>"; |
Angenommen, die Klasse "Person" ist für dich nicht verfügbar, lediglich die öffentlichen Schnittstellen. Du kannst also maximal den Konstruktor aufrufen, um ein neues Objekt zu erzeugen und die ID abholen.
Du sollst jetzt eine Klasse "Employer" schreiben, die "Person" erweitert, auf die veränderlichen Werte darfst du schreibend und lesend zu greifen. Veränderlich bedeutet, das man die Werte jederzeit anpassen können muss.
Werte wie der Vorname, das Geburtsdatum und die ID definieren wir einfach mal unveränderlich. Daher kannst du nur über Getter auf die Werte zu greifen.
Das ganze macht vor allem dort Sinn, wo mit Klassen gearbeitet werden soll, auf die ein weiterer Programmierer (saftmeister hat die Klasse "Person" geschrieben, jannicars die Klasse "Employer") keinen Zugriff haben braucht/soll/darf.
Wie gesagt, das ist stark vom Anwendungsfall abhängig.
Grüße
--
Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)
Es ist vor allem für dich als Entwickler gedacht.
Eine gut durchdachte Klassen-Architektur verringert Fehlerquellen. Angenommen, du hast zwei Klassen, beide haben nix mit einerander gemeinsam, außer einer public Membervariablen, die zufällig in beiden Klassen gleich heißt. In einem unachtsamen Moment schreibst du statt $a->membervar ein $b->membervar. Dann gehst du 2 Tage auf die Suche nach dem Fehler, weil das nicht unbedingt offensichtlich ist.
Zugegeben, das könnte natürlich auch mit Settern passieren.
Wenn du allerdings Member als private deklarierst, die nicht unbedingt von außen erreichbar sein müssen, förderst du deine eigene Hirnhygiene. Das ist ein nicht zu unterschätzendes Stil-Mittel.
Sei's drum. Wenn du das public machen willst, weil es dir damit erstmal leichter fällt, dann mach es so. Ab einem gewissen Level, wenn du schon OOP gut beherrschst, wirst du es freiwillig anwenden 
Aber ich muss entschieden protestieren: Egal ist es nicht! Wenn es egal wäre, hätte man die drei Modifizierer nicht einführen brauchen 
Spätestens bei Singleton- oder Factory-Pattern wirst du merken, das es gut ist, sowas zu haben.
Und ja, es hat was mit Sicherheit zu tun. Damit steuerst du Zugriffsmodi auf Member-Variablen und Methoden.
Ich bin mir sicher, das du es eines Tages verwenden wirst
Grüße
--
Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)
Hmm, warum probierst du es nicht einfach? Nur als Tipp: Wenn du den Constructor private deklarierst, was meinst du, was dann passiert? Ist es dann überhaupt noch möglich, ein Objekt von der Klasse zu erzeugen?
Grüße
--
Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)
Hat Maniac bereits geschrieben: Muss man nicht, wird bei nicht Angabe automatisch auf public gesetzt.
EDIT:
Das muss aber nicht heißen, dass das für immer so bleibt. Es könnte sein, dass das PHP-Core-Team sich von heute auf morgen entscheidet, dass aus Sicherheitsgründen um zu drehen und als "deprecated" einzustufen.
Grüße
--
Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)
[PHP][Snippet] Array zu XML konvertieren