Erben von mehreren Klassen

  • Für alle die wissen möchte wofür ich das brauche.

    Ich wollte die UIButton-Klasse erweitern, sprich das UIButton weitere Funktionalitäten haben soll von einer anderen selbstgeschriebenen Klasse die relativ viele Funktionen hat.
    Da hatte ich mir gedacht, fertige eine neue Klasse an, die sowohl von UIButton als auch der eigenen Klasse alles erbt. Normal könnte ich ja einfach die selbstgeschriebene Klasse von UIButton erben lassen.
    Aber diese erbt bereits auch von einer anderen Kontrollklasse.

    Grob sieht es also so aus:

    [Kontrollklasse] -- verbt --> [selbstgeschriebene Klasse1]--- vererbt ---> [Meine selbst-
    ------------------------------------------------------------------------------------ geschriebene Klasse
    --------------------------------- [UIButton]----------------------- vererbt ---> die erben sollte]

    aber da es scheinbar nicht so geht, werde ich mir mal eure Tips zu gemüte ziehen und schauen ob ich damit was erreiche!
  • Du erklärst uns nur, was du vor hast.
    Du erklärst uns aber nicht, wofür du das brauchst.

    Konkret: WOZU brauchst du sowohl die Funktionalitäten deiner anderen Klasse UND die des UIButtons?

    Für mich klingt das immer mehr nach einer Category.
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Die UIButton-Funktionalitäten brauche ich, damit das Objekt ebend als Button auf der Visualisierung verwendet werden kann.
    Meine Klasse hat die Funktionalität, dass sie den Status des Buttons bestimmt (Berechnungen) und bei events handlet. da die buttons zt dynamisch
    erzeugt werden, dachte ich mir, wenn ich eine klasse habe die sowohl von uibotton als auch meiner statusklasse erbt, dann kann ich mir bissl was sparen
    und einiges lässt sich dann einfacher handeln, weil ich dann auf beides zugreifen von dem dynamisch erzeugten objekt.
  • uwoan schrieb:

    Die UIButton-Funktionalitäten brauche ich, damit das Objekt ebend als Button auf der Visualisierung verwendet werden kann.
    Meine Klasse hat die Funktionalität, dass sie den Status des Buttons bestimmt (Berechnungen) und bei events handlet. da die buttons zt dynamisch
    erzeugt werden, dachte ich mir, wenn ich eine klasse habe die sowohl von uibotton als auch meiner statusklasse erbt, dann kann ich mir bissl was sparen
    und einiges lässt sich dann einfacher handeln, weil ich dann auf beides zugreifen von dem dynamisch erzeugten objekt.


    dafür ist der button aber nicht zuständig!?
  • gritsch schrieb:

    uwoan schrieb:

    Die UIButton-Funktionalitäten brauche ich, damit das Objekt ebend als Button auf der Visualisierung verwendet werden kann.
    Meine Klasse hat die Funktionalität, dass sie den Status des Buttons bestimmt (Berechnungen) und bei events handlet. da die buttons zt dynamisch
    erzeugt werden, dachte ich mir, wenn ich eine klasse habe die sowohl von uibotton als auch meiner statusklasse erbt, dann kann ich mir bissl was sparen
    und einiges lässt sich dann einfacher handeln, weil ich dann auf beides zugreifen von dem dynamisch erzeugten objekt.

    dafür ist der button aber nicht zuständig!?

    Genau das ist der Punkt.
    Die Funktionalität gehört in einen Controller, der Button ist ein View.
    Das Beides ist vergleichbar mit Adamsäpfeln und Evas Birnen.
    Das gehört nicht zusammengewürfelt sondern getrennt.

    Was dir auf den ersten Blick einfacher aussieht, sieht nur mangels Erfahrung so aus.
    Es verkompliziert tatsächlich alles unnötig.
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • uwoan schrieb:

    Die UIButton-Funktionalitäten brauche ich, damit das Objekt ebend als Button auf der Visualisierung verwendet werden kann.
    Meine Klasse hat die Funktionalität, dass sie den Status des Buttons bestimmt (Berechnungen) und bei events handlet. da die buttons zt dynamisch
    erzeugt werden, dachte ich mir, wenn ich eine klasse habe die sowohl von uibotton als auch meiner statusklasse erbt, dann kann ich mir bissl was sparen
    und einiges lässt sich dann einfacher handeln, weil ich dann auf beides zugreifen von dem dynamisch erzeugten objekt.

    Dafür ist Vererbung der View-Klasse eindeutig der falsche Weg. Unterklassen von UIButton zu bauen, ist nur sehr selten notwendig.

    Wie es gritsch schon angedeutet hat, fallen die beschriebenen Aufgaben nicht in die Zuständigkeit des Buttons. Dafür its der Controller zuständig. Lies Dir aber bitte erstmal etwas zum MVC-Pattern durch, z. B.: developer.apple.com/library/io…oc/uid/TP40002974-CH6-SW1
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:


    Dafür ist Vererbung der View-Klasse eindeutig der falsche Weg. Unterklassen von UIButton zu bauen, ist nur sehr selten notwendig.

    Ich las irgendwo, dass zu häufiges Subclassing eher ein Antipattern sei.
    Im Klassenbrowser stelle ich fest, dass NSTextFieldCell mit seinen 6 Parentklassen schon heftig spezialisiert ist.
    Allerdings scheint es mir auch die einzige Klasse zu sein, die derart oft spezialisiert wurde.
    Ausgenommen den Cells kommt kaum eine Klasse auf mehr als 3 Klassen bis NSObject.

    Wann immer es geht versuche ich, weiterführende Spezialisierungen zu vermeiden.
    (Also bei UI-Elementen, Collections und so weiter.)

    Wenn ich jetzt UNBEDINGT noch die Methode -getObjectsForRange: in einem NSArray brauche, dann lege ich mir dafür keine Subklasse an.
    Ich erweitere NSArray einfach über eine Kategorie um die Methode und fertig is. Die Kategorie packe ich einfach in die Klasse, in der ich diese Methode so UNBEDINGT brauche.
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • macmoonshine schrieb:

    Lucas de Vil schrieb:

    Dann kann eine Klasse also doch von (Klassen)Objekten erben?

    Nein, eine Klasse erbt von einer Klasse nicht von einem Objekt.

    Das ist auch absolut richtig. Klasse und (Klassen-)Objekt sind zwei verschiedene Paar Schuhe. Das eine ist ein Typ, das andere ein Empfänger von Nachrichten. Und Klassenobjekt aus Sicht des Objective-C-Programmierers sind nicht Klassenobjekte im Sinne des RTE. Das kann man auch daran erkennen, dass die Klasse sowohl Instanz-, wie Klassenmethoden kennt, das Klassenobjekt zur Laufzeit wiederum nur die Instanzmethoden kennt, weshalb es immer zwei Klassenobjekte geben muss. Das ist aber wieder etwas anderes als das Klassenobjekt, wie es der Programmierer sieht. Das Klassenobjekt des Programmierers kennt (empfängt) nur Klassenmethoden.

    Das geht bei Objective-C leider etwas durcheinander.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • gritsch schrieb:

    Lucas de Vil schrieb:

    Wenn ich jetzt UNBEDINGT noch die Methode -getObjectsForRange: in einem NSArray brauche, dann lege ich mir dafür keine Subklasse an.

    das würde auch nicht gehen weil NSArray ein Class-Cluster ist!

    Stimmt, das kommt in dem Fall erschwerend hinzu.

    Eigentlich wollte ich ursprünglich UIButton um eine Methode erweitern, aber mir fiel einfach keine sinnvolle Erweiterung für einen Button ein.
    Für das Array ist mir etwas eingefallen, an die Class-Clusterung habe ich dabei natürlich nicht mehr gedacht.

    Amin Negm-Awad schrieb:

    Das eine ist ein Typ, das andere ein Empfänger von Nachrichten. Und Klassenobjekt aus Sicht des Objective-C-Programmierers sind nicht Klassenobjekte im Sinne des RTE. Das kann man auch daran erkennen, dass die Klasse sowohl Instanz-, wie Klassenmethoden kennt, das Klassenobjekt zur Laufzeit wiederum nur die Instanzmethoden kennt, weshalb es immer zwei Klassenobjekte geben muss. Das ist aber wieder etwas anderes als das Klassenobjekt, wie es der Programmierer sieht. Das Klassenobjekt des Programmierers kennt (empfängt) nur Klassenmethoden.

    Das verwirrt mich.
    Klasse = Typ, Objekt = Empfänger von Nachrichten. Okay.
    Klasse = Bauplan im Code, gibts zur Laufzeit nicht mehr.
    Klassenobjekt = Empfänger von Nachrichten, welcher Klassenmethoden ausführt. Ein Klassenobjekt kennt keine Variablen. Es gibt immer nur ein einziges Klassenobjekt je Typ.
    Instanzobjekt = Empfänger von Nachrichten, welcher Instanzmethoden ausführt. Ein Instanzsobjekt kann Instanzvariablen haben. Es gibt beliebig viele Instanzobjekte je Typ.
    Wobei 'Typ' schwierig ist... Es ist ja nachher alles irgendwo nur 'id'.

    So ist meine Sicht der Dinge. Deshalb nehme ich das als Sicht des Programmierers an. Schließlich bin ich nicht die RTE.

    Wie sieht das denn jetzt die RTE?
    Wie kann die RTE einen Bauplan erstellen? Wie kann sie an den Bauplan eines Objekts kommen?

    Ich verstehe es so, dass es mit Eintritt in die RTE keine Klassen mehr gibt. Diese liegen in den .h und .m Dateien rum, auf die das Programm nach dem Kompilieren ja keinen Zugriff mehr haben dürfte.
    Es gibt nur noch jeweils ein Klassenobjekt je Typ und N Instanzobjekte je Typ.

    C-Quellcode

    1. NSString *string /*Instanzobjekt 1*/= [NSString /*Klassenobjekt*/ string];
    2. NSString *name /*Instanzobjekt 2*/ = [NSString /*Klassenobjekt*/ stringWithString:@"Name"];


    Was bringe ich da durcheinander bzw. was handhabt die RTE anders?
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • RegExpressive schrieb:

    Lucas de Vil schrieb:

    Ein Klassenobjekt kennt keine Variablen.
    Ich bin nicht mehr auf dem Laufenden, wie das in Obj-C war, aber wo sind dann die Klassenvariablen (Beispiel: Instanz-Zähler)?

    Es gibt keine Klassenvariablen.
    Und was soll ein Instanzzähler sein?
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Lucas de Vil schrieb:

    Es gibt keine Klassenvariablen.
    Und was soll ein Instanzzähler sein?
    Ein Beispiel für eine Variable, die logisch der Klasse zugeordnet sein muß und nicht jeder einzelnen Instanz.

    So kann man zum Beispiel eine Methode/Funktion haben wollen, die die Anzahl der aktuell existierenden Instanzen dieser Klasse liefert (oder andere ähnliche Gesamt-Informationen). Die Variable dafür muß logischerweise zentral angelegt sein.

    macmoonshine schrieb:

    Gibt es in Objective-C nicht. Du kannst nur statische Variablen wie in C verwenden.
    Schade. Wobei das natürlich funktional äquivalent benutzt werden kann, aber an der Stelle fehlt dann halt die Abstraktion im Code.
  • RegExpressive schrieb:

    Lucas de Vil schrieb:

    Es gibt keine Klassenvariablen.
    Und was soll ein Instanzzähler sein?
    Ein Beispiel für eine Variable, die logisch der Klasse zugeordnet sein muß und nicht jeder einzelnen Instanz.

    So kann man zum Beispiel eine Methode/Funktion haben wollen, die die Anzahl der aktuell existierenden Instanzen dieser Klasse liefert (oder andere ähnliche Gesamt-Informationen). Die Variable dafür muß logischerweise zentral angelegt sein.

    macmoonshine schrieb:

    Gibt es in Objective-C nicht. Du kannst nur statische Variablen wie in C verwenden.
    Schade. Wobei das natürlich funktional äquivalent benutzt werden kann, aber an der Stelle fehlt dann halt die Abstraktion im Code.


    Genau das meinte ich mit meinem ersten Beitrag in dem Singleton-Thread:

    Hier fängt das Problem an: Ein Instanzzähler wird eben in aller Regel fehlerhaft der Klasse zugeordnet. Wieso sollten die Instanzen selbst oder über ihre Klasse wissen, welche anderen Instanzen noch existieren? Wieso sollte das die Klasse interessieren? Funktioniert sie dann anders? In Wahrheit hat das logisch überhaupt nichts mit den Instanzen zu tun, sondern man frickelt es in deren Klasse unlogisch herein: Jemand anderes will in Wahrheit wissen, welche Instanzen herumgeistern. Dann soll sich aber gefälligst der darum kümmern und nicht die arme Klasse missbrauchen, weil das so schön einfach ist. Macht man das dann noch mit Singletons, hat man sein miserables Design auch noch testunfähig gemacht. "Luja, sog' I, Luja!"

    Da heißt es also nicht, dass Fehlen von Klassenvariable zu betrauern, sondern das Fehlen des eigenen guten Designs. :)

    Wenn du wirklich mal einen Fall hast, da die bereits bestehenden Instanzen interessieren – etwa Twintoning –, dann kann man das sauber machen, auch ausdruckskräftig. Meld dich dann einfach noch einmal.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Amin Negm-Awad ()

  • macmoonshine schrieb:

    RegExpressive schrieb:

    Wobei das natürlich funktional äquivalent benutzt werden kann, aber an der Stelle fehlt dann halt die Abstraktion im Code.

    Was meinst Du damit?


    Ich glaube, er will einfach den Designfehler ausdruckskräftig formulieren können. ;)
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • RegExpressive schrieb:

    Lucas de Vil schrieb:

    Es gibt keine Klassenvariablen.
    Und was soll ein Instanzzähler sein?
    Ein Beispiel für eine Variable, die logisch der Klasse zugeordnet sein muß und nicht jeder einzelnen Instanz.

    So kann man zum Beispiel eine Methode/Funktion haben wollen, die die Anzahl der aktuell existierenden Instanzen dieser Klasse liefert (oder andere ähnliche Gesamt-Informationen). Die Variable dafür muß logischerweise zentral angelegt sein.

    Ja, aber... Wozu sollte ich einer Klasse logisch eine Variable zuordnen?

    Und wen interessiert die Anzahl der Instanzen einer Klasse? 8|
    Ich bin Besitzer einer Instanz, ich gebe den Besitz der Instanz ab, fertig.

    Niemanden kümmert es, wie viele Instanzen einer Klasse noch so im Programm rumschwimmen.
    Auch nicht, von wo aus die letzte Instanz erstellt wurde oder ähnliche Gesamtinformationen.

    Ich sehe da (in Objective-C) echt keinen Nutzen in dieser Funktionalität.
    So gar nicht.
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • macmoonshine schrieb:

    Was meinst Du damit?
    Ob ich in C++ eine Klassenvariable deklariere oder in Obj-C auf den alten ANSI-C-Mechanismus mit einer statischen Variable zurückgreifen muß, führt letztlich zur selben Funktionalität: Eine Variable, die bei bestimmten Instanz-Methoden zwar verwendet und aktualisiert werden kann, von der es aber nur eine einzige zentrale und gemeinsame Inkarnation gibt.

    Amin Negm-Awad schrieb:

    Hier fängt das Problem an: Ein Instanzzähler wird eben in aller Regel fehlerhaft der Klasse zugeordnet. Wieso sollten die Instanzen selbst oder über ihre Klasse wissen, welche anderen Instanzen noch existieren? Wieso sollte das die Klasse interessieren? Funktioniert sie dann anders? In Wahrheit hat das logisch überhaupt nichts mit den Instanzen zu tun, sondern man frickelt es in deren Klasse unlogisch herein: Jemand anderes will in Wahrheit wissen, welche Instanzen herumgeistern. Dann soll sich aber gefälligst der darum kümmern und nicht die arme Klasse missbrauchen, weil das so schön einfach ist. Macht man das dann noch mit Singletons, hat man sein miserables Design auch noch testunfähig gemacht. "Luja, sog' I, Luja!"

    Da heißt es also nicht, dass Fehlen von Klassenvariable zu betrauern, sondern das Fehlen des eigenen guten Designs. :)
    Na, na. Jetzt komm' mal wieder vom hohen Roß herunter. ;)

    Verschiedene Sprachen legen unter anderem aufgrund existierender oder fehlender Möglichkeiten unterschiedliche Entwurfspattern nahe.

    Beispielsweise ist bei C++ das Vorhandensein "richtiger" Destruktoren eine geniale Hilfe, um den eigenen Code sauberer und robuster zu machen, indem Objekte sich sauber, vollständig und an der korrekten Stelle (also insbesondere, wenn ihr Scope innerhalb eines lokalen Code-Stücks an der schließenden geschweiften Klammer endet) von selbst entsorgen können und dabei vollautomatisch alle Konsistenz-Maßnahmen durchführen, die in ihrer Klasse definiert wurden und um die sich kein Aufrufer zu kümmern braucht.

    Im Beispiel kann es zum Beispiel wesentlich sein, daß automatisch beim Verschwinden des letzten Objekts der Klasse bestimmte Signalisierungen erfolgen können.

    In C++ ist das völlig sauber, zuverlässig und für den Aufrufer völlig transparent alleine schon in der Klasse selbst machbar und funktioniert vor allem auch ohne Verzögerung (die Freigabe erfolgt sofort, nicht erst irgendwann später).

    Das ist durchaus eine sinnvolle Angelegenheit und erlaubt dadurch ganz andere Strategien bei der Implementierung als bei praktisch allen anderen Sprachen, bei denen Destruktoren leider in dieser Form nicht existieren.

    Es geht mir gar nicht darum, daß C++ "die beste" OO-Sprache sein sollte, denn es hat natürlich seine eigenen Haken und Ösen, während Obj-C z.B. in Punkto Laufzeit-Flexibilität brillieren kann.

    Worauf es mir ankommt ist, daß unterschiedliche Sprachkonzepte unterschiedliche Entwurfspattern ermöglichen, nahelegen oder gar erzwingen.

    Und man sollte nicht der Illusion anhängen, daß nur deshalb, weil man sich bestimmte Pattern angewöhnt hat, die in der Lieblingssprache aus verschiedenen Gründen nun mal sinnvoll sind, exakt genau diese Pattern auch in absolut jeder anderen Sprache optimal wären – das ist definitiv nicht der Fall!

    Auch die Frage der Mehrfach-Vererbung, die diesen Thread gestartet hat, ist nicht per se zu verteufeln – es gibt gute Gründe, sie unter den passenden Umständen in C++ zu benutzen. Aber eben auch gute Gründe, sich der Konsequenzen und ggf. Problempotentiale bewußt zu sein und es in anderen Fällen auch zu lassen.

    Und in anderen Sprachen (die sich vor allem die erheblichen Compiler- bzw. Code-internen Komplikationen eines solchen Mechanismus gespart haben) muß man eben andere Wege gehen.

    Im obigen Beispiel wäre es wohl auch in C++ ein Irrweg gewesen, aber das gilt nicht für alle Fälle.

    In Obj-C gelten eigene Regeln und eben auch bevorzugte Pattern, die sich aber aufgrund der Gegebenheiten von denen in anderen Sprachen unterscheiden.

    Man sollte diese Unterschiede einfach nur nicht aus den Augen verlieren.