PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C#] Unklarheiten Vererbung und Cast


Buzzler
2010-05-24, 12:05:59
Zur Erklärung;
FindNearestObjectToClean() gibt eine Instanz der Klasse InteractionInstance zurück (ach nee...)
CleaningInstance ist abgeleitet von InteractionInstance und ist unverändert bis auf zwei override Methoden (eine Test() Methode, die checkt, ob eine andere Methode ausgeführt werden darf und eine CallBack-Methode, um die es mir eigentlich geht)

Wenn Folgendes funktioniert (instance also nicht null ist)
InteractionInstance instance = this.Actor.LotHome.FindNearestObjectToClean(this.Actor, this.Autonomous, this.mBlockCounts) as InteractionInstance;
wieso funktioniert das hier dann nicht? (instance ist danach immer null)
CleaningInstance instance = this.Actor.LotHome.FindNearestObjectToClean(this.Actor, this.Autonomous, this.mBlockCounts) as CleaningInstance;
Müsste CleaningInstance, weil es aus InteractionInstance abgeleitet ist, nicht auch überall da funktionieren, wo InteractionInstance funktioniert? Ich hab da wohl was falsch verstanden, aber was?

Demirug
2010-05-24, 12:16:34
Was du hier versuchst ist ein Upcast. Da C# als .Net Sprache aber strong typed ist darf man nur upcasten auf einen Type dem das Objekt auch entspricht. Wenn das Objekt als nur InteractionInstance Type ist darf man es nie auf ein CleaningInstance Type casten. Das funktioniert nur wenn das Objekt vom Type CleaningInstance, oder einem davon abgeleiteten Type, ist.

Im Allgemeinen sollte man upcasts aber sowieso vermeiden und das Problem durch virtuelle Methoden oder interfaces lösen.

Buzzler
2010-05-24, 12:44:47
@Demirug: Ok, danke für die Erklärung. Ich könnte FindNearestObjectToClean() jetzt umgehen und mir eine Methode schreiben, die mir ein CleaningInstance Objekt zurückgibt.

Dabei stellt sich mir aber gleich die nächste Frage: Könnte ich einer Methode, die als Parameter ein Objekt vom Typ InteractionInstance erwartet (ggfs. mit explizitem Cast) ein Objekt vom Typ CleaningInstance übergeben? (Wäre dann entsprechend doch ein Downcast.) Welche Methoden würden dann aufgerufen, die der Basisklasse oder die von meiner abgeleiteten Klasse?
Obwohl, ich sehe gerade, dass die Methode, der das dann übergeben wird, ein Interface als Parameter hat. Ist also eine akademische Frage. Interessiert mich aber trotzdem.

Und ja, ich würde es auch bevorzugen, wenn da überall nur mit Interfaces gearbeitet würde. Ist aber nicht meine Code-Basis, sondern die von Sims3. Insgesamt wirkt die auf mich "handwerklich" gut gemacht, gibt aber auch ein paar Stellen, bei denen z.B. keine Interfaces benutzt werden, obwohl es entsprechende Interfaces schon gibt oder besonders schicke Stellen, bei denen der entsprechende Coder unbedingt schlauen Code schreiben musste...

Monger
2010-05-24, 12:52:36
Welche Methoden würden dann aufgerufen, die der Basisklasse oder die von meiner abgeleiteten Klasse?

Wenn du eine Methode als virtual deklariert hast, und dann in der Unterklasse überschrieben hast - dann diese.

Downcasts funktionieren natürlich auch implizit. Denn jede CleaningInstance ist eine InteractionInstance, aber nicht jede InteractionInstance ist eine Cleaning instance...

Wenn du einen Upcast wirklich brauchst, macht es evtl Sinn, vorher erstmal auf den Typus zu prüfen.


Ist aber nicht meine Code-Basis, sondern die von Sims3.
Nur mal aus Neugier: hat Sims3 eine .NET Api?!?
Oder wovon redest du gerade?

Demirug
2010-05-24, 12:58:41
Nur mal aus Neugier: hat Sims3 eine .NET Api?!?
Oder wovon redest du gerade?

Sims benutzt .Net als Script System. Und bevor die Frage auch noch kommt. Auch auf den Konsolen. Wie das genau funktioniert darf ich hier aber nicht verraten.

Buzzler
2010-05-24, 13:30:05
Wenn du eine Methode als virtual deklariert hast, und dann in der Unterklasse überschrieben hast - dann diese.
Jetzt wird es hässlich: Das wird aber wie die Zugriffsbeschränkungen nur zur Compile-Zeit überprüft und nicht zur Laufzeit, oder?

Downcasts funktionieren natürlich auch implizit. Denn jede CleaningInstance ist eine InteractionInstance, aber nicht jede InteractionInstance ist eine Cleaning instance...
Prinzipiell ist mir das eigentlich auch klar. Dass das im Ursprungsposting Geschriebene nicht funktionieren kann, hätte mir eigentlich auch klar sein müssen, aber im Hinterkopf spukte irgendwie rum, dass ich ja gar nicht viel geändert habe. ;)

Wenn du einen Upcast wirklich brauchst, macht es evtl Sinn, vorher erstmal auf den Typus zu prüfen.
Hmm, soll man solche Prüfungen nicht vermeiden wie die Hölle, weil man dann immer Probleme kriegt, wenn zusätzliche Typen dazu kommen?

Nur mal aus Neugier: hat Sims3 eine .NET Api?!?
Hat Demirug ja schon beantwortet. Läuft in .NET2.0 und praktisch der gesamte Code bis auf die Grafikengine liegt in ein paar unverschlüsselten DLLs, die man sich ohne Weiteres mit dem Red Gate's .NET Reflector anschauen kann und in eigenen Projekten referenzieren kann. Das im Einzelnen dann zu begreifen, ist dann wieder so eine Sache, zumindest für mich. Da es halt Sims3 ist, gibt es zwar viele Leute, die Klamotten und Möbel und sowas machen und auch mit XML-Mods (die praktisch jeder in 5 Minuten selber machen kann) wird man praktisch zugeschissen, aber Skript-Modder gibt es nur eine Handvoll, weswegen man bei Sims3-Skript-spezifischen (Verständnis-)Problemen meistens allein da steht.

Im Endeffekt setze ich mich übrigens damit auseinander, weil es mir Spaß macht und ich dabei lerne. Ist halt was Anderes, als bei Null anzufangen, nur seinen eigenen Code zu haben, den man kennt und popelige Programme zu schreiben, die es tausendmal besser als Freeware im Internet gibt.

Edit: Bevor ich jetzt wieder zig neue Methoden schreibe: Wäre es im vorliegenden Fall nicht am Naheliegendsten, die abgeleitete Klasse mit einem Konstruktor zu versehen, der als Parameter ein Objekt der Basisklasse aufnimmt?

Monger
2010-05-24, 13:56:17
Jetzt wird es hässlich: Das wird aber wie die Zugriffsbeschränkungen nur zur Compile-Zeit überprüft und nicht zur Laufzeit, oder?

Wenn du eine Methode mit der selben Signatur in der Unterklasse wie in der Oberklasse hast, wird der Compiler dich zumindest warnen. Du musst dann entweder die Methode als Überladen oder Überschreiben markieren...

So mal ganz grundsätzlich: ein Cast verändert ein Objekt ja in keinster Weise. Ob du jetzt dein Objekt als X oder als Y deklarierst, ändert überhaupt nix an dem, was passiert wenn du darauf eine Methode aufrufst.

Die ganze Casterei ist einzig und allein zur Compilezeit relevant. Das ist nur zu deinem Komfort, damit deine Tippfehler nicht erst zur Laufzeit zur Exception führen.


Hmm, soll man solche Prüfungen nicht vermeiden wie die Hölle, weil man dann immer Probleme kriegt, wenn zusätzliche Typen dazu kommen?

Schon richtig. Deshalb solltest du auch Upcasts ganz allgemein vermeiden. Ich sag das nur, weil ich auch schon gesehen habe, wie jemand konsequent per Try/Catch alle ClassCastExceptions geschluckt hat. Wie ein Cast geht, weiß interessanterweise jeder Anfänger - aber dass man Objekte auch fragen kann ob sie vom Typ XY sind, das vergessen viele. Manchmal ist es sicherer, erst zu fragen: "Bist du vom Typ x? Okay, dann caste auf x."


Edit: Bevor ich jetzt wieder zig neue Methoden schreibe: Wäre es im vorliegenden Fall nicht am Naheliegendsten, die abgeleitete Klasse mit einem Konstruktor zu versehen, der als Parameter ein Objekt der Basisklasse aufnimmt?
Zumindest von der Signatur her scheint mir das eigentlich ein Fall für Generics zu sein. Sowas à la:


FindNearestObjectToClean<T>(Actor, Autonomous, mBlockCounts) as T where T:InteractionInstance

PatkIllA
2010-05-24, 13:59:31
Jetzt wird es hässlich: Das wird aber wie die Zugriffsbeschränkungen nur zur Compile-Zeit überprüft und nicht zur Laufzeit, oder?Das passiert schon zur Laufzeit.

Hmm, soll man solche Prüfungen nicht vermeiden wie die Hölle, weil man dann immer Probleme kriegt, wenn zusätzliche Typen dazu kommen?Hängt wohl vom Einzelfall ab, aber das Problem besteht.

edit:
war wohl zu langsam.

@Monger
ein Cast kann ein Objekt(bzw das was deiner Variable zugewiesen wird) schon verändern. Immer dann wenn ein expliziter Cast vorhanden ist. Neben dem Unterschied dass eine Exception auftritt unterscheidet sich ein Cast durch den as operator auch noch dadurch das diese explizte im zweiten Fall nicht benutzt wird.
Außerdem gibt es noch unterschiede bei expliziten Interface implementierungen. Da ist der Typ der Variable schon wichtig.

Monger
2010-05-24, 14:23:04
@Monger
ein Cast kann ein Objekt(bzw das was deiner Variable zugewiesen wird) schon verändern.

Zum Beispiel? Wenn du auf das IConvertible Interface anspielst: wird zwar durchs Casten gerne mal ausgelöst, hat aber eigentlich nicht unmittelbar etwas damit zu tun. Was da intern im .NET Framework an der Stelle passiert, ist sowieso "magic".

Außerdem gibt es noch unterschiede bei expliziten Interface implementierungen. Da ist der Typ der Variable schon wichtig.
Auch dafür würde ich gerne ein Beispiel sehen. Interfaces sind etwas trickreich, weil deren Namensdeklarationen völlig anders aussehen können als die öffentlichen Methoden der implementierenden Klasse. Aber das ändert trotzdem nichts an dem Verhalten der jeweiligen Instanz.

PatkIllA
2010-05-24, 14:29:10
Zum Beispiel? Wenn du auf das IConvertible Interface anspielst: wird zwar durchs Casten gerne mal ausgelöst, hat aber eigentlich nicht unmittelbar etwas damit zu tun. Was da intern im .NET Framework an der Stelle passiert, ist sowieso "magic".
Ich meinte jetzt das explicit keyword. Ich wollte auch mehr darauf hinaus, dass ein cast mit "(ClassName)variable" was anderes ist als "variable as ClassName".

Auch dafür würde ich gerne ein Beispiel sehen. Interfaces sind etwas trickreich, weil deren Namensdeklarationen völlig anders aussehen können als die öffentlichen Methoden der implementierenden Klasse. Aber das ändert trotzdem nichts an dem Verhalten der jeweiligen Instanz.

using System;

namespace CastTest
{
interface MyInterface
{
void MyMethod();
}

class MyClass : MyInterface
{
public void MyMethod()
{
Console.WriteLine("foo");
}

void MyInterface.MyMethod()
{
Console.WriteLine("bar");
}
}

class Program
{
static void Main(string[] args)
{
MyClass a = new MyClass();
a.MyMethod();
MyInterface b = a;
b.MyMethod();
}
}
}
Das gibt folgendes aus:foo
barDer typ der Variable ist dabei also nicht egal

Buzzler
2010-05-24, 14:57:08
Ich hab in Zwischenzeit übrigens rausgefunden, dass es an anderer Stelle noch ein CreateInstanceWithCallBacks() gibt. :freak: Hätte ich mir also alles sparen können. Das "NearestObject" muss ich dann zwar selber finden, aber das dürfte kein großes Problem sein.

Macht diesen Thread allerdings nicht sinnlos, denn mir geht es ja um's grundsätzliche Verstehen.

Wenn du eine Methode mit der selben Signatur in der Unterklasse wie in der Oberklasse hast, wird der Compiler dich zumindest warnen. Du musst dann entweder die Methode als Überladen oder Überschreiben markieren...
Ich muss wohl doch erklären, was ich mit "hässlich" meine. ;) Also meine Methoden haben den override Modifikator, die Methoden der Basisklasse im ursprünglichen Code sind allerdings nicht mit virtual gekennzeichnet, so dass ich sie in der abgeleiteten Klasse eigentlich nicht überschreiben darf. Ich habe jetzt bei den Bibliotheken, die ich in meinem Projekt referenziere, die entsprechenden Methoden mit dem virtual Modifikator versehen. Diese Bibliotheken sieht aber nur mein Projekt zur Compile-Zeit. Die Bibliotheken, die das Spiel zur Laufzeit benutzt, rühre ich nicht an.

Ich sag das nur, weil ich auch schon gesehen habe, wie jemand konsequent per Try/Catch alle ClassCastExceptions geschluckt hat.
Autsch! :eek: Bei Sims3 muss man generell ein bisschen vorsichtig damit sein, Exceptions zu fangen, wenn man nicht sicher ist, dass man sie selbst verursacht hat. Wenn die bei einer ausgiebig getesteten Mod noch auftreten, ist das meistens ein Zeichen dafür, dass Sims3 mal wieder einen Spielstand gefressen hat und da Referenzen ins Leere zeigen, bei denen die Entwickler selbst vorgesehen haben, dass sie immer auf gültige Objekte zeigen müssen.

Manchmal ist es sicherer, erst zu fragen: "Bist du vom Typ x? Okay, dann caste auf x."
Naja, ich mache es anders herum. Ich frage nach dem Cast, ob das Objekt gültig ist. Muss man sich beim Sims3-Code sowieso angewöhnen, weil da ein Haufen Referenzen ausdrücklich auf null zeigen dürfen und viele Methoden im Zweifelsfall null zurückgeben.

Zumindest von der Signatur her scheint mir das eigentlich ein Fall für Generics zu sein.{...}
Klingt sinnvoll, kann ich in dem Fall allerdings nicht machen, weil das eine EA-Methode ist. :)

Das passiert schon zur Laufzeit.
Was meinst Du mit "schon"?

PatkIllA
2010-05-24, 15:00:42
Was meinst Du mit "schon"?Nur das es nicht zur Compilezeit passiert. War eigentlich nur ein Füllwort.

Buzzler
2010-05-24, 15:14:57
Nur das es nicht zur Compilezeit passiert. War eigentlich nur ein Füllwort.
Meinen wir jetzt das Gleiche? Wenn ich in einer abgeleiteten Klasse eine Methode mit override überschreiben will, die in der Basisklasse nicht mit virtual gekennzeichnet ist, kriege ich einen Compiler-Fehler, der besagt, dass ich das nicht darf und das Schlüsselwort "new" benutzen soll.

PatkIllA
2010-05-24, 15:20:24
Ich meinte jetzt die Frage wann überprüft wird welche konkrete Implementierung aufgerufen wird.
Welche Implementierung aufgerufen wird entscheidet sich zur Laufzeit. Der Compiler stellt lediglich sicher, dass eine entsprechende Implementierung existiert.

Buzzler
2010-05-24, 15:40:31
Welche Implementierung aufgerufen wird entscheidet sich zur Laufzeit.
Ok, jetzt ist klar. Das wusste ich im Prinzip schon. Die Gretchenfrage ist ob das Framework dann danach geht, ob es eine override Methode gibt oder danach, ob die Methode der Basisklasse mit virtual gekennzeichnet ist. Kann man wahrscheinlich nicht mit Sicherheit sagen und sich sowieso nicht drauf verlassen. Ich sagte aber schon, dass es hässlich ist und ich es zum Glück auch gar nicht ausprobieren muss? ;)

PatkIllA
2010-05-24, 15:44:25
Du kannst ja auch eine Methode gleichen Names in der abgeleiteten Klasse implementieren, die nicht mit override gekennzeichnet ist. Das gibt dann "nur" eine Warnung zur Compilezeit und welche Methode aufgerufen wird hängt dann vom Typ der Variablen ab.

Monger
2010-05-24, 16:33:42
Ok, jetzt ist klar. Das wusste ich im Prinzip schon. Die Gretchenfrage ist ob das Framework dann danach geht, ob es eine override Methode gibt oder danach, ob die Methode der Basisklasse mit virtual gekennzeichnet ist. Kann man wahrscheinlich nicht mit Sicherheit sagen und sich sowieso nicht drauf verlassen. Ich sagte aber schon, dass es hässlich ist und ich es zum Glück auch gar nicht ausprobieren muss? ;)
Ich will dafür meine Hand nicht ins Feuer legen, aber: wenn du eine Methode überschreiben könntest, obwohl sie in der Oberklasse nicht als "virtual" gekennzeichnet ist, wäre das eine schwere Sicherheitslücke. Damit könntest du beliebigen Code in eine Klasse einführen.
Mir ist auch ehrlich schleierhaft, warum ein Überschreiben ohne dazu passendes Virtual nur eine Warnung, und keinen Fehler ausgibt, immerhin ist das eine schwere Interface Änderung.
Deshalb: ich glaube nicht, dass dein Mod gegen die unveränderten Sims 3 Dlls lauffähig wäre. Zumindest nicht so wie erwartet...


Ich meinte jetzt das explicit keyword. Ich wollte auch mehr darauf hinaus, dass ein cast mit "(ClassName)variable" was anderes ist als "variable as ClassName".

Ich muss zugeben: da habe ich ne Bildungslücke. Bin ja ohnehin eher auf VB.NET abonniert, aber der zweite Cast Typus ist mir unbekannt.



...
class Program
{
static void Main(string[] args)
{
MyClass a = new MyClass();
a.MyMethod();
MyInterface b = a;
b.MyMethod();
}
}
}
Das gibt folgendes aus:foo
bar
Das ist genau genommen auch eher ein Namensraum Problem. Du hast hier zwei verschiedene Typen, die beide genau die selbe Methodensignatur besitzen. Das ist aber auch eine Besonderheit von C#, dass die Methodenimplementation genauso heißen muss wie das dazugehörige Interface. In VB.NET geht auch folgendes:


Public Interface MyInterface
Sub DoAlpha()
End Interface

public Class MyClass
Implements MyInterface

public Sub Meh() implements MyInterface.DoAlpha

End Sub
End Class

Public Class Program
Public sub Main()
Dim x as New MyClass()
x.Meh()
Dim y as MyInterface = x
y.DoAlpha()
End Sub
End Class


Das ist halt eine Konsequenz von Polymorphismus: das selbe Objekt kann - je nach Betrachtungswinkel - eine vollkommen andere Gestalt haben. Aber ob ich jetzt meinen Hund als Säugetier oder als Vierbeiner deklariere, ändert nichts daran dass er ist was er ist.

Buzzler
2010-05-24, 17:09:03
Ich will dafür meine Hand nicht ins Feuer legen, aber: wenn du eine Methode überschreiben könntest, obwohl sie in der Oberklasse nicht als "virtual" gekennzeichnet ist, wäre das eine schwere Sicherheitslücke. Damit könntest du beliebigen Code in eine Klasse einführen.
Ist was dran. Die Zugriffsbeschränkungen werden zur Laufzeit aber definitiv nicht geprüft (Oder kann man das evtl. beim Compiler einstellen?). Ist das im Endeffekt nicht eine genauso große Sicherheitslücke? Spätestens wenn man Delegaten ändern würde?

Monger
2010-05-24, 17:25:55
Ist was dran. Die Zugriffsbeschränkungen werden zur Laufzeit aber definitiv nicht geprüft (Oder kann man das evtl. beim Compiler einstellen?). Ist das im Endeffekt nicht eine genauso große Sicherheitslücke? Spätestens wenn man Delegaten ändern würde?
Normalerweise wird beim Laden einer Assembly erstmal geprüft, ob die signaturmäßig mit dem zusammenpasst was man erwartet. Ist die Assembly entweder gar nicht oder nicht in der erwarteten Form da, wird eine "AssemblyNotFound" Exception geworfen.

Sowas würde ich jetzt auch bei dir vermuten. Oder (noch schlimmer): es failed überhaupt nicht, weil du eine Methode die zwar als "Override" gekennzeichnet ist, aber dazu kein passendes Virtual. Da das aber nur eine Warnung produziert, wird in deinem Code eben grundsätzlich nur die Methode der Oberklasse aufgerufen, aber nie die überschriebene Methode. Das würdest du erst merken, wenn sich die entsprechende Methode nicht so verhält wie gedacht.

PatkIllA
2010-05-24, 18:35:49
Ich muss zugeben: da habe ich ne Bildungslücke. Bin ja ohnehin eher auf VB.NET abonniert, aber der zweite Cast Typus ist mir unbekannt.
VB .NET kenne ich wiederum kaum.
Das zweite scheint TryCast zu entsprechen.
http://msdn.microsoft.com/de-de/library/zyy863x8.aspx

Buzzler
2010-05-24, 19:09:49
Normalerweise wird beim Laden einer Assembly erstmal geprüft, ob die signaturmäßig mit dem zusammenpasst was man erwartet. Ist die Assembly entweder gar nicht oder nicht in der erwarteten Form da, wird eine "AssemblyNotFound" Exception geworfen.
Was meinst Du jetzt? Wer oder was prüft das?

Sowas würde ich jetzt auch bei dir vermuten. Oder (noch schlimmer): es failed überhaupt nicht, weil du eine Methode die zwar als "Override" gekennzeichnet ist, aber dazu kein passendes Virtual. Da das aber nur eine Warnung produziert, wird in deinem Code eben grundsätzlich nur die Methode der Oberklasse aufgerufen, aber nie die überschriebene Methode. Das würdest du erst merken, wenn sich die entsprechende Methode nicht so verhält wie gedacht.
Letzteres scheint der Fall zu sein. Hab es jetzt interessehalber doch mal Methode Brutal ausprobiert was da passiert und an entsprechender Stelle eine override Methode geschrieben, die schlicht eine Exception wirft. Verhält sich im Spiel völlig normal. Ich muss jetzt nicht nochmal sagen, dass ich den Plan wie im Ursprungsposting dargestellt längst aufgegeben habe, oder?

Mit Zugriffsbeschränkungen meinte ich aber den public/protected/private-Kram. Bei frühen Versionen von Sims3 war es z.B. so, dass praktisch alles, was mit dem Alter zu tun hatte (selbst die accessor methods ohne set!), protected oder private war. Nachdem ich dann im Code eines anderen Modders gesehen habe, wie er auf ein protected member lockerleicht zugegriffen hat, hat der mir erzählt, dass er schlicht die Bibliothek, mit der er arbeitet, entsprechend geändert hat und das zur Laufzeit nicht geprüft wird. Hab ich dann selbst nachgemacht, also nach MSIL dekompiliert, die entsprechenden Modifier geändert und rekompiliert (wie gesagt nur bei dem, was ich benutze, nicht bei dem, was das Spiel benutzt). Lief danach im Spiel, als wäre das alles schon immer public gewesen.

Buzzler
2010-05-26, 14:18:16
Ich hab nochmal zwei Verständnisfragen.

Gegeben ist eine abstrakte Klasse
public abstract class InteractionDefinition<TActor, TTarget, TInteraction> : InteractionDefinition where TActor: class, IActor where TTarget: class, IGameObject where TInteraction: InteractionInstance, new()

Hab bei MSDN die Erklärung zu generischen Klassen gelesen, raffe das aber nicht. Das "Generische Klassen, die von offenen konstruierten Typen erben, müssen Einschränkungen angeben, die den Einschränkungen des Basistyps übergeordnet sind oder diese implizieren." sagt mir z.B. gar nichts.

Kann mir jemand erklären, wie das mit den generischen Typen zu verstehen und vor allem wie im o.a. Fall die Syntax zu lesen ist?

Wie kann ich die abstrakte Klasse als Paramter einer Methode übergeben? Sprich, welche Syntax muss ich da benutzen?

del_4901
2010-05-26, 14:21:08
http://msdn.microsoft.com/de-de/library/6b0scde8%28VS.80%29.aspx

Buzzler
2010-05-26, 14:46:42
http://msdn.microsoft.com/de-de/library/6b0scde8%28VS.80%29.aspx
Ok, danke, habs verstanden.

Wie (wenn überhaupt) kann ich das jetzt aber als Parameter übergeben? Im Prinzip wäre der Typ wenn ich das richtig verstanden habe im vorliegenden Fall

InteractionDefinition<IActor, IGameObject, InteractionInstance>

Geht aber in dem Fall nicht, weil InteractionInstance selbst auch abstrakt ist, selbst in einer weiteren abstrakten Klasse generisch abgeleitet wird, welche dann nochmal abstrakt, generisch abgeleitet wird... Danach kommen dann endlich nicht-abstrakte, nicht-generische Implementierungen. Nur weiß ich nicht, welche dieser Klassen ich beim Aufruf an der Backe habe. Darum geht es ja gerade.

Monger
2010-05-26, 15:29:17
Geht aber in dem Fall nicht, weil InteractionInstance selbst auch abstrakt ist, selbst in einer weiteren abstrakten Klasse generisch abgeleitet wird, welche dann nochmal abstrakt, generisch abgeleitet wird... Danach kommen dann endlich nicht-abstrakte, nicht-generische Implementierungen. Nur weiß ich nicht, welche dieser Klassen ich beim Aufruf an der Backe habe. Darum geht es ja gerade.
Dann ist die Methode halt Blödsinn, weil da steht nunmal: nur Klassen erlaubt, die einen parameterlosen Konstruktor besitzen.

Wahrscheinlich instanziieren sie auf die Weise intern eine Klasse, und brauchen dafür eben einen Konstruktor. Ist natürlich einfacher zu implementieren, nimmt dir aber natürlich die Möglichkeit zur Abstraktion.

Buzzler
2010-05-26, 17:00:34
Dann ist die Methode halt Blödsinn{...}
Danke, das hab ich jetzt gebraucht. ;)

Ist natürlich einfacher zu implementieren, nimmt dir aber natürlich die Möglichkeit zur Abstraktion.
Da will man schon brav sein und eine der wichtigsten und elegantesten Grundlagen der objektorientierten Programmierung nutzen und endet damit, endlos Typabfragen zu machen, um in unterschiedliche Typen zu casten und dann eine Methode aufzurufen, die die Typen sowieso alle ganz identisch an die x Stufen darüber liegende Basisklasse weiterreichen. Wenn ich dabei nicht wieder Einiges gelernt hätte oder zumindest deutlich besser verstehen würde als vorher, könnte ich mich glatt ärgern, Stunden mit etwas zugebracht zu haben, was ich nach jetzigem Stand in fünf Minuten machen könnte.