Vererbung & Listen

Mysticman

Ensign
Registriert
Mai 2004
Beiträge
129
alsoo, ich versuch mir grad die ganze zeit diese beiden themen reinzupeilen, krieg es aber nicht hin!
könnte mir mal bitte einer erklären, was vererbung bedeutet, bzw wie es genau funktioniert?
und mit Listen genauso^^, weil durch unser skript raff ich rein gar nix!...
 
ja, soweit bin ich in meinem buch auch gekommen! :(
nur es geht nicht in meinen kopf, was ich mit vererbung gewinne?ich muss doch so oder so ein neues objekt anlegen, was auf die selben Sachen zugreift, also hab ich doch nix gewonnen oder?
man, dsad geht nicht in meinen kopf :( drehe hier echt gleich durch^^
 
Naja, ein Vorteil ist z.B., dass du eine Collection erstellen kannst, die Objekte der Oberklasse enthalten soll. Dann kannst du darin auch Objekte der abgeleiteten Klasse speichern.
 
Du hast darduch wohl was gewonnen.

Wenn du wie oben die Klasse "Tier" hast müsstes du für die Katze noch die Beine und das Fell Implementieren.
Und einer Schlange ihre Haut.

Das brauchst du durch Vererbung nicht.
 
Ruhig Blut :streicheln:.
Wenn du in der Klasse "Tier" das Attribut "Gewicht" definierst und die Methode "fressen()", dann musst du das in den davon abgeleiteten Klassen Hund und Katze nicht mehr machen.
Schließlich erben die beiden das ja von Tier.
Du brauchst somit den Code für fressen() und Gewicht nur ein einziges Mal schreiben, aber dir sicher sein, dass Hund und Katze das auf die selbe Art und Weise tun.

Oder willst du Quellcode doppelt schreiben :rolleyes:?

Außerdem hast du den Vorteil der Polymorphie.
Was das wieder ist kannst du auch in dem zuvor genannten Link nachlesen.
Kurzfassung: Wenn du sagst, dass du ein Tier hast, dann kannst du problemlos den Hund gegen die Katze tauschen. Es bleibt weiterhin ein Tier.
 
Naja mit Polymorphie könnte ich ein neues Tier bauen das aus Katze und Hund besteht :-), oder eine Klasse die aus Tier und etwas anderem besteht.

Von daher ist Polymorphie mit Vorsicht zu geniessen.

MfG

Arnd
 
Jetzt meinst du aber Mehrfachvererbung Arnd und nicht Polymorphie ;) Polymorphie kommt bei Basisklassen-Zeigern und virtuellen Funktionen ins Spiel.

Davon abgesehen ist auch Vererbung immer mit Vorsicht genießen ;) (das klassische Problem warum es falsch ist, ein Quadrat von Rechteck abzuleiten)
 
Zuletzt bearbeitet:
Zudem kann man in der Klasse Tier die Funktion atmen() implementieren. Die Klasse Fisch kann davon ableiten, aber die Funktion atmen() neu definieren, so dass ein Fisch eben anders atmen kann als das Tier im allgmeinen. :)
 
ok das habe ich ja verstanden! aber wie sieht das ganze denn im code aus?
definiere ich in der basisklasse einfach ABSTRACTE Methoden, wo der methodenrumpf fehlt?
und den methodenrumpf implementiere ich in den Klassen, die von der Basisklasse erben?
oder Bekomme ich nur die Variablennamen geerbt, wie z.b. Alter, Name usw?
das verstehe ich net so ganz.

EDIT: und wie sieht das mit den mothoden dann aus, müssen die vom code her identisch sein oder können die ganz anders sein?
 
Zuletzt bearbeitet:
@7H3 N4C3R,

ist korrekt, danke für die Korrektur.

Als Beispiel:
Code:
class Tier
{
public:
  void  atmen() = 0;
};

class Fisch : public Tier
{
public:
  void atmen();
};

class Katze: public Tier
{
public:
  void atmen();
};

void Katze::atmen()
{
  Lungenatmung();
}

void Fisch::atmen()
{
  Kiemenatmung();
}

void main()
{
  Fisch lFisch;
  Katze lKatze;

  lKatze.atmen();
  lFisch.atmen();
}

Ich habe es nicht kompiliert, es kann also sein das die Konstruktoren noch ergänzt werden müssen. Der Code für die jeweilige Atmungsart fehlt natürlich auch noch :-).

MfG

Arnd
 
Zuletzt bearbeitet:
aber da spare ich doch nichts ;/ ?
also meiner meinung nach hab ich damit nichts gekommt, außer das ich immer den selben methodennamen habe oder?
 
Hm, vielleicht habe ich ein Beispiel, das es etwas klarer macht, was gemeinst ist...
Code:
class Tier
{
   public:
      void atmen ();
      void fressen ();
   
      int gewicht;
      int groesse;
      
};

class Katze : public Tier
{
   public:
      void atmen ();
};

class Hund : public Tier
{
   public:
      void atmen ();
};

int main ( void )
{
   
   Katze MyKatze;
   Hund  MyHund;
   
   MyKatze.gewicht = 123;
   MyKatze.groesse = 456;
   
   MyHund.gewicht = 789;
   MyHund.groesse = 12;
   
   MyKatze.atmen ();
   MyHund.atmen ();
   
}
Natürlich müssen die ganzen Funktionen noch definiert werden, aber das spare ich mir.
Was jetzt der Vorteil ist, ist dass ich nur einmal die Attribute "gewicht" und "groesse" in meiner Basisklasse(Tier) definiere und damit automatisch in Hund und Katze vorhanden sind (jeder Hund und jede Katze hat ja ein Gewicht/Groesse).
Ich hoffe, ich konnte es noch etwas verdeutlichen :)

mfg DaDrivel
 
hm^^ Jein^^ wo spart man sich was bei methoden?du definierst ja die gleichen methoden in jeder klasse nochmal, also wieso in der oberklasse definieren?^^ da spart man doch nix :(
 
Mysticman schrieb:
hm^^ Jein^^ wo spart man sich was bei methoden?du definierst ja die gleichen methoden in jeder klasse nochmal, also wieso in der oberklasse definieren?^^ da spart man doch nix :(


Das Beispiel war vielleicht etwas unglücklich gewählt.

Hier mal nen bissel konkreter. Code ist ne wilde Mischung aus PHP und Java. ;)

PHP:
/* Lebewesen allgemein */
public abstract class Lebewesen {
	public float gewicht;
	public float groesse;

	public abstract String atmen();

}

/* Lungenatmer - üblicherweise Landlebewesen außer Wale. */
public abstract class Lungenatmer extends Lebewesen {

	public String atmen() {
		return "Überlebt in O2 Atmosphäre";
	}

}

/* Kiemennatmer - üblicherweise Fische. */
public abstract class Kiemenatmer extends Lebewesen {

	public String atmen() {
		return "Überlebt in Wasser";
	}

}

/* 	Konkretes Beispiel für ein Lungenatmer.
	Kann noch verfeinert werden, z.B: Labrador, Schäferhund, etc. */
public abstract class Hund extends Lungenatmer {
	/* Hier weiter spezifische Eigenschaften und Methoden. */
	public string fellfarbe;
}

/* 	Konkretes Beispiel für ein Kiemenatmer.
	Kann noch verfeinert werden, z.B. Weißer Hai, Blauhai, etc. */
public abstract class Hai extends Kiemenatmer {
	/* Hier weiter spezifische Eigenschaften und Methoden. */
	public integer flossenanzahl;
}


public class M_planet {
	public Lebewesen[] lebewesen;  // Polymorphie Beispiel
}


sol3 = new M_planet;

hund = new Hund;
hund.groesse = 1.5;
hund.groesse = 8000;
hund.fellfarbe = "braun";

hai = new Hai;
hai.groesse = 7.0;
hai.groesse = 140000;
hai.flossenanzahl = 6;


sol3.lebewesen[0] = hund;
sol3.lebewesen[1] = hai;


echo sol3.lebewesen[0].atmen();
echo sol3.lebewesen[1].atmen();


So, das sollte Dir jetzt den Vorteil etwas stärker verdeutlichen.


Ciao
 
Zuletzt bearbeitet:
Ein Vorteil bei meinem Beispiel ist das Du eine definierte Schnittstelle hast, die jede abgeleitete Klasse definieren muss (wird durch das =0 nach der Methode erzwungen). Dadurch kannst Du sicherstellen das Anwender Deiner Klasse, das machen was Du mit Deiner Basisklasse erreichen willst.
Hier das jedes Tier auch Luft holt, jedes auf seine Weise. Die Verarbeitung der Luft ist dann wieder für jedes Tier gleich.

Wenn Du Code sparen willst so ist das auch möglich.

Code:
class Tier
{
public:
  void  atmen();
  void Luftholen() = 0;
};

void Tier::atmen()
{
   Luftholen();
   eingeatmeteLuftverarbeiten();
}

void Fisch :: Luftholen()
{
   benutzeKiemen();
};

void Katze::Luftholen()
{
  benutzeMund();
};

MfG

Arnd
 
Zuletzt bearbeitet:
Ok, eure Beispiele sollten die Vorteile recht gut zeigen :)
Was ich nicht ganz verstehe, wieso du, Mysticman, nicht verstehst, wieso man sich bei meinem Code etwas spart. Ich muss doch meine Membervariablen nur einmal deklarieren. Bringt das keinen Vorteil? Und es gibt sicher noch viele andere Beispiele, bei denen man sich MemberFunktionen sparen kann( wenn man z.b. seine Membervariablen privat hält und sich auf diese Zugriffsfunktionen definiert).

mfg DaDrivel
 
Hallo, ich habe einige Fragen zum Thema Vererbung:

1.) Eine Klasse A erbt von einer anderen Klasse B, welches ein private-Attribut x hat. Wird x nun mitvererbt?

Mir ist klar, dass man keinen Zugriff auf x hat, das würde nur bei protected oder private funktionieren. Wird das Attribut aber trotzdem vererbt?

2.) Eine abstrakte Klasse hat ein private-Attribut x. Macht das überhaupt Sinn? Verhält sich das bei abstrakten Klassen evtl. anders, so dass z.B. die erste abgeleitete Klasse trotzdem Zugriff auf das Attribut hat?

Danke! :)
 
zu 1.) Das Attribut x wird mitvererbt. du kannst nur nicht direkt darauf zugreifen, weil es private ist. Sollte aber in der Basisklasse eine Get-Methode auf x implementiert sein, die public oder protected ist, kannst den Wert darüber auslesen.

zu 2.) Abstrakte Klassen (zumindest in Java) sind Klassen, in denen nicht jede Methode, die deklariert ist, auch implementiert ist.
Beispiel:
Die abstrakte Basisklasse Lebewesen hat eine (nicht implementierte) Methode fortgewegen(). Diese Methode
muss jetzt in einer abgeleiteten Klasse, von der man Objekte erzeugen will, implementiert werden. So bewegt sich ein Hund anders fort als eine Schlange. Für beide ist aber vordefiniert (in der Basisklasse), dass sie sich fortbewegen können.
 
Danke schon mal. :)

Ja, ich weiß schon, was abstrakte Klassen sind und wie man sie verwendet usw.
Nur - macht ein privates Attribut in einer abstrakten Klasse irgendwie Sinn?

Zum 1.:
Wird es dann wirklich mitvererbt und auf die vererbte Variable zugegriffen, oder greift die mitvererbte öffentliche Methode dann intern auf die Basisklasse zu?
Also wird die Klasse wirklich komplett neu von der ursprünglichen erzeugt, wobei dann auf manche Elemente nicht mehr zugegriffen werden kann oder wird egtl. auch ein Objekt der Basisklasse mitangelegt, auf das zugegriffen wird? In letzteren Fall würde das Element ja doch nicht mitvererbt werden.

Meiner Meinung nach wird es im Sinne der Vererbung nicht mitvererbt. Man müsste das Attribut ja in der vererbten Klasse auch neu anlegen, weil es egtl. nur in der Basisklasse vorhanden ist. Was passiert egtl. wenn eine solche set-Methode mitvererbt wird und ein Attribut mit dem selben Namen noch einmal angelegt wird? Bezieht sich dieses set dann auf die Basisklasse oder auf das neu angelegte Attribut?
 
Zuletzt bearbeitet:
Zurück
Oben