Thursday, January 11. 2007Generics - mühsame UmstellungTrackbacks
Trackback specific URI for this entry
No Trackbacks
Comments
Display comments as
(Linear | Threaded)
Nun ja, überleg dir mal folgendes:
Eine abstrakte Klasse A hat eine Methode Copy, die A zurückgibt. Klasse B ist von A abgeleitet und will dass Copy B zurückgibt - vor allem um die Methode ohne Rumcasterei nutzen zu können wenn Methoden von B benutzt werden. Dank Generics kann man das an manchen Stellen umgehen, aber an manchen halt nicht..
Ok dann andersherum: Wofür erbt dann B von A?
Das macht ja nur Sinn, wenn Du ... a) ... Anwendungen folgender Art im Sinn hast: A b = new B(); Dann musst Du aber, wenn Du explizit Die copy-Methode von B nutzen möchtest, auch casten. Viel schlimmer wird es vor allem dann, wenn copy in B ein Objekt einer Klasse zurückgeben soll, die nicht in einer Vererbungshierarchie mit dem Rückgabewert von A::copy() steht. b) ... Funktionalität wiederverwenden möchtest. Es ist fraglich, ob unter diesem Blickpunkt guten Gewissens die Aussage getroffen werden kann, dass B ein A ist.
Nun ja, ein Beispiel aus der Praxis:
CODE: class CollectionBase<t> { public CollectionBase</t><t> Copy() {} }</t> Davon abgeleitet ist folgende Klasse: CODE: class MyItemCollection : CollectionBase<myitem> { public override CollectionBase</myitem><myitem> Copy() {} public void DoWork() {} }</myitem> Wenn ich also irgendwo die Methode Copy verwenden wollte, müsste ich von CollectionBase<myitem> auf MyItemCollection casten um die Methode DoWork() benutzen zu können..</myitem>
Nun ja, vielleicht ist das Beispiel nicht klar geworden - es wird kein Verhalten umdefiniert!
Die Copy()-Methode hat was in der CollectionBase zu suchen, wenn sie dort benutzt wird Außerdem wäre nicht von CollectionBase zu erben ziemlich blöd, da man dann Code-Duplikate ohne Ende hat - in CollectionBase ist halt die Collection an sich definiert.. Bekannt dürfte ja auch die Methode Clone vom Interface ICloneable sein. Dort wird immer nur ein object zurückgegeben obwohl der Typ der aktuellen Instanz korrekter wäre.
Ja wie gesagt stellt sich bei sowas schon die Frage, ob MyItemCollection von CollectionBase erben sollte, wenn Verhalten umdefiniert wird, bzw ob die copy() Methode etwas in der CollectionBase zu suchen hat, wenn ihr Verhalten für die Unterklassen offenbar nicht gleich ist.
Also ein anderes Objekt zurückzugeben als in der Oberklasse angegeben ist meiner Ansicht nach schon eine Umdefinierung des Verhaltens.
Ich gebe ja kein anderes Objekt zurück sondern nur eine Spezialisierung. Weiterhin besteht das Problem ja nicht nur bei Klassenvererbung sondern auch bei Interface-Implementierung..
Wie sollte man denn deiner Ansicht so ein Problem lösen?
Covariant return types brauchst Du doch nur, wenn eine nicht abstrake Klasse von einer anderen nicht abstrakten Klasse erbt.
Das ist aber definitiv schlechtes Design (siehe "Object-oriented Design Heuristics" von Arthur J. Riel).
äh irgendwie hat der da eben was verschluckt. Der Text sollte folgendermaßen aussehen:
Ja, sie ist aber keine Spezialisierung, weil CollectionBase intern etwas hat wie LinkedList<Object> und MyItemCollection<MyItem> damit nichts anfangen kann und ein eigenes LinkedList braucht.
Nun ja, es ist egal, um ich intern ein Array of Object habe oder LinkedList<object> oder ArrayList
Aus diesem Grund ist meiner Meinung MyItemCollection eine Spezialisierung von CollectionBase.</object>
Ja, sie ist aber keine Spezialisierung, weil CollectionBase intern etwas hat wie LinkedList und MyItemCollection damit nichts anfangen kann und ein eigenes LinkedList braucht.
Eine MyItemCollection ist eine Spezialisierung von CollectionBase, die anstatt Objects nur MyItems verwalten soll.
Ok, dann anders gefragt: Die Klasse CollectionBase speichert sicherlich irgendwie Objects, oder? Was machst Du denn mit denen, wenn Du MyItemCollection implementierst?
Da man die copy-Methode, wenn sie in jeder Unterklasse anders definiert ist, eh nicht ohne Cast polymorph nutzen kann, kann sie auch aus der Oberklasse entfernt und nur in den Unterklassen definiert werden.
Ganz abgesehen davon nehme ich stark an, dass CollectionBase genau dann abgeleitet werden soll, wenn neue Funktionalität hinzugefügt werden soll, und nicht, um ihr beizubringen, Objekte eines anderen Typs zu enthalten.
Spezialisierungen eines Typs zu enthalten und dementsprechend neue Funktionalität einzubauen ist aber genau hier erwünscht.
Und Copy ist in der Unterklasse nicht anders definiert sondern gibt nur eine Spezialisierung zurück..
Nein, es ist nicht egal, denn es geht hier darum, ob MyItemCollection eine CollectionBase ist, und das trifft meiner Ansicht nach nicht zu, weil Du eigentlich überhaupt kein gleiches Verhalten hast, sofern Du keine Generics einsetzt. Denn die eine Collection arbeitet auf Objects, die andere eben nicht.
Und falls Du Generics nutzt, brauchst Du weder diese Vererbungsbeziehung noch covariant return types.
Ok, wenn ich dich mit der MyItemCollection nicht überzeugen kann: wie steht es mit ICloneable?
siehe http://msdn2.microsoft.com/en-us/library/system.icloneable.aspx
Hat nur eine Funktion: CODE: Object Clone ()
|
QuicksearchStatische SeitenCalendar
KategorienCreative CommonsBlog AdministrationShow tagged entries 26c3 cisco Coding darmstadt dhcp dotNet fachschaft Failover Foto Fun Gadgets Games General gremienarbeit Hacking Handy Hardware Internet Java Kino LAN-Party Linux Microsoft netzwerk Office openldap PHP planspiel Redundanz Server staub studierende Studium stupa switch TV twitter Verwaltung Virtual Server Wahlen Windows Work ältestenrat |
|||||||||||||||||||||||||||||||||||||||||||||||||