Mako: OOP PHP Fragen

Hi Leute, ich habe hierzue ein paar fragen.

class Lebewesen  
{  
    public $Vorname;  
    public $Alter;  
    public $Energie;  
	  
    protected function setVorname($vorname)  
    {  
        $this->Vorname = $vorname;  
    }  
  
    public function getVorname()  
    {  
        return $this->Vorname . ' ';  
    }  
	  
    protected function setAlter($alter)  
    {  
        $this->Alter = $alter;  
    }  
  
    public function getAlter()  
    {  
        return $this->Alter . ' ';  
    }  
	  
    protected function setEnergie($energie)  
    {  
        $this->Energie = $energie;  
    }  
  
    public function getEnergie()  
    {  
        return $this->Energie . ' ';  
    }  
	  
	  
    public function Laufe($verbrauch)  
    {		  
       $aktuelleEnergie = $this->getEnergie();  
		  
       if ($verbrauch > $aktuelleEnergie)  
       {  
            $brauchtEnergie = $verbrauch - $aktuelleEnergie;  
            return 'Nicht genügend Energie. Man braucht ' . $brauchtEnergie . ' Energie';  
       }  
       else  
       {  
            $neuEnergie = $aktuelleEnergie - $verbrauch;  
	    $this->setEnergie($neuEnergie);  
            return $verbrauch . ' Energie verbraucht';  
       }  
    }  
}  
  
class Person extends Lebewesen  
{  
    public function __construct($vorname, $nachname)  
    {  
        $this->setVorname($vorname);  
        $this->setNachname($nachname);  
		$this->setEnergie(99);  
    }  
	  
    public function setNachname($nachname)  
    {  
        $this->Nachname = $nachname;  
    }  
  
    public function getNachname()  
    {  
        return $this->Nachname . ' ';  
    }  
}

wenn ich das weg lasse

public $Vorname;  
public $Alter;  
public $Energie;

funktioniert der Code immer noch :S wieso?

das mit der $aktuelleEnergie = $this->getEnergie(); habe ich so gelöst.
ich dachte man könnte es auch so lösen $Energie ist dann immer die aktuelle Energie, aber so funktioniert das nicht. wieso genau?

würde mich freuen wenn mir jemand weiter helfen könnte.

Vielen Dank
Mako

  1. Moin!

    wenn ich das weg lasse

    public $Vorname;

    public $Alter;
    public $Energie;

    
    > funktioniert der Code immer noch :S wieso?  
      
    Er wirft aber Notices wegen undefinierter Properties in der Klasse. Schreib mal als allererste Zeile rein:  
    ~~~php
    error_reporting(E_ALL);  
    
    

    PHP erlaubt, an jedes Objekt beliebig public-Eigenschaften zuzuweisen, ohne sie deklarieren zu müssen. Das ist nur im Sinne von OOP sehr schlechter Stil, denn gerade durch die Deklaration wird ja vereinbart, welche Eigenschaften die Klasse nach außen hin haben soll. Wildwuchs macht es nur schwerer, das Programm zu verstehen und zu debuggen.

    das mit der $aktuelleEnergie = $this->getEnergie(); habe ich so gelöst.
    ich dachte man könnte es auch so lösen $Energie ist dann immer die aktuelle Energie, aber so funktioniert das nicht. wieso genau?

    Die Variable heißt $this->Energie - genauso, wie bei den Methodenaufrufen. Das ist PHP, nicht Java!

    - Sven Rautenberg

    1. das mit der $aktuelleEnergie = $this->getEnergie(); habe ich so gelöst.
      ich dachte man könnte es auch so lösen $Energie ist dann immer die aktuelle Energie, aber so funktioniert das nicht. wieso genau?

      Die Variable heißt $this->Energie - genauso, wie bei den Methodenaufrufen. Das ist PHP, nicht Java!

      Vielen Dank fürs weiterhelfen

  2. Tach!

    Hi Leute, ich habe hierzue ein paar fragen.

    Die sind ja schon geklärt, aber noch ein paar Anmerkungen.

    Getter und Setter. Man lernt ja, vor allem wenn man von großen OOP-Systemen wie Java oder C#/VB.NET kommt, dass man nicht direkt auf Eigenschaften zugreifen sondern die Zugriffe kapseln soll. Dann kann man später bei Bedarf diese Zugriffsmethoden erweitern, ohne dass man am restlichen Programm was ändern muss. .NET macht es hier cleverer, weil man bei Propertys die Zugriffsmethoden nicht direkt sieht, die Propertys also wie normale nackige Fields anspricht. Wechselt man von Fields zu Propertys, muss man am restlichen Programm syntaktisch nichts ändern. Bei Java mit seinen expliziten Zugriffsmethoden muss man die Syntax anpassen, wenn man von Eigenschaft auf Zugriffsmethode wechselt. Auch deswegen hat es sich eingebürgert, alles gleich zu kapseln. Dieses System hat vor allem dann Nachteile, wenn man Resourcen sparen muss. Auf Android gibt es die klare Empfehlung, auf einfache Zugriffsmethoden zu verzichten, vor allem wenn die Eigenschaften nicht nach außen hin propagiert werden müssen. Denn diese Methoden fressen dann nur Prozessorzyklen und Batterie, ohne dass man auf der Habenseite groß was verbuchen kann. Das einzige Argument, dass mir dafür einfällt, wäre das "später erweiterbar, ohne Syntaxänderungen an anderen Stellen". Dagegen spricht aber das YAGNI-Prinzip - you ain't gonna need it - du wirst es nicht brauchen.

    Die Frage, die du dir stellen solltest: Ist es für dich von Vorteil, solche einfachen Getter/Setter zu verwenden?

    Du könntest mit dem Argument kommen: zumindest die Getter haben gleich noch ein Leerzeichenanfügen eingebaut, das braucht es für die Ausgabe.

    public function getEnergie()
        {
            return $this->Energie . ' ';
        }

    Und das ist eine ganz schlechte Idee. Du erstellst deine Klassen, um ein Datenmodell abzubilden. Zu dem Zeitpunkt weißt du noch gar nicht, was mit den Daten am Ende alles passieren soll. Energie ist vermutlich ein Zahlenwert. Mit dem Leerzeichen wird es zu einem String.

    public function Laufe($verbrauch)
        {
           $aktuelleEnergie = $this->getEnergie();

    if ($verbrauch > $aktuelleEnergie)

    An dieser Stelle holst du dir den Wert, der ein String ist und werwendest ihn wieder als Zahl. Bedank dich bei PHP, dass es aus Strings, die mit einer Zahl anfangen, im Zahlenkontext die Zahl extrahiert und den Rest ignoriert. In anderen Systemen würdest du damit gehörig auf die Nase fallen. Also lass die ausgabespezifischen Formatierungen weg. Sie stören auch bei String-Werten (wie Name), wenn es darum geht, sie in eine Datenbank einzutragen - oder allgemein gesagt, in allen Kontexten, die nichts mit der Ausgabe zu tun haben.

    Damit haben deine Getter keine weitere Aufgabe mehr, als den Zugriff zu kapseln. Das ergibt am Ende jede Menge Methodenaufrufe ohne wirkliche Gegenleistung.

    dedlfix.

    1. Tach!

      Hi Leute, ich habe hierzue ein paar fragen.

      Die sind ja schon geklärt, aber noch ein paar Anmerkungen.

      Vielen Dank für deine Anmerkungen