Carsten Geschrieben 7. März 2011 Melden Share Geschrieben 7. März 2011 Im Rahmen meiner KI-Reihe hab ich in einem Tutorial mal das Thema Vererbung in C# etwas unter die Lupe genommen: Was ist Vererbung? Wofür brauch ich das? Und vorallem: Wie mach ich das? Diesen Fragen will in meinem 13 minütigen Video auf den Grund gehen. Zum Tutorial: Unity3D Tutorial - C# Vererbung Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 8. März 2011 Melden Share Geschrieben 8. März 2011 Das muss ich mir demnächst mal ansehen. Vererbung kann in Unity leider nicht richtig ausgenutzt werden, da der Inspektor keine Werte erbender Typen zulässt - deshalb benutze ich das nie ^^ Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Carsten Geschrieben 8. März 2011 Autor Melden Share Geschrieben 8. März 2011 Hallo Sascha, ich weiß jetzt gerade nicht wirklich was Du mit "Werte erbender Typen" meinst. Werte vererbt man ja nicht sondern nur die Eigenschaften und Methoden (und deren Variablen etc.) einer Klasse. Und das Nutzen einer Klasse bzw. eines Skripts als Basisklasse für eine andere funktioniert wunderbar, wie du dem Video entnehmen kannst. Aber vielleicht missverstehe ich dich auch gerade ein bisschen ... Gruß Carsten Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 8. März 2011 Melden Share Geschrieben 8. März 2011 Ich meine folgendes: Klasse B erbt von Klasse A Variable ist vom Typ Klasse A und bekommt aber ein Objekt des Typs Klasse B als Wert. Das will der Inspektor nicht... wäre aber supernützlich. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Carsten Geschrieben 9. März 2011 Autor Melden Share Geschrieben 9. März 2011 Da hast Du natürlich recht, sowas geht nicht. Aber das geht auch grundsätzlich nicht, denn sonst könnte man ja auf ein Variable jedes Skript ziehen, weil ja alle Unity-Skripte von MonoBehaviour erben. So ein Verhalten sollte man über Schnittstellen lösen können, wobei ich das in Unity noch nicht gemacht habe. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 9. März 2011 Melden Share Geschrieben 9. März 2011 Naja, man definiert ja auch keine Variablen vom Typ MonoBehaviour. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Carsten Geschrieben 9. März 2011 Autor Melden Share Geschrieben 9. März 2011 Nein, aber die Skripte erben davon ... Okay, das trifft nicht ganz auf dein obiges Beispiel zu, geb ich ja zu Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
amdbuster Geschrieben 20. März 2019 Melden Share Geschrieben 20. März 2019 Auch wenn das Thema schon älter ist, hätte ich auch mal eine Frage. In einem Tutorial(1.Bild) wurde die Vererbung vorgestellt. Nun wollte ich das mal ausprobieren(2.Bild) und habe ein funktionierendes Script um die Klasse "Superhelden" erweitert(rot eingerahmtes). Doch funktioniert das nicht und Unity gibt die Meldungen aus: Assets/03_C#_Grundlagen/Scripts/S31ConstructorUndVererbung.cs(29,14): error CS0101: The namespace `global::' already contains a definition for `Mensch' & Assets/03_C#_Grundlagen/Scripts/S31ConstructorUndVererbung.cs(53,14): error CS0101: The namespace `global::' already contains a definition for `SuperMensch' . Funktioniert das nur von einem Script zum anderen oder geht das auch innerhalb eines Scripts? Falls ja, was habe ich falsch gemacht? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
SirTreffNix_Dev Geschrieben 20. März 2019 Melden Share Geschrieben 20. März 2019 Die Meldung sagt eigentlich, dass es bereits eine Klasse mit diesem Namen gibt. Kann es sein, dass du das Script umbenannt oder verschoben hast und es diese Klassen deshalb jetzt zwei mal in deinem Projekt gibt? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
amdbuster Geschrieben 21. März 2019 Melden Share Geschrieben 21. März 2019 Ahja, hatte sie wirklich umbenannt und nicht gesehen das die alte noch/wieder da war. Nun habe ich aber diese Fehlermeldungen: Assets/03_C#_Grundlagen/Scripts/S31ConstructorUndVererbung.cs(20,29): error CS1729: The type `SuperMensch' does not contain a constructor that takes `3' arguments Assets/03_C#_Grundlagen/Scripts/S31ConstructorUndVererbung.cs(57,12): error CS1729: The type `Mensch' does not contain a constructor that takes `0' arguments Wenn ich das richtig verstehe, wird die Klasse nicht ausgelesen. Man kann doch schon vorhandenes erweitern und muß nicht jedesmal alles neu schreiben, oder? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
SirTreffNix_Dev Geschrieben 21. März 2019 Melden Share Geschrieben 21. März 2019 Auf dem Screenshot von deinem Code, hat die Klasse Mensch einen Konstruktor, der drei Argumente erwartet. Durch die Vererbung musst du den Konstruktor der Basisklasse bedienen. Dieser erwartet zwingend drei Argumente. Entweder du erstellst in der Basisklasse zusätzlich einen Konstruktor, der 0 Argumente akzeptiert oder du übergibst die Argumente mit dem Schlüsselwort "base" an die Basisklasse. Vereinfacht dargestellt entweder: public class Mensch { public Mensch(int dasAlter, string derName, string derBeruf) { } public Mensch() { } } public class SuperMensch : Mensch { public SuperMensch(int dasAlter, string derName, string dieFaehigkeit) { } } oder: public class Mensch { public Mensch(int dasAlter, string derName, string derBeruf) { } } public class SuperMensch : Mensch { public SuperMensch(int dasAlter, string derName, string dieFaehigkeit, string derBeruf) : base (dasAlter, derName, derBeruf) { } } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
amdbuster Geschrieben 21. März 2019 Melden Share Geschrieben 21. März 2019 Also muß ich doch nochmal alles angeben. Im Video(1.Bild) sagt er: "die klasse Wassermonster kann alles was die Monster können, aber zusätzlich noch schwimmen..." Deshalb bin ich davon ausgegangen das man nicht wieder alles angeben muß. So wie in deinem 1. bsp hatte ich es schon, bis auf die 2. public Mensch() Wozu wäre die denn gut? zum 2, bsp. Gibt man in dem Konstruktor nicht nur das an, was auch vergeben ist( der Beruf soll ja nicht angezeigt werden)? bei mir SuperMensch held1 = new SuperMensch(100, "Superman", "fliegen"); . . public SuperMensch (int dasAlter, string derName, string dieFaehigkeit) wenn ich dann das mit Base probiere, bekomme ich auch Fehlermeldungen: public SuperMensch (int dasAlter, string derName, string dieFaehigkeit) :base(dasAlter, derName, derBeruf) Assets/03_C#_Grundlagen/Scripts/S31ConstructorUndVererbung.cs(57,102): error CS0103: The name `derBeruf' does not exist in the current context wenn ich dann "derBeruf" rausnehme, kommt dies: Assets/03_C#_Grundlagen/Scripts/S31ConstructorUndVererbung.cs(57,78): error CS1729: The type `Mensch' does not contain a constructor that takes `2' arguments Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
SirTreffNix_Dev Geschrieben 21. März 2019 Melden Share Geschrieben 21. März 2019 Mit der Zeile: public SuperMensch (int dasAlter, string derName, string dieFaehigkeit) :base(dasAlter, derName, derBeruf) übergibst du dasAlter, derName, derBeruf an den Konstruktor der Basisklasse (durch die Verwendung von :base(dasAlter,derName,derBeruf) der in diesem Fall 3 Argumente erwartet. "derBeruf" ist aber unbekannt, da an den Konstruktor von SuperMensch die Variablen "dasAlter, derName, dieFaehigkeit" übergeben werden. Das sagt die folgende Fehlermeldung aus: Zitat Assets/03_C#_Grundlagen/Scripts/S31ConstructorUndVererbung.cs(57,102): error CS0103: The name `derBeruf' does not exist in the current context Wenn du dann wie von dir Beschrieben "derBeruf" wieder raus nimmst, werden wieder nur zwei Argumente an den Konstruktor der Basisklasse übergeben. Dadurch erhälst du die folgende Fehlermeldung: Zitat Assets/03_C#_Grundlagen/Scripts/S31ConstructorUndVererbung.cs(57,78): error CS1729: The type `Mensch' does not contain a constructor that takes `2' arguments In dem Screenshot aus deinem Tutorial sind gar keine Konstruktoren angegeben wodurch das "Problem" nicht entsteht. Der Konstruktor wird immer aufgerufen, wenn ein neues Objekt vom Typ dieser Klasse erstellt wird über z.B. SuperMensch test = new SuperMensch() Es besteht die Möglichkeit für jede Klasse mehrere Konstruktoren anzugeben. Dann wird je nachdem welche Parameter übergeben werden der richtige "ausgewählt". Wenn du nun über public Mensch() { } einen weiteren Konstruktor der Klasse Mensch hinzufügst, kann ein Objekt vom Typ Mensch entweder über Mensch test1 = new Mensch() // ohne Argumente oder mit Mensch test2 = new Mensch(100, "Superman", "fliegen") // mit Argumente erstellt werden. Da in diesem Fall, die Klasse Mensch keine Argumente zwingend erwartet (es wird ja entweder der Konstruktor ohne Argumente aufgerufen oder eben mit drei Argumenten) kann deine Klasse SuperMensch von Mensch erben ohne Argumente zu übergeben. Das ganze ist auch ganz gut unter: https://docs.microsoft.com/de-de/dotnet/csharp/programming-guide/classes-and-structs/using-constructors beschrieben. Ich hoffe ich konnte es einigermaßen verständlich beschreiben. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
amdbuster Geschrieben 21. März 2019 Melden Share Geschrieben 21. März 2019 Ich glaub langsam kapier ichs. Ich müßte also für jede neue Unterklasse auch einen neuen Konstruktor anlegen, wenn ich andere Werte übernehmen will. Macht das ganze ja nicht wirklich einfacher. Nun habe ich einen mit "public Mensch(int dasAlter, string derName){}" angelegt(ohne die Argumente ging es auch nicht), allerdings fehlen die Werte von der Klasse Mensch in der Ausgabe: die Fähigkeit von ist fliegen und dessen Alter beträgt: 0 Es geht nur wenn ich wirklich alles reinschreibe public Mensch(int dasAlter, string derName) { alter = dasAlter; name = derName; } Da sehe ich dann aber nicht, was mir die Vererbung bringen soll. Da kann ich ja gleich in der Klasse alles neu schreiben. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
devandart Geschrieben 21. März 2019 Melden Share Geschrieben 21. März 2019 Wenn Du in einer erbenden Klasse Parameter im Konstruktor übergibst, musst Du diese an die Basisklasse weiterreichen. public class Mensch { protected readonly int alter; public Mensch(int alter) { this.alter = alter; } } public class SuperMensch : Mensch { public SuperMensch(int alter) : base(alter) { } } Statt im Konstruktor kannst Du auch Eigenschaften beim Erzeugen vom Objekt setzen. Dies hat Vor- und Nachteile. public class Mensch { private int alter; private string name; public int Alter { get { return alter; } set { alter = value; } } public int Name { get { return name; } set { name = value; } } } public class SuperMensch : Mensch { } //... irgendwo var superMensch = new SuperMensch() { Alter = 10, Name = "Hans Wurst" }; Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
SirTreffNix_Dev Geschrieben 22. März 2019 Melden Share Geschrieben 22. März 2019 Zitat Da sehe ich dann aber nicht, was mir die Vererbung bringen soll. Da kann ich ja gleich in der Klasse alles neu schreiben. Die Vererbung bietet dir ja die Möglichkeit auch Methoden der Klasse von der du erbst zu nutzen. z.B. könntest du in deiner Klasse "Mensch" Variablen für Lebenspunkte, Erfahrungspunkte usw. haben. Deine Klasse Supermensch hat dann z.B. Variablen und Methoden für Superkräfte die gewisse Dinge tun. Deine Klasse Mensch hat aber z.B. bereits Methoden um Lebenspunkte hinzuzufügen, abzuziehen usw. Diese müsstest du dann in der Klasse Supermensch nicht noch einmal schreiben sondern könntest die Methode aus der Basisklasse verwenden. Solltest du dann doch einmal eine Methode aus der Basisklasse "Mensch" ändern wollen in "Supermensch" kannst du diese "überschreiben" oder "erweitern". Override - https://docs.microsoft.com/de-de/dotnet/csharp/language-reference/keywords/override 1 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 22. März 2019 Melden Share Geschrieben 22. März 2019 vor 22 Stunden schrieb amdbuster: Da sehe ich dann aber nicht, was mir die Vererbung bringen soll. Da kann ich ja gleich in der Klasse alles neu schreiben. Es gibt genau zwei Gründe für Vererbung: Polymorphismus, wie bereits erwähnt, und Verhinderung von Code-Duplizierung. "Guter Code" definiert sich nicht dadurch, dass er funktioniert, sondern durch Meta-Qualitäten. Das wären so Sachen wie Lesbarkeit, Wartbarkeit, Modularität, Robustheit. Code-Duplizierung, also "alles neu schreiben", bedeutet schlechte Robustheit. Denn wenn du dann feststellst, dass dein "Mensch" doch etwas anders funktionieren soll, darfst du erstmal an beiden Stellen, an denen du definiert hast, wie ein Mensch funktioniert, deinen Code abändern. Wenn du dann noch mehr "Mensch"-Klassen hast, dann steigt dein Änderungsbedarf proportional. Wenn du dann vergisst, eine der Änderungen zu machen, hast du direkt Fehlerpotential des Todes. Trotz alledem muss ich sagen: Ich baue selber ungefähr niemals Vererbungshierachien, wenn es um Komponenten in Unity geht. Denn Tatsache ist, dass alles, was du mit Vererbungshierarchien bauen kannst, auch mit Komponenten gebaut werden kann. Komponentenklassen, die voneinander erben, sind nie nötig und daher selten sinnvoll. Und Vorteile gibt's auch noch dazu. Von daher würde ich auf jeden Fall empfehlen zu lernen, wie Vererbung funktioniert und was man damit macht, aber in Unity für Komponenten verwenden... eher nicht. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.