[PHP5] Abstrakte Elternklasse, konkrete Kindklasse

Alles, was PHP betrifft, kann hier besprochen werden.

[PHP5] Abstrakte Elternklasse, konkrete Kindklasse

Postby Thasmo » 20. December 2005 20:39

Hallo, der Titel lässt leider nicht allzuviele Zeichen zu um das Thema vollständig zu beschreiben.

Ich möchte einer Variablen in einer abstrakten Elternklasse den Wert einer Klassenkonstante von einer konkreten Kindklasse zuweisen:

ClassParent->variable = ClassChild::CONSTANT;

Da ich aber bei der Konstante variabel sein muss,
da es mehrere KindKlassen gibt die ich instanziere,
müsste ich den Klassennamen dynamisch erhalten.

Leider funktioniert dies beides nicht:
$this->variable = self::CONSTANT;
$this->variable = __CLASS__::CONSTANT;

Hat jemand einen Tipp für mich? Danke SEHR! =o)
Thasmo
 
Posts: 32
Joined: 28. November 2005 13:25

Postby KingCrunch » 20. December 2005 21:57

Erklär mal dein Problem genauer, dass ich das verstehe. Was hast du mit der Abstrakten Klasse vor und wieso sollen die Ableitungen Inhalte darin ablegen?
Last edited by KingCrunch on 20. December 2005 22:03, edited 1 time in total.
Nicht jeder Fehler ist ein Bug ...
KingCrunch
 
Posts: 1724
Joined: 26. November 2005 19:25

Postby Thasmo » 20. December 2005 22:00

KingCrunch wrote:try
Code: Select all
$this->variable = parent::CONSTANT;


Doesn't work. - Keine Chance.

Die Klasse in der die Zeile existiert, sprich
in der Klasse in der ich versuche den Wert der
Konstante der Kindklasse der Variable zuzuweisen
ist doch schon die ParentKlasse, daher denke
ich kann parent:: ja auch nicht funktionieren.
Thasmo
 
Posts: 32
Joined: 28. November 2005 13:25

Postby KingCrunch » 20. December 2005 22:04

Muss auch zugeben, dass ich das Problem nicht ganz verstanden habe: Siehe mein erster Beitrag ;)
Nicht jeder Fehler ist ein Bug ...
KingCrunch
 
Posts: 1724
Joined: 26. November 2005 19:25

Postby Thasmo » 20. December 2005 22:19

Hier ein Auszug aus meiner Klasse:

Code: Select all
<?php

abstract class GameServer {
   protected $ip, $port, $data, $status, $conn;
   
   public function __construct($address) {   
      if(preg_match('/:/', $address))
         list($this->ip, $this->port) = split(':', $address);
      else {
         $this->ip = $address;
         $this->port = self::PORT;
      }
   }
}

class Quake3Server extends GameServer {
   const PORT = '27960';
   
   public function __construct($address) {      
      parent::__construct($address);
   }
}

$gameserver = new Quake3Server('IP_without[:PORT]"');

?>


Falls kein Port angegeben wurde möchte ich den Standard PORT setzen. Ich habe mehrere ExtendKlassen, jede hat einen anderen Standard PORT.

Wie kann ich das Problem denn noch (besser) lösen?
Thasmo
 
Posts: 32
Joined: 28. November 2005 13:25

Postby Thasmo » 20. December 2005 22:37

Wenn ich es mit einer Variablen mache dann funtioniert es:

Code: Select all
$this->port = $this->defport;


Mit einer Konstante nicht. =o(
Thasmo
 
Posts: 32
Joined: 28. November 2005 13:25

Postby KingCrunch » 20. December 2005 23:15

Bei deinem Aufruf
Code: Select all
$this->port = self::PORT;

existiert die Konstante nicht, da innerhalb der abstrakten Klasse auch keine entsprechende Konstante existiert. Ein ähnlicher Aufruf auf Kind-Klassen sind schon deshalb nicht möglich, da die Kinder nicht eindeutig sind. Eine einfache Lösung wäre es den "Default-Port" bei Aufruf des Parent-Konstruktor mit zu übergeben.
Code: Select all
<?php

abstract class GameServer {
   protected $ip, $port, $data, $status, $conn;
   
   public function __construct($address,$defaultPort) {   
      if(preg_match('/:/', $address))
         list($this->ip, $this->port) = split(':', $address);
      else {
         $this->ip = $address;
         $this->port = $defaultPort;
      }
   }
}

class Quake3Server extends GameServer {
   const PORT = '27960';
   
   public function __construct($address) {     
      parent::__construct($address,self::PORT);
   }
}

$gameserver = new Quake3Server('IP_without[:PORT]"');

?>

Du kannst aber auch den Port direkt ändern:
Code: Select all
<?php

abstract class GameServer {
   protected $ip, $port, $data, $status, $conn;
   
   public function __construct($address) {   
      if(preg_match('/:/', $address))
         list($this->ip, $this->port) = split(':', $address);
      else {
         $this->ip = $address;
      }
   }
}

class Quake3Server extends GameServer {
   const PORT = '27960';
   
   public function __construct($address) {     
      $this->port = self::PORT;
      parent::__construct($address);
   }
}

$gameserver = new Quake3Server('IP_without[:PORT]"');

?>

Wenn die if-Abfrage im Parent-Konstruktor den Port überschreibt, ist ja halb so wild ;)
Nicht jeder Fehler ist ein Bug ...
KingCrunch
 
Posts: 1724
Joined: 26. November 2005 19:25

Postby Thasmo » 21. December 2005 00:05

Das verstehe ich soweit.

Jedoch funktioniert das hier doch schon:

Code: Select all
$this->port = Quake3Server::PORT;


Wieso sollte ich also nicht irgendwie auf
die Kindklasse zugreifen können, wenn es
doch auch mit der Variable funktioniert:

Code: Select all
$this->port = $this->defport;


Im Sinne der Konstanten müsste es doch
self::PORT sein, da ja $this->PORT nicht richtig ist.

Das verwirrt mich. Oder ist einfach die Handhabung
bei Konstanten anders als bei den Variablen, da es keinen
Bezug auf Konstanten gibt, wie der Bezug $this auf Variablen?

*grübel*
Thasmo
 
Posts: 32
Joined: 28. November 2005 13:25

Postby KingCrunch » 21. December 2005 00:19

Ne, also jein, hängt mit den Sichtbarkeiten (scope) zusammen. Ein Objekte besitzt grundsätzlich alle Elemente von sich und alle Parents. Wenn du statisch "parent::methode(..)" eingibst, dann kannst du dort die Eigenschaften ($this->..) nutzen, da das Objekte ja beides besitzt und deshalb beides "sieht". Der Aufruf der Konstanten gehört aber zur Klasse. Deshalb funktioniert "Quake3Server::Konstante", da du damit die Klasse, die die Konstante bereitsstellt, explizit angibst. Die Angabe "self::Konstante" kennt allerdings die Parent-Klasse nicht, weil sie in der Klasse nicht definiert ist. Zudem wüsste sie auch weiterhin nicht exakt welches "self" damit gemeint ist ;)

Hmm... versteht man das?
Also, über die Variable funktioniert das, weil das Objekt sowohl Kind- als auch Elternklasse beinhaltet.
Über Konstante geht es nicht, da die Elternklasse die Kindklasse von sich aus nicht kennt. Zudem ist die Kindklasse nicht eindeutig definiert, da ja eine Klasse beliebig viele nachkommen haben kann.
Über eine Konstante geht es, wenn die Elternklasse den genauen Namen der Klasse kennt, unabhängig von der Verwandtschaft.

So oder so ähnlich
Nicht jeder Fehler ist ein Bug ...
KingCrunch
 
Posts: 1724
Joined: 26. November 2005 19:25

Postby Thasmo » 21. December 2005 20:08

KingCrunch wrote:Ne, also jein, hängt mit den Sichtbarkeiten (scope) zusammen. Ein Objekte besitzt grundsätzlich alle Elemente von sich und alle Parents. Wenn du statisch "parent::methode(..)" eingibst, dann kannst du dort die Eigenschaften ($this->..) nutzen, da das Objekte ja beides besitzt und deshalb beides "sieht". Der Aufruf der Konstanten gehört aber zur Klasse. Deshalb funktioniert "Quake3Server::Konstante", da du damit die Klasse, die die Konstante bereitsstellt, explizit angibst. Die Angabe "self::Konstante" kennt allerdings die Parent-Klasse nicht, weil sie in der Klasse nicht definiert ist. Zudem wüsste sie auch weiterhin nicht exakt welches "self" damit gemeint ist ;)

Hmm... versteht man das?
Also, über die Variable funktioniert das, weil das Objekt sowohl Kind- als auch Elternklasse beinhaltet.
Über Konstante geht es nicht, da die Elternklasse die Kindklasse von sich aus nicht kennt. Zudem ist die Kindklasse nicht eindeutig definiert, da ja eine Klasse beliebig viele nachkommen haben kann.
Über eine Konstante geht es, wenn die Elternklasse den genauen Namen der Klasse kennt, unabhängig von der Verwandtschaft.

So oder so ähnlich


Hm. Gut. Ich hab verstanden, dass es von der Sichtbarkeit her nicht funktionieren kann, aber wieso genau, das ist mir noch etwas unklar.
Thasmo
 
Posts: 32
Joined: 28. November 2005 13:25


Return to PHP

Who is online

Users browsing this forum: No registered users and 2 guests