[PHP] Klassen

27o8

abgemeldet
2 Mai 2006
9.028
933
Moin,
was ich mich schon lange Frage: "Was bringen Klassen?". Ich sehe keinen Vorteil für mich eine Klasse zu erstellen :roll: bislang mache ich immer alles mit Funktionen.

Wer kann mir erklären wozu es Klassen gibt, und vorallem warum ich die nutzen sollte und was für Vorteile das hat ;)

Und nicht schimpfen weil ich das nicht weis *gg man kann ja nicht alles wissen und ich frage ja nach um diese Bildungslücke zu schließen :p

Gruß
Gremlin
 
hmm, tja, wie soll man das erklären du hast bestimmte Dinge (Objekte) voneinander gekapselt. Und vorallem hast du zusammengehörige Funktionen zusammen.
Du kannst Daten teilen die alle Methoden nutzen und diese nach aussen schützen, nicht so wie mit Globals, hmm, ach, ich hoffe mal tleilax oder thehacker schreiben da nochwas, die können das denke ich besser erklären, solange sie net nur rein theoretisch mit Kapselung, Polymorphie, Geheimnissprinzip etc kommen ^^
 
Ich hätte als erstes die Kapselung erwähnt :mrgreen: Danach die Begriffe Abstraktion und Geheimniskrämer-Prinzip :biggrin:

Machen wirs mal völlig untheoretisch mit einem Beispiel:
Wie ich zu DOS-Zeiten damals an meinem Strategiespiel gebastelt hab, lauteten meine Funktionen in etwa so:
PHP:
// player.h

char** player_name;
unsigned long* player_color;

void player_playround(int player);
unsigned char player_isalive(int player);
unsigned long player_getpoints(int player);

void player_spawnunit(int player, int unit, int x, int y);
Man erkennt, dass jede Funktion und Variable mit "player_...." benannt is, damit ich z.B. player_name nicht mit map_name verwechsel.
Daten werden in Arrays gespeichert und mit einer ID, die gleich dem Arrayindex is, erreicht. Auch muss jede Funktion diese ID als Argument bekommen, z.B. Lebt Spieler player noch ? Wie viele Punkte hat Spieler player ?
PHP:
// player.c
void player_playround(int player)
{
  printf("%s ist dran...", player_name[player]);
  if(!player_isalive(player))
    return;

  player_foo(player);
  printf("%s hat nun %ld Punkte.", player_name[player], player_getpoints(player));
}
Gucken wir uns das mal aus Klassenperspektive an:
Jeder Spieler ist nun ein echtes Objekt. Objekte haben Eigenschaften (Klassenvariablen) und Methoden (Klassenfunktionen).
PHP:
public class Player
{
  public:
    Player();
    ~Player();

  private:
    char* Name;
    unsigned long Color;

  public:
    void playround(void);
    unsigned char isalive(void);
    unsigned long getpoints(void);

    void spawnunit(int unit, int x, int y);
};
Die Arrays und die komischen IDs fallen weg. Jede Funktion arbeitet mit ihren Werten. Ich gucke nicht mehr, ob Spieler ID noch lebt, sondern ich gucke, ob ich (das Objekt selbst, Operator this liefert eine Referenz auf sich selbst) noch lebe.
PHP:
// player.cpp
void Player::playround(void)
{
  printf("%s ist dran...", name);
  if(!isalive())
    return;

  foo();
  printf("%s hat nun %ld Punkte.", name, getpoints());
}
Vergleichen wir nunmal den Startcode, der die Spieler erstellt.
Früher sind die Arrays gefüllt worden:
PHP:
// main.c

extern char** player_name;
int player_count;

int main(int argc, char** argv)
{
  int i;

  player_count = 4;
  player_name = (char**)_fmalloc(sizeof(char*));
  for(i = 0; i < player_count; i++)
    player_name[i] = (char*)_fmalloc(32);

  game_play();

  for(i = 0; i < player_count; i++)
    _ffree(player_name[i]);
  _ffree(player_name);
}
Heute werden Objekte der Klasse erstellt (Instanzen). Der Konstruktor kümmert sich um die Initialisierung, der Destruktor räumt automatisch wieder auf, wenn das Objekt gelöscht wird:
PHP:
// main.cpp

int player_count;
Player* players;

int main(int argc, char** argv)
{
  int i;

  player_count = 4;
  players = new Player[player_count]; // triggers constructors

  game_play();

  for(i = 0; i < player_count; i++)
     delete players[i]; // triggers destructors
  delete players;
}
PHP:
// player.cpp

Player::Player()
{
  name = new char[32];
}

Player::~Player()
{
  delete name;
}
Noch ein Begriff: Vererbung
Beispiel: Ein AI-Spieler funktioniert genauso wie ein menschlicher Spieler. Der menschliche Spieler braucht ein Interface, die AI hingegen eine Funktion zum Nachdenken. Sterben können sie beide, Punkte und Namen haben sie auch beide.

PHP:
// ai.h

public class AIPlayer : public Player
{
  public:
    AIPlayer();
    ~AIPlayer();

  protected:
    int think_round(unsigned long milli_seconds);
}
PHP:
// human.h

public class HumanPlayer : public Player
{
  public:
    HumanPlayer();
    ~HumanPlayer();

  protected:
    Interface* interface; // <- das Interface is wieder ne Klasse
    inline void show_interface(void) {
      interface->show();
    }
}
Weitere Infos z.B. aus der Wikipedia:
https://de.wikipedia.org/wiki/Objektorientierte_Programmierung
https://de.wikipedia.org/wiki/Klasse_(objektorientierte_Programmierung)
https://de.wikipedia.org/wiki/Konstruktor
https://de.wikipedia.org/wiki/Vererbung_(Programmierung)

P.S. Du hattest im Titel PHP stehen. Meine Beispiele sind alle C/C++, weil ich mit Klassen in PHP noch ned wirklich viel gemacht hab.
Die Konzepte sind aber in allen Programmiersprache gleich, drum heißt es ja allgemein OOP.
 
wobei es bei php nicht wirklich toll ist da es erst nachträglich in die sprache intigriert wurde und deswegen nicht wirklich effektiv ist. bei ruby (als bsp) gibt es keine "normalen" variablen wie string oder float sondern "string" ist ein object der klasse string.... nun sind alle "funktionen" die man auch aus php kennt methoden der klasse string.

zbsp
Code:
var = "ein satz mit vielen buchstaben"

 var.split   #gibt ein array mit den einzelen wörtern zurück => ["ein","satz","mit","vielen","buchstaben"]

var enthält den string auf den split angewand wird und split ist eine methode von string.

wenn man so eine sprache lernt versteht man oop viel einfacher da jede zeile oop enthält.
 
wobei es bei php nicht wirklich toll ist da es erst nachträglich in die sprache intigriert wurde und deswegen nicht wirklich effektiv ist.
Bullshit :!:
Was damals war ist doch vollkommen egal. PHP5 beherrscht die Objektorientierung, und das ist das einzige was zählt. Und gerade autoloading und die Interzeptor-Methoden sind richtig geniale Neuerungen, die andere Sprachen nicht haben.

bei ruby (als bsp) gibt es keine "normalen" variablen wie string oder float sondern "string" ist ein object der klasse string.... nun sind alle "funktionen" die man auch aus php kennt methoden der klasse string.
Jup sowas wäre schön, aber das war eben auch nie der Ansatz von PHP. Aber auch nicht schlimm, kann man ja auf andere Sprachen ausweichen, wenn man Wert drauf legt. Aber das Vorgehen von PHP hat auch Vorteile ;) Füge mal selbst dem String neue Methoden hinzu, geht nur mit Ableitung, und da wird wieder ein String-Objekt erstellt und nicht ein char-Array (Java).

wenn man so eine sprache lernt versteht man oop viel einfacher da jede zeile oop enthält.
das lasse ich mal in den Raum gestellt. Man verwendet dann zwangsmäßig OOP, ob man auch weiß man tut (alle Attribute nur public, alle Methoden nur public) bezweifle ich, man weiß nur, dass man eine Klasse erstellen muss. Aber den Sinn erklärt das noch nicht.
 
Danke schonmal c und c++ hab ich mich noch nie mit befasst aber so auf den ersten Blick kann ich mir schon denken wie es in php ungefähr wäre zumindest bei einigen Sachen.

Ich hab mir auch jetzt mal einige Artikel (noch nicht alle) bei Wikipedia durchgelesen wodurch sich für mich wieder paar Fragen ergeben.

Wikipedia: Objektorientierte Programmierung schrieb:
Die Grundidee der objektorientierten Programmierung ist, Daten und Funktionen, die auf diese Daten angewendet werden können, möglichst eng in einem sogenannten Objekt zusammenzufassen und nach außen hin zu kapseln, so dass Methoden fremder Objekte diese Daten nicht versehentlich manipulieren können.
Also der Sinn ist es die Daten der Klasse A vor Änderungen durch Klasse B zu schützen, aber das hab ich doch mit funktionen auch da doch nur intern die Daten bearbeitet werden!?

Nehmen wir mal das beliebte Beispiel "Klasse Auto":

PHP:
<?php

// die Klasse "Auto" definieren
class auto
{

    // eine Eigenschaft/Attribut festlegen
    var $benoetigter_kraftstoff;

    // eine Methode (flapsig Funktion) festlegen
    function tankdeckel_oeffnen()
    {
        // Ihr Auto spricht mit Ihnen - wenn der
        // Tankdeckel geöffnet wird, sagt es, welchen
        // Kraftstoff es benötigt
        echo "<p>Bitte mit $this->benoetigter_kraftstoff betanken";
    }
}

// bisher passiert noch gar nichts,
// jetzt wird aus der Klasse ein Objekt erzeugt
$auto_1 = new auto;

// dem Auto wird nun der Kraftstoff zugewiesen,
// eine Eigenschaft (Attribut) wird definiert
$auto_1->benoetigter_kraftstoff = "Diesel";

// und nun wird das erste mal die Methode (Funktion)
// tankdeckel_oeffnen aufgerufen und das Auto sagt
// freudig, was es für Sprit benötigt
$auto_1->tankdeckel_oeffnen();
?>
(Quelle: https://www.php-kurs.com/objektorientierte-programmierung-beispiel.htm)

Da seh ich einfach keinen Sinn drin, mag zwar jetzt keine so Tolle
Klasse sein aber wieso so umständlich? Ich würde es einfach so machen:

PHP:
<?php
function tankdeckel_oeffnen($array){
   return 'Bitte '.$array['kraftstoff'].' tanken! <br />';
}

$auto1 = Array();
$auto1['kraftstoff'] = 'Diesel';

$auto2 = Array();
$auto2['kraftstoff'] = 'Super Bleifrei';

echo tankdeckel_oeffnen($auto1);
echo tankdeckel_oeffnen($auto2);
?>
Das ist doch das gleiche wie als wenn ich:
PHP:
$auto1 = new auto;
$auto1->benoetigter_kraftstoff = 'Diesel';
$auto1->tankdeckel_oeffnen();

$auto2 = new auto;
$auto2->benoetigter_kraftstoff = 'Super Bleifrei';
$auto2->tankdeckel_oeffnen();
schreibe. Den Sinn warum ich hier dann doch die Klasse nutzen sollte versteh ich einfach nicht :-?.

Gruß
Gremlin

*edit*
Das Array hab ich nur genutzt um vllt. noch andere Sachen wie $auto1['farbe'] zu übergeben, hätte natürlich auch ne normale Variable übergeben können das ist mir auch klar ^^
 
Zuletzt bearbeitet:
das lasse ich mal in den Raum gestellt. Man verwendet dann zwangsmäßig OOP, ob man auch weiß man tut (alle Attribute nur public, alle Methoden nur public) bezweifle ich, man weiß nur, dass man eine Klasse erstellen muss. Aber den Sinn erklärt das noch nicht.

nein den sinn erklärt es nicht aber es ist eine möglichkeit die hilft ihn zu verstehn! (natürlich ist das von der person und deren vorkenntnissen abhängig aber mir hats geholfen)

zum letzten beitrag von gremlin: ich hab ja gesagt das es in php nicht so viel sinn macht (bis auf die wiederverwendbarkeit) wenn man von der prozedualen programmierung kommt!
 
Und was is jetzt mit deinem Code los, wenn der Entwickler der Funktion tankdeckel_oeffnen() nun das in das ändert:
function tankdeckel_oeffnen($array){
return
'Bitte '.$array['kraftstoffe']['primary'].' tanken! <br />';
}
Man is auf die Idee gekommen, dass Autos mehrere Treibstoffe tanken können. z.B. Ein Elektro-Auto, was ohne Strom noch n Diesel-Reserve-Tank hat.

Der Anwender, der diese Funktion benutzt, guck dumm, als ihm sein Script/Programm um die Ohren fliegt, weil sich die Schnittstelle (interface) heimlich still und leise geändert hat.
Stichwort "Geheimniskrämer-Prinzip": Es geht den Anwender nichts an, wie die Funktion tankdeckel_oeffnen() funktioniert. Genauso wenig (Kapselung) will der Tankdeckel auf alle möglichen weiteren Daten zugreifen.

Der Anwender braucht nur ein Auto, um ihm mitzuteilen, welchen Treibstoff es braucht (wie das intern gemacht wird, interessiert ihn nicht). Er hat also ein Auto
PHP:
$auto = new Auto();
und teilt ihm nur den Kraftstoff mit
PHP:
$auto->kraftstoff = "Diesel";
.
 
diese OOP-Beispiele sind meist die schlechtesten Beispiele für OOP ;)
Weil sie so primitiv sind das Funktionen wirklich mehr sinn machen.

der Sinn von OOP das INNERHALB einer Klasse Dinge vorgehen können, die dich nicht zu interessieren brauchen, die Klasse Auto hat Methoden wie starteMotor(), beendeMotor(), etc etc
Was in diesen Methoden passiert weißt du nicht, du interessierst dich nur für die public-Methoden, die dir zur Verfügung stehen. Intern können soviele Variablen gespeichert sein, wie es will, die du alle nicht kennst (auch Helper-Methoden die komplexe Vorgänge aufsplitten) und du hast KEINEN zugriff darauf. Bei Funktionen hast du das Problem, dass du ihm alle Daten übergeben musst, die für die Funktion gebraucht werden, das kann sehr viele Fehler verursachen. Es werden zum Beispiel wichtige nicht öffentliche Attribute des Autos $auto['resource-pointer'] verändert und auf einmal gibt alles nur noch Fehler, du konntest in Dinge eingreifen die dich nichts angehen, und genau das verhindern Objekte. Zudem hast du wie in häckerleins Beispiel die Funktionen eines Autos an einem Punkt (im Objekt) und nicht in einzelnen Methoden.

Wie sieht es nun aus, wenn wir neben normalen Autos noch Cabrios haben?

Erstmal die Klasse für Autos:
PHP:
class Auto{
  private parkfertig = true;

  //Auto starten
  public start(){
    $this->parkfertig = false;
  }

  //Auto parkfertig abstellen
  public stop(){
    $this->parkfertig = true;
  }

}

Das ist mal ganz primitiv eine Klasse die später dazu dienen soll ein Auto zu fahren, dabei wird immer gespeichert ob das auto parkfertig ist, wenn wir es starten kann es das nicht mehr sein. NAtürlich hat es auch MEthoden wie fahren(), bremsen() etc
Wenn das nun in Funktionen umgesetzt werden würde, hätten wir ein array mit dem wert parkfertig, da kann es dann sein, dass wir fahren, der Programmierer aber auf die geniale Idee kommt in dem Array manuell parkfertig auf true setzt, das funktioniert ja gar nicht da er vllt noch gar nicht den Motor ausgemacht hat, genau das verhindern wir indem wichtige Attribute privat nur in der Klasse verfügbar sind, es kann niemand eingreifen.
Nun haben wir aber noch Cabrios, da mus beim parkfertig abstellen noch das Dach zugemacht werden, nun haben wir mit einer Funktion auto_parkfertigAbstellen() ein Problem, denn es kann das Dach net zumachen, ok, alles kein Problem, also schreiben wir eine Funktion cabrio_parkfertigAbstellen(). Perfekt, alles funzt, nur wir haben vergessen das in der Methode auto_zuendschluesselZiehen() die parkfertigabstellen Funktion aufgerufen wird, also müssen wir wieder eine Funktion cabrio_zuendschluesselZiehen() schreiben, die eigentlich das gleiche macht, wie die andere Funktion, nur das sie eine andere Funktion aufruft als die Auto-Funktion, ziemlich dämmlich, duplizierter Code.
In der Objektorientierung könnten wir von der Klasse Auto die Klasse Cabrio ableiten und müssten nur die Methode parkfertigAbstellen() überschreiben, alle Methoden von Auto die diese Methode aufrufen würden, würden nun diese überschriebene Methode von der Cabrio-Klasse aufrufen.

Mein erster Schritt zur Objektorientierung war eigentlich, weil ich einen Batzen von Variablen hatte, die ich jedesmal von einer Funktion zur anderen Schleifen musste, weil diese diese behandelt. Durch die Obejktorientierung war das einfach, die Klasse hat diese Variablen einfach intern gespeichert und fertig. Es konnte nie wieder passieren, dass ich aus Versehen (oder jemand anders) wichtige Variablen überschreibt, wodurch nichts mehr geht, sondern man musste nur die öffentlichen Methoden kennen und fertig.
Ich denke man muss den Weg selbst finden, versuch doch mal eine DB-Klasse in Funktionen umzusetzen :biggrin:
Das wird in dem Moment spaßig wo man auf 2 Datenbanken zugreifen muss, dann muss jedesmal die Verbindungskennung mitgereicht werden, und wenn man die manuell verändert - AUA - mit OOP geht das net.
 
Ich nehme mir mal das Recht raus und mach noch nen Post zu deiner Beispielklasse mit dem Auto :biggrin:
Denn diese ist nicht ganz ok, und deswegen macht sie keinen Sinn. Also erweitern wir sie mal: (hat nun auch nicht alle Regeln von OOP aber mehr, dass es Sinn macht)

PHP:
<?php

// die Klasse "Auto" definieren
class auto{

  //Kraftstofftypen
  const KRAFTSTOFF_DIESEL = 'Diesel';
  const KRAFTSTOFF_SUPER_BLEIFREI = 'SuperBleifrei';

  // eine Eigenschaft/Attribut festlegen
  private $benoetigter_kraftstoff;

  // eine Methode (flapsig Funktion) festlegen
  public function tanken($liter){
    if(/* $kraftstoffAnDerTankstelle < $liter */){
      return false;
    }
    else{
      // $kraftstoffAnDerTankstelle -= $liter;
      return true;
    }
  }

  //Im Konstruktor muss der Kraftstofftyp eingegeben werden
  public function __construct($kraftstoff){
    if($kraftstoff != self::KRAFTSTOFF_DIESEL && $kraftstoff != self::KRAFTSTOFF_SUPER_BLEIFREI){
      throw new Exception('nicht erlaubter Kraftstoff');
    }
  }
}

// bisher passiert noch gar nichts,
// ein Auto welches Diesel benötigt wird erstellt
$auto_1 = new Auto(Auto::KRAFTSTOFF_DIESEL);

// nun werden 500 Liter getankt
$auto_1->tanken(500);
?>

Was ist nun der große Sinn dahinter?
Was IN der Klasse passiert ist uns egal, wir wissen, dass wir nur Autos mit den beiden Kraftsstoffen erzeugen können (alles andere wird einen Fehler ergeben) und das wir eine gewisse Menge tanken können, was beim Tanken passiert ist uns egal, wir wissen aber das uns der Erfolg mitgeteilt wird. Wie also nun getankt wird ist egal, ob wir selbst Öl produzieren oder an die Tanke fahren. Das ist das Geheimnisprinzip, wir wissen nicht was intern passiert, wir wissen nur wie wir diese Klasse bedienen sollen, und wir können keine internen Prozesse modifizieren und so Fehler einbauen (vereinfacht) zusätzlich hat jede Funktion eine Überprüfung auf Plausibilität der Daten (zb man kann keine negativen Liter tanken). Wir haben also einen ganzen Prozess gekapselt, den jeder Idiot bedienen kann ohne zu wissen was dabei vorgeht, er muss nur das Interface (die öffentlichen Methoden) kennen und das war es schon.
 
Weil wirs hier mit Autos haben, möchte ich an dieser Stelle mal eine alte Lösung von mir für eine Algorithmik-Übungsaufgabe reinstellen.
Code is in Java (für unsere Spezialisten, die hier zufällig mitlesen: Ja, DAS ist Java :yes: :ugly:), aber das sollte ja ned stören.

PHP:
public abstract class Fahrzeug
{
  String Name; // Name des Fahrzeugs
  int Raeder; // Anzahl der Raeder
  int MaxGeschwindigkeit; // Maximale Geschwindigkeit, die das Fahrzeug haben kann
  
  /**
   * Gibt ein paar grundsaetzliche Daten aus
   */
  void AusgabeDaten()
  {
    System.out.println("Ich bin \""+Name+"\", habe "+Raeder+" Raeder und fahre maximal "+MaxGeschwindigkeit+" km/h.");
    AusgabeZusatzDaten();
  }
  
  /**
   * Gibt ggf. zusaetzliche Daten aus
   */
  abstract void AusgabeZusatzDaten();
  
  public static void main(String... args)
  {
    // Teste
    System.out.println("Test...");
    System.out.println();
    
    Motorrad TestMotorrad=new Motorrad();
    TestMotorrad.AusgabeDaten();
    
    System.out.println();
    
    Fahrrad TestFahrrad=new Fahrrad();
    TestFahrrad.Gepaecktraeger=true;
    TestFahrrad.AusgabeDaten();
    
    System.out.println();
    
    Personenkraftwagen TestPersonenkraftwagen=new Personenkraftwagen();
    TestPersonenkraftwagen.PS=200;
    TestPersonenkraftwagen.Sitze=5;
    TestPersonenkraftwagen.Kofferraum=66;
    TestPersonenkraftwagen.AusgabeDaten();
    
    System.out.println();
    
    Lastkraftwagen TestLastkraftwagen=new Lastkraftwagen();
    TestLastkraftwagen.PS=50;
    TestLastkraftwagen.Sitze=3;
    TestLastkraftwagen.Ladekapazitaet=3750;
    TestLastkraftwagen.AusgabeDaten();
    TestLastkraftwagen.Nutze();
    
    System.out.println();
    
    Omnibus TestOmnibus=new Omnibus();
    TestOmnibus.PS=85;
    TestOmnibus.Personen=65;
    TestOmnibus.AusgabeDaten();
    TestOmnibus.Nutze();
    
    System.out.println();
    
    Limosine TestLimosine=new Limosine();
    TestLimosine.PS=175;
    TestLimosine.Sitze=5;
    TestLimosine.Kofferraum=80;
    TestLimosine.AusgabeDaten();
    
    System.out.println();
    
    Cabrio TestCabrio=new Cabrio();
    TestCabrio.PS=350;
    TestCabrio.Sitze=4;
    TestCabrio.Kofferraum=10;
    TestCabrio.AusgabeDaten();
    
    System.out.println();
    System.out.println("Happy End :-)");
  }
}


abstract class Zweirad extends Fahrzeug
{

  Zweirad()
  {
    Raeder=2;
  }
}


class Motorrad extends Zweirad
{

  Motorrad()
  {
    Name="Motorrad";
    MaxGeschwindigkeit=120;
  }
  
  void AusgabeZusatzDaten() {}
}


class Fahrrad extends Zweirad
{
  Boolean Gepaecktraeger;
  
  Fahrrad()
  {
    Name="Fahrrad";
    MaxGeschwindigkeit=40;
  }
  
  void AusgabeZusatzDaten()
  {
    System.out.println("Ausserdem habe ich "+((Gepaecktraeger==true) ? "einen" : "keinen")+" Gepaecktraeger.");
  }
}


abstract class Kraftfahrzeug extends Fahrzeug
{
  int PS;
  /* Motorrad wuerde hier auch passen, wurde aber bei Zweirad eingeordnet, da Java-Klassen immer nur
     von einer Klasse erben koennen
  */
  
  Kraftfahrzeug()
  {
    // Nix zu tun
  }
  
  void AusgabeZusatzDaten()
  {
    System.out.println("Ausserdem habe ich "+PS+" PS unter der Haube !");
  }
}


class Personenkraftwagen extends Kraftfahrzeug
{
  int Sitze;
  int Kofferraum; // Groeße in Liter
  
  Personenkraftwagen()
  {
    Name="Personenkraftwagen";
    MaxGeschwindigkeit=200;
    Raeder=4;
  }
  
  void AusgabeZusatzDaten()
  {
    super.AusgabeZusatzDaten();
    System.out.println("Ich biete "+Sitze+" Sitze und "+Kofferraum+"l Kofferraum.");
  }
}


class Lastkraftwagen extends Kraftfahrzeug
{
  int Sitze;
  int Ladekapazitaet;
  
  Lastkraftwagen()
  {
    Name="Lastkraftwagen";
    MaxGeschwindigkeit=140;
    Raeder=8;
  }
  
  void AusgabeZusatzDaten()
  {
    super.AusgabeZusatzDaten();
    System.out.println("Ich biete "+Sitze+" Sitze und "+Ladekapazitaet+"l Ladekapazitaet.");
  }
  
  void Nutze()
  {
    // Lastkraftwagen ist ein Nutzfahrzeug.
    System.out.println("Ich fahre Waren durch die Gegend...");
  }
}


class Omnibus extends Kraftfahrzeug
{
  int Personen;
  
  Omnibus()
  {
    Name="Omnibus";
    MaxGeschwindigkeit=120;
    Raeder=6;
  }
  
  void AusgabeZusatzDaten()
  {
    super.AusgabeZusatzDaten();
    System.out.println("Ich kann "+Personen+" Personen transpotieren.");
  }
  
  void Nutze()
  {
    // Omnibus ist ein Nutzfahrzeug.
    System.out.println("Ich fahre Personen durch die Gegend...");
  }
}


class Limosine extends Personenkraftwagen
{
  
  Limosine()
  {
    Name+=" - Modell Limosine";
  }
  
  void AusgabeZusatzDaten()
  {
    super.AusgabeZusatzDaten();
    System.out.println("Modell: Limosine");
  }
}


class Cabrio extends Personenkraftwagen
{
  
  Cabrio()
  {
    Name+=" - Modell Cabrio";
  }
  
  void AusgabeZusatzDaten()
  {
    super.AusgabeZusatzDaten();
    System.out.println("Modell: Cabrio");
  }
}
 
Um noch einen Aspekt zu bringen, den ich beim Überfliegen jetzt grade nicht so entdeckt habe:

Wiederverwendbarkeit in Kombination mit Namespaces

Habe ich einmal eine Klasse mit eindeutigem (und treffenden!) Namen geschrieben, kann ich diese immer und überall wiederverwenden und komme nicht wie bei Funktionen in die Misere, dass da evtl. was doppelt heisst.

Ist zwar nur grob umrissen, was Namespaces sind, aber im Endeffekt ist diese Kapselung in einer Klasse einfach wesentlich natürlicher und im Endeffekt, wenn man sich dran gewöhnt hat, intuitiver als Funktionengedönse. Ich würde ja auch nicht X Papiere zu unterschiedlichen Themen einfach so durcheinander würfeln, sondern alles schön in thematische Ordner packen. So sollten Anwendungen (und somit Klassen) das auch handhaben.

Sorry, falls ich was doppelt aufgegriffen habe, aber bin grad nicht ganz auf der Höhe und habe nur quer gelesen...
 
Wiederverwendbarkeit in Kombination mit Namespaces

Namespaces sind schön und gut, jedoch in PHP noch nicht integriert :p
Aber kommt ja nun doch schon mit PHP 5.3 (finde es Klasse, dass nun einiger 6er Features schon in 5.x einfliesen)
Aber persönlich halte ich von Namespaces nicht zu viel, ich finde wenn man wirklich ne gute Namensgebung hat, sollte das ohne Probleme funzen, natürlich kommt es toll, wenn fremde Libraries dies nicht tun (man erinnere sich an das Problem mit der Date-Klasse aus PHP 5.1)
 
Aber persönlich halte ich von Namespaces nicht zu viel, ich finde wenn man wirklich ne gute Namensgebung hat, sollte das ohne Probleme funzen, natürlich kommt es toll, wenn fremde Libraries dies nicht tun (man erinnere sich an das Problem mit der Date-Klasse aus PHP 5.1)

Ich glaub tleilax meint schon allein den Namespace der Klasse ansich. Und ja extra Namespaces in PHP :think: Ich wüsste vor schreck gar nicht was ich damit innem PHP Script sollte... soviele externe Bibliotheken dass es da zu kollisionen kommt verwendet man in PHP Scripts eigentlich nicht, jedenfalls ich nicht.