PHP OOP: Wann benutzt man Klassenkonstanten?

klausschreiber

Well-known member
ID: 162475
L
6 Mai 2006
247
8
Hallo,

ich habe mal ne Frage bezüglich Klassenkonstanten. Ich habe in einer Klasse ein paar Variablen, die sich nicht ändern. Bei der prozedualen Programmierung ist das ja ein Fall für Konstanten.
Klassenkonstanten sind ja "public". Meine sich nicht verändernden Variablen bzw. halt Eigenschaften sind aber "private" oder "protected".
Nimmt man bei bei OOP für sich nicht ändernde Eigenschaften immer Klassenkonstanten, unabhängig davon, welche Zugriffsbeschränkung man der Eigenschaft normalerweise geben würde?

Gruß,
Klaus
 
Wenn der Wert konstant ist, jedoch es keinen Sinn macht ihn von außen einsehbar zu machen (weil man die Info nicht braucht), wofür willst du dann eine Konstante nutzen?
Schreib den Wert fest an die Stelle wo er gebraucht wird, er scheint ja irrelevant nach Außen zu sein und komplett fest.

Da er für Außen unwichtig ist, würde ich ihn ansonsten als protected final deklarieren.
 
Wow, danke für sehr flotte Antwort.

Da er für Außen unwichtig ist, würde ich ihn ansonsten als protected final deklarieren.
Eigenschaften kann man doch gar nicht final deklarieren, oder? So steht es zumindest auf einer PHP OOP Seite:
www.peterkropff.de/site/php/final.htm schrieb:
Leider ist es nicht möglich, gezielt einzelne Eigenschaften als final zu deklarieren. Es ist, genau gesagt, überhaupt nicht möglich! Um zu verhindern, dass Eigenschaften nicht überschrieben werden können, gibt es nur eine radikale Methode. Man definiert die Klasse als final.
Oder habe ich deine Aussage falsch verstanden?
 
danke für deine Antwort.

Wenn ich das richtig sehe, ist es dann am besten, Werte, die sich nicht ändern, aber eigentlich las private oder protected zu definieren sind, als private bzw. protected Variablen zu definieren, oder?

Ich habe halt eine abstrakte "Mutter"-Klasse, die alle Methoden enthält, die in allen "Kind"-Klassen benötigt werden. Die Methoden der Mutterklasse sind jedoch auf Eigenschaften der gerade verwendeten Kindklasse angewiesen (die Eigenschaften ändern sich zwar nicht während der Laufzeit, aber bei Kindklasse A ist der Wert der Eigenschaft anders als bei Kindklasse B). Dann definiere ich die Eigenschaften einfach als protected in den Kindklassen und fertig, oder?
 
Dann definiere ich die Eigenschaften einfach als protected in den Kindklassen und fertig, oder?
Ich würde sagen, eher protected in der Elternklasse und in der Kindklasse wird dann der Wert eventuell geändert.
So ist die Elternklasse dann "vollständig" und ist nicht auf Variablen angewiesen, die eventuell nicht implementiert wurden.
 
Danke für deine Antwort.

Das Problem ist aber, dass es praktisch keinen Standardwert für die Variablen gibt. Also ich kann nicht wirklich einen Wert festlegen, der genommen werden soll, wenn keiner festgelegt wurde. Wenn eine Variable fehlt, ist es eigentlich besser, es kommt eine Fehlermeldung, als wenn ein Standardwert genommen wird, der dann totalen Mist produziert (sind reguläre Ausdrücke, die sich halt jedes Mal komplett unterscheiden). Oder implementiert man die Werte dann einfach als Leerstring?
Die Mutterklasse ist auch nicht direkt aufrufbar, da ich sie als abstract definiert habe. Perfekt wäre es nach meinem Verständnis, wenn man die benötigeten Eigenschaften in der Mutterklasse ebenfalls abstract definieren würde, aber das geht ja meines Wissens nur bei Methoden?
 
dann schreib doch eine protected abstract methode ;)

PHP:
// statt
protected $_var;

// das
protected abstract getVar() {}
 
danke für deine Antwort.

Vielleicht stehe ich gerade auf dem Schlauch, aber ich verstehe gerade nicht genau, wie du das meinst.

Ich habe in meiner abstrakten Mutterklasse z.B. folgenden Ausschnitt:
PHP:
protected function parse()
{
        preg_match_all($this->regexp, $this->file, $this->dataarray, PREG_SET_ORDER);
        ... // (geht noch weiter, aber hierfür unwichtig)
}
In einer Kindklasse habe ich dann folgenden Ausschnitt:
PHP:
protected $file;
protected $regexp;
...

public function __construct($file)
{
    $this->file = $file;
    $this->regexp = "/regulärer Ausdruck/";
    $this->parse();
}
(Es ist nicht so, dass in der Kindklasse nur die Variablen festgelegt werden, sondern es werden schon auch neue Methoden hinzugefügt bzw. in Sonderfällen Methoden der Mutterklasse überschrieben.)

Die Werte für $this->regexp sind ja damit in der Kindklasse fest drinnen und $this->file wird ja bereits beim Erstellen eines Objekts übergeben. Wenn jede Kindklasse dann für die Variablen Getter-Methoden enthalten müsste, würden die ja praktisch so aussehen und wären damit sinnlos:
PHP:
protected getRegexp()
{
    $this->regexp = "regulärer Ausdruck";
}
Oder habe ich etwas falsch verstanden?
 
Oder habe ich etwas falsch verstanden?

Jap :p Gemeint war das wohl so:
Kindklasse:
PHP:
protected static function getRegexp()
{
    return '#...#';
}
Elternklasse:
PHP:
abstract function getRegexp() {}

protected function parse()
{
        preg_match_all($this->getRegexp(), $this->file, $this->dataarray, PREG_SET_ORDER);
        ... // (geht noch weiter, aber hierfür unwichtig)
}

Inwieweit man abstract, protected und static kombinieren darf weiß ich jetzt nicht, das solltest du nochmal entsprechend nachgucken ;)
 
Die Werte für $this->regexp sind ja damit in der Kindklasse fest drinnen und $this->file wird ja bereits beim Erstellen eines Objekts übergeben. Wenn jede Kindklasse dann für die Variablen Getter-Methoden enthalten müsste, würden die ja praktisch so aussehen und wären damit sinnlos:
PHP:
protected getRegexp()
{
    $this->regexp = "regulärer Ausdruck";
}
Oder habe ich etwas falsch verstanden?

Im Sinne der Objektorientierung ist es Quatsch und nicht möglich in einer Vater-Klasse (deine abstrakte Klasse) auf Attribute zuzugreifen, die da gar nicht existieren ;)
Deine Eltern haben dir ja auch nicht auf gut Glück Kleider gekauft in der Hoffnung du wirst ein Mädchen oder?
Deswegen sollst du die Methode bauen, dass die abstrakte Klasse auf jedenfall weiß, dass es einen RegExp gibt, denn es gibt eine abstrakte getRegexp-Methode und diese muss ein nicht abstraktes Kind implementieren.
 
danke für deine Antwort,

hmm, ok. Aber wie soll die Methode in der Kindklasse dann aussehen? In der Vaterklasse schreibe ich ja dann:
PHP:
protected abstract getFile();
protected abstract getRegexp();
Kindklasse:
PHP:
protected abstract getFile()
{
    //Was schreibe ich hier dann rein?
}
protected abstract getRegexp()
{
    //Was schreibe ich hier dann rein?
}
Irgendwie habe ich es immer noch nicht verstanden, habe eh noch meine Probleme mit OOP^^.

edit:
ups, hab deinen Post übersehen, MrToiz. Auch dir danke für die Antwort.
Jap :p Gemeint war das wohl so:
Kindklasse:
PHP:
protected static function getRegexp()
{
    return '#...#';
}
Meinst du damit, dass ich in das return dann den regulären Ausdruck reinpacke? Also oben gar kein $this->regexp definiere, sondern das dann folgendermaßen mache?
PHP:
protected static function getRegexp()
{
    return 'regulärer Ausdruck;
}
Und wie mache ich das dann bei dem Wert $file, der sich jedesmal ändert und im Kontruktor mitgegeben wird?
 
Zuletzt bearbeitet:
statisch? Ne, ich dachte das eigentlich so, wie du es in deinem "Habe-ich-das-so-richtig-verstanden"-Beispiel hattest :biggrin:
 
ok, danke.
also wird das folgende:
PHP:
protected $file;
protected $regexp;
...

public function __construct($file)
{
    $this->file = $file;
    $this->regexp = "/regulärer Ausdruck/";
    $this->parse();
}
dann zu folgendem:
PHP:
 protected $file;
 protected $regexp;
 ...

 protected getRegexp()
{
    $this->regexp = "regulärer Ausdruck";
}

 public function __construct($file)
 {
     $this->file = $file;
     $this->parse();
 }
richtig? Aber ist das dann nicht eher ein Setter, als ein Getter?
Und wie würdest du das dann mit dem Wert $file machen, der normalerweise beim erstellen des Objekts mitübergeben wird? Würdest du $file komplett aus dem Kontruktor rausnehmen und eine puplic Methode machen, wie:
PHP:
public function setFile($file)
{
    $this->file = $file;
}
und in der Haupdatei dann halt statt
PHP:
new class($file);
folgendes:
PHP:
new class();
setFile($file);
?
Ist das ganze dann nicht recht umständlich, bzw. bläht den Quellcode auf? Oder gibt es in anderen Programmiersprachen für diesen Fall auch die Möglichkeit, Eigenschaften abstract zu definieren?
 
Ich würde es nach dem gleichen Ansatz machen.

Nein, das gibt es in keiner mir bekannten Sprache ist nämlich ziemlich sicher einfach nur nen Designfehler.
 
ok, vielen Dank für deine super Hilfe.
Jezt hab ich nur nochmal eine allerletzte (hoffe ich zumindest^^) Frage.

Es ist zwar eigentlich Korintenkackerei, aber ich will halt lernen, wie man es wirklich richtig macht.
z.B. bei $regexp:
Der Wert von $regexp wird ja eigentlich nicht "abgefragt", sondern "gesetzt". Müsste es dann nicht ganz genau genommen statt:
PHP:
protected getRegexp()
{
    $this->regexp = "regulärer Ausdruck";
}
folgendermaßen heißen:
PHP:
protected setRegexp()
{
    $this->regexp = "regulärer Ausdruck";
}

Und dann noch eine allerletzte allgemeine Frage. Wenn ich keine Vaterklasse hätte, die auf Werte in der Kindklasse angewiesen ist, sondern z.B. in diesem Fall halt einfach alles in eine Klasse gepackt hätte (Klar, wäre unklug, wenn man bestimmte Methoden in mehreren Klassen gebrauchen kann, aber nur als Beispiel), dann wäre es schon korrekt, die Werte einfach im Knstruktor den Variablen zuzuweisen, oder?