Methode in einer abgeleiteten Klasse

  • Lucas de Vil schrieb:

    Erster Gedanke zu 1)
    Wie soll denn das bitte etwas abstrakter aussehen?

    C-Quellcode

    1. if( [instance isKindOfClass:[subclass2 class] || [instance isKindOfClass:[subclass4 class] || [instance isKindOfClass:[subclass9 class])
    2. {
    3. //do stuff every of this subclasses can do
    4. }
    5. if( [instance isKindOfClass:[subclass1 class] || [instance isKindOfClass:[subclass3 class] || [instance isKindOfClass:[subclass9 class])
    6. {
    7. //do stuff every of this subclasses can do
    8. }

    Das ist ja neben hässlich auch noch total C++

    Was für ein Biss vom Apfel, der am Baume der Erkenntnis hing. Allerdings ist diese schon etwas älter. Steht nämlich bereits in meinem ersten Beitrag:
    Dass du das in C++ so fühlst, ist logisch, weil sich C++ auf Typen verlässt. Du würdest mutmaßlich auch in C++ nach dem Typen fragen und dann casten, was dannn auch in sich schlüssig wäre.


    Dinger gibt's, einfach irre!


    Lucas de Vil schrieb:

    Amin Negm-Awad schrieb:

    Wie bereits eingangs gesagt, ist es keine Lösung, im if nach der Methode zu fragen und dann im if-Zweig irgendwelche Annehmen über den Typen zu machen.

    Wo zum Henker macht er bitte im if-Zweig irgendwelche Annahmen über den Typen? Die macht er ja wohl definitiv schon weit vor dem if-Zweig!

    Es ist gleichgültig, wo er das definiert hat. Er macht eine if-Abfrage und wünscht dann, dass der Compiler innerhalb des if-Zweigs einen automatischen Downcast vornimmt. Der Compiler denkt gar nicht daran.

    Dir ist aber schon prinzipiell klar, dass er einen Fehler hat, weil sein Wunsch von der Wirklichkeit abweicht? Sonst gäbe es diesen Thread ja nicht. Oder wie viele Threads kennst du, die nur mitteilen, dass der Compiler genau das macht, was man erwartet?

    Lucas de Vil schrieb:

    Amin Negm-Awad schrieb:

    Übrigens bringt -start ganz gewiss keine Fehlermeldung, da diese keine Parameter nimmt. Und deshalb stört sich der Compiler auch nicht daran.

    Soweit ich mich erinnere gibt es gern mal Probleme, wenn der Compiler gleiche Methoden mit unterschiedlicher Signatur bekommt.
    Also Dinge wie -(void)start, -(void)start: (id)something, -(void)start: (id)something: (id)different: (id)also
    Hab jetzt keine Zeit im Forum zu suchern, erinnere mich aber, dass dazu was geschrieben stand.

    Musst du gar nicht lange suchen, steht nämlich in dem Beitrag, den du gerade unvollständig zitierst:
    Es muss mindestens -start: sein oder einen Rückgabewert haben. (Intern ist das dasselbe.)


    Du warst nur so schlau, dass zu löschen.

    Lucas de Vil schrieb:

    Amin Negm-Awad schrieb:

    Woher weißt du, ob die in einer Sammlung stecken?

    Ich gehe davon aus. Steht doch da.

    Coole Sache: Du konstruierst also eine Szenerie, nur um deiner Wahrheit nahe zu kommen, oder wie hast du das gleich formuliert?

    Aber mal ehrlich: Die Lösung eines Downcasting-Problems dürfte nur außerordentlich geringen logischen Bezug zu Collections haben, oder?

    Lucas de Vil schrieb:

    Amin Negm-Awad schrieb:

    Ah, deshalb antwrte ich dir auch gleich mit Schwachsinn.

    Genialität und Wahnsinn liegen dicht beieinander. Mit Weisheit und Schwachsinn dürfte es ähnlich sein.

    Zuweilen liegen sie ganz weit auseinander.

    Lucas de Vil schrieb:

    Nun gut, offenbar versuchen wir, dasselbe mitzuteilen.
    Deshalb fasse ich noch einmal in einem eigenen Post zusammen.

    Nein. Du hast es nur mittlerweile eingesehen.
    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"?
  • Amin Negm-Awad schrieb:

    Lucas de Vil schrieb:

    Erster Gedanke zu 1)
    Wie soll denn das bitte etwas abstrakter aussehen?

    C-Quellcode

    1. if( [instance isKindOfClass:[subclass2 class] || [instance isKindOfClass:[subclass4 class] || [instance isKindOfClass:[subclass9 class])
    2. {
    3. //do stuff every of this subclasses can do
    4. }
    5. if( [instance isKindOfClass:[subclass1 class] || [instance isKindOfClass:[subclass3 class] || [instance isKindOfClass:[subclass9 class])
    6. {
    7. //do stuff every of this subclasses can do
    8. }

    Das ist ja neben hässlich auch noch total C++

    Was für ein Biss vom Apfel, der am Baume der Erkenntnis hing. Allerdings ist diese schon etwas älter. Steht nämlich bereits in meinem ersten Beitrag:
    Dass du das in C++ so fühlst, ist logisch, weil sich C++ auf Typen verlässt. Du würdest mutmaßlich auch in C++ nach dem Typen fragen und dann casten, was dannn auch in sich schlüssig wäre.


    Dinger gibt's, einfach irre!

    Das richtete sich ja an mich :P Und war auch eine völlig korrekte Aussage. Wobei ich aber in meiner ursprünglichen Überlegung eigentlich darauf hinauswollte, dass man soetwas in C++ zwar machen kann, aber in der Regel nicht machen sollte (und üblicherweise auch nicht macht). Also wiegesagt, besseres Klassendesign oder Visitor-Pattern oder sonstwas anderes. Daher meine Skepsis gegenüber einem ähnlichen bzw. vergleichbaren Vorgehen in Obj-C. Also: If-else-Prüfung. egal ob jetzt auf Typ oder "Kompetenz", kommen mir komisch vor.
    C++
  • Ja nee, is klar Amin. :rolleyes:

    zerm schrieb:

    Also: If-else-Prüfung. egal ob jetzt auf Typ oder "Kompetenz", kommen mir komisch vor.

    Nun ja, wenn du beispielsweise Actions hast, kann eine Prüfung auf die Kompetenz sinnvoll sein.
    Immerhin kann ein -title an das falsche Objekt gesendet dein gesamtes Programm zum Abstürzen bringen.

    Wie häufig man das jetzt braucht weiß ich nicht.
    Außer in konstruierten Szenarien habe ich da noch keine Notwendigkeit erlebt.

    Allerdings musste ich auch noch keine KVC/KVO Implementierung von 0 auf an basteln und kann auch nicht einschätzen, in welchen tiefen Interna des Cocoa-Frameworks diese Methoden ihre Berechtigung haben.

    Zumindest dürfte es kein zuverlässiges Paradigma geben, welches die Kompetenzprüfung in if-Abfragen umgeht, so wie es die automatische Typprüfung des Compilers tut.
    Hier wären lediglich Protokolle ein Hilfsmittel.

    zerm schrieb:

    Wobei ich aber in meiner ursprünglichen Überlegung eigentlich darauf hinauswollte...

    Ich kann mir in Anbetracht des Threadverlaufes nicht vorstellen, dass sich Amin für ursprüngliche Intentionen interessiert. ;)
    «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:


    Nun ja, wenn du beispielsweise Actions hast, kann eine Prüfung auf die Kompetenz sinnvoll sein.
    Immerhin kann ein -title an das falsche Objekt gesendet dein gesamtes Programm zum Abstürzen bringen.

    Und warum hast Du ein Objekt, an dass Du überlegst "-title" zu senden? Warum musst Du also Actions, die von etwas, was "-title" kann und von etwas, was kein "-title" kann, zusammenführen?
    Warum nicht eine Action "buttonPushed:" und "keineAhnungwas:", beide rufen dann "errechneWas:" auf, wobei der eine noch den Title vom Button anfragt, der geklickt hat. Weisste, wie ich meine?
    Ich frage auch nur, und will nicht behaupten, dass das die bessere Lösung sei oder so. Aber hier hat ja die gemeinsame Aktion unterschiedliche Bedeutungen, je nachdem wer sie ruft - warum also nicht unterschiedliche Aktionen?

    Lucas de Vil schrieb:


    Ich kann mir in Anbetracht des Threadverlaufes nicht vorstellen, dass sich Amin für ursprüngliche Intentionen interessiert. ;)

    Macht er das nicht prinzipiell immer? Irgendwie muss man ja noch was finden, wie man jemanden missverstehen kann :P
    C++
  • zerm schrieb:

    Amin Negm-Awad schrieb:

    Lucas de Vil schrieb:

    Erster Gedanke zu 1)
    Wie soll denn das bitte etwas abstrakter aussehen?

    C-Quellcode

    1. if( [instance isKindOfClass:[subclass2 class] || [instance isKindOfClass:[subclass4 class] || [instance isKindOfClass:[subclass9 class])
    2. {
    3. //do stuff every of this subclasses can do
    4. }
    5. if( [instance isKindOfClass:[subclass1 class] || [instance isKindOfClass:[subclass3 class] || [instance isKindOfClass:[subclass9 class])
    6. {
    7. //do stuff every of this subclasses can do
    8. }

    Das ist ja neben hässlich auch noch total C++

    Was für ein Biss vom Apfel, der am Baume der Erkenntnis hing. Allerdings ist diese schon etwas älter. Steht nämlich bereits in meinem ersten Beitrag:
    Dass du das in C++ so fühlst, ist logisch, weil sich C++ auf Typen verlässt. Du würdest mutmaßlich auch in C++ nach dem Typen fragen und dann casten, was dannn auch in sich schlüssig wäre.


    Dinger gibt's, einfach irre!

    Das richtete sich ja an mich :P Und war auch eine völlig korrekte Aussage. Wobei ich aber in meiner ursprünglichen Überlegung eigentlich darauf hinauswollte, dass man soetwas in C++ zwar machen kann, aber in der Regel nicht machen sollte (und üblicherweise auch nicht macht). Also wiegesagt, besseres Klassendesign oder Visitor-Pattern oder sonstwas anderes. Daher meine Skepsis gegenüber einem ähnlichen bzw. vergleichbaren Vorgehen in Obj-C. Also: If-else-Prüfung. egal ob jetzt auf Typ oder "Kompetenz", kommen mir komisch vor.

    Ja, ich sagte ja auch, dass es von deinem Standpunkt (frühe Typisierung) absolut nachvollziehbar ist.

    In Objective-C ist das völlig gang und gäbe. Bei Delegates siehst du ständig, dass nachgefragt wird: "Kann er dies, kann er jenes?" Aber auch etwa das Laden von Dokumenen funktioniert so: "Mal schauen, welche Methode implementiert ist."

    Völlig normal für einen Objective-C-ler.
    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"?
  • zerm schrieb:

    Lucas de Vil schrieb:


    Nun ja, wenn du beispielsweise Actions hast, kann eine Prüfung auf die Kompetenz sinnvoll sein.
    Immerhin kann ein -title an das falsche Objekt gesendet dein gesamtes Programm zum Abstürzen bringen.

    Und warum hast Du ein Objekt, an dass Du überlegst "-title" zu senden? Warum musst Du also Actions, die von etwas, was "-title" kann und von etwas, was kein "-title" kann, zusammenführen?
    Warum nicht eine Action "buttonPushed:" und "keineAhnungwas:", beide rufen dann "errechneWas:" auf, wobei der eine noch den Title vom Button anfragt, der geklickt hat. Weisste, wie ich meine?
    Ich frage auch nur, und will nicht behaupten, dass das die bessere Lösung sei oder so. Aber hier hat ja die gemeinsame Aktion unterschiedliche Bedeutungen, je nachdem wer sie ruft - warum also nicht unterschiedliche Aktionen?

    Lucas de Vil schrieb:


    Ich kann mir in Anbetracht des Threadverlaufes nicht vorstellen, dass sich Amin für ursprüngliche Intentionen interessiert. ;)

    Macht er das nicht prinzipiell immer? Irgendwie muss man ja noch was finden, wie man jemanden missverstehen kann :P

    Es ist einfach komplizierter, verursacht mehr Code und vor allem doppelten Code.

    Die Methode tut ja immer dasselbe, etwa die ersten drei Zeichen lesen. Sie macht es nur aus etwas anderem. Natürlich kan man jetzt für jeden Fall einen "Anpassungslayer" implementieren. Aber wozu? Das Beispiel aus dem Kurs dient ja nur als Beispiel. Dahinter kann viel mehr stecken. Es ist ja extrem einfach gehalten.

    Übrigens gibt es immer noch den Unterschied zwischen Klassen und Fähigkeiten. Bei einer klassenbasierten Lösung benötigst du drei Methoden: Menu-Item, Button (beide title) und Textfeld (-stringValue). Gehst du von der Fähigkeit aus, hast du wenn überhaupt nur 2 Fälle.

    Man kann auch eine klassenbasierte Lösung in zwei Fälle stopfen, wenn man eine Mittelklasse bildet (NSContainsValueInTitleControl). Dann geht das Spiel aber für die Hintergrundfarbe von vorne los. Und am Ende bekommst du das hierarchisch gar nciht mehr hin, womit du bei Mehrfachvererbung landest.
    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 ()

  • zerm schrieb:

    Lucas de Vil schrieb:


    Nun ja, wenn du beispielsweise Actions hast, kann eine Prüfung auf die Kompetenz sinnvoll sein.
    Immerhin kann ein -title an das falsche Objekt gesendet dein gesamtes Programm zum Abstürzen bringen.

    Und warum hast Du ein Objekt, an dass Du überlegst "-title" zu senden? Warum musst Du also Actions, die von etwas, was "-title" kann und von etwas, was kein "-title" kann, zusammenführen?
    Warum nicht eine Action "buttonPushed:" und "keineAhnungwas:", beide rufen dann "errechneWas:" auf, wobei der eine noch den Title vom Button anfragt, der geklickt hat. Weisste, wie ich meine?
    Ich frage auch nur, und will nicht behaupten, dass das die bessere Lösung sei oder so. Aber hier hat ja die gemeinsame Aktion unterschiedliche Bedeutungen, je nachdem wer sie ruft - warum also nicht unterschiedliche Aktionen?

    Lucas de Vil schrieb:


    Ich kann mir in Anbetracht des Threadverlaufes nicht vorstellen, dass sich Amin für ursprüngliche Intentionen interessiert. ;)

    Macht er das nicht prinzipiell immer? Irgendwie muss man ja noch was finden, wie man jemanden missverstehen kann :P



    Ach so ist. Am Ende steht hier meine ursprngliche Lösung. Am Anfang hieß die Schwachsinn.

    Was gibt es da misszuverstehen?

    Aber es ist natürlich einfacher, persönlich zu werden. Immerhin sprichst du hier von einem Thema, von dem du selbst angibst, keine Ahnung zu haben.
    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 ()

  • Lucas de Vil schrieb:

    Ja nee, is klar Amin. :rolleyes:

    zerm schrieb:

    Also: If-else-Prüfung. egal ob jetzt auf Typ oder "Kompetenz", kommen mir komisch vor.

    Nun ja, wenn du beispielsweise Actions hast, kann eine Prüfung auf die Kompetenz sinnvoll sein.
    Immerhin kann ein -title an das falsche Objekt gesendet dein gesamtes Programm zum Abstürzen bringen.

    Wie häufig man das jetzt braucht weiß ich nicht.
    Außer in konstruierten Szenarien habe ich da noch keine Notwendigkeit erlebt.

    Allerdings musste ich auch noch keine KVC/KVO Implementierung von 0 auf an basteln und kann auch nicht einschätzen, in welchen tiefen Interna des Cocoa-Frameworks diese Methoden ihre Berechtigung haben.

    Zumindest dürfte es kein zuverlässiges Paradigma geben, welches die Kompetenzprüfung in if-Abfragen umgeht, so wie es die automatische Typprüfung des Compilers tut.
    Hier wären lediglich Protokolle ein Hilfsmittel.

    zerm schrieb:

    Wobei ich aber in meiner ursprünglichen Überlegung eigentlich darauf hinauswollte...

    Ich kann mir in Anbetracht des Threadverlaufes nicht vorstellen, dass sich Amin für ursprüngliche Intentionen interessiert. ;)

    Nein, ein Protokoll bietet hier keine Lösung.

    Ein Protokoll dient dazu, typfremde Klassen zu standadisieren. Das haben wir nicht.

    In dem Falle des OP müsstest du entweder pro Subklasse ein Protokoll aufsetzen. Dann kannst du gleich die Klasse abfragen.

    Oder du packst die in den Subklassen jeweils unterschiedlich auftretenden Methoden in ein Protokoll. Dann kannst du aber gleich die Methoden abfragen.

    Ein Protokoll ist dann sinnvol, wenn du überhaupt keine Aussage über die Klasse machen kannst (kann er aber: gemeinsame Basisklasse) und es einen hohen Anteil an gemeinsam zu implementierenden Methoden gibt, die vom Benutzer (also bei ihm der abgebildete Code) feststehen. Er hat aber die unterschiedlichen Methoden in der Subklasse und müsste jetzt kreuz und quer protokollieren. Das ist eher nicht wartbar.
    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"?
  • Lucas de Vil schrieb:

    Ja nee, is klar Amin. :rolleyes:

    Okay, schlagendes Argument. Komisch, dass deine Lösung meiner jetzt fast wortgleich ist. Vorhin war die noch Schwachsinn …

    Lucas de Vil schrieb:

    zerm schrieb:

    Wobei ich aber in meiner ursprünglichen Überlegung eigentlich darauf hinauswollte...

    Ich kann mir in Anbetracht des Threadverlaufes nicht vorstellen, dass sich Amin für ursprüngliche Intentionen interessiert. ;)

    Du kannst dir so einiges nicht vorstellen. Das ist aber nicht mein Problem.

    Wie dem auch sei: Mein erster Lösungsansatz wird jetzt komischerweise auch von dir vertreten, obwohl er vorher noch Schwachsinn hieß. Das sagt in der Tat etwas von deiner Vorstellungskraft.
    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"?
  • Nicht dein Lösungsansatz war Schwachsinn, sondern das Konstrukt deines 'Einstellungsgespräches'.
    Trotz zitierter Stelle siehst du es wieder im Gültigkeitsbereich des kompletten Threads, was es aber nicht ist.

    Ach komm, ich geb's auf.
    «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
  • Wie bereits mehrfach geschrieben, ich bin lernwillig und frage nur. Ich behaupte hier nichts und gebe mir Mühe, nichts misszuverstehen.

    Amin Negm-Awad schrieb:


    Es ist einfach komplizierter, verursacht mehr Code und vor allem doppelten Code.

    Meinst Du? Ich stelle mir das so vor:

    Quellcode

    1. - (void)actionButton:(NSButton*)sender {
    2. [self machWasMitTitel:[sender title]];
    3. [self berechneWas];
    4. }
    5. - (void)actionWasAndres:(NSWasAndres*)sender {
    6. [self machWasMitWasAnderem:[sender wasAnderes]];
    7. [self berechneWas];
    8. }
    9. - (void) berechneWas {
    10. [self ganzAnstrengendeRechnungen];
    11. }
    Alles anzeigen

    vs.

    Quellcode

    1. - (void) berechneWas:(id)sender {
    2. if([sender respondsToSelector:@selector(title)]) {
    3. [self machWasMitTitel:[sender title]];
    4. }
    5. else if([sender respondsToSelector:@selector(wasAnderes)]) {
    6. [self machWasMitWasAnderem:[sender wasAnderes]];
    7. }
    8. [self ganzAnstrengendeRechnungen];
    9. }

    Sieht schon etwas kürzer aus, letzteres. Aber ist das wirklich soviel weniger kompliziert und deutlich klarer? Ich bin noch nicht ganz überzeugt :)

    Amin Negm-Awad schrieb:


    Aber es ist natürlich einfacher, persönlich zu werden. Immerhin sprichst du hier von einem Thema, von dem du selbst angibst, keine Ahnung zu haben.

    Ich werde doch nicht persönlich, sei doch nicht albern. Ich habe nur öfter das Gefühl, dass Du gerne auf Details herumreitest, die von anderen zugegebenermassen nicht vollkommen korrekt beschrieben wurden - aber ohne, dass dies auch nur einer Person irgendeinen Erkenntnisgewinn bringt.
    In diesem Thread gerade stimme ich eigentlich mit Dir überein, aber ich kann verstehen, wie man an Deiner Art zu argumentieren verzweifeln kann.
    Aber, beispielsweise, um zu erleutern, wie Du auf andere (bzw. mich) manchmal wirkst:
    Du schreibst Dinge wie "Aber fwtag weigert sich ja hartnäckig, Objective-C zu lernen". So berechtigt das sein mag (ich will darüber jetzt nicht urteilen), ist das im Prinzip "geflame" und unredlich. Das kann man auch freundlicher formulieren bzw. ganz weglassen, weil es niemanden etwas bringt. Ein weiteres Beispiel sind Aussagen von Dir wie etwa "Doch steht zur Diskussion. Und zwar schon in meinem ersten Beitrag. Einfach noch einmal lesen." Wenn Du der Meinung bist, der Betreffende hätte Deinen früheren Beitrag nicht verstanden, kannst Du Doch einfach noch einmal versuchen zu erklären, was Du meinst. Eventuell war der erste Beitrag ja nicht so deutlich, oder es fällt schwer, das Ganze auf eine andere Tatsache anzupassen. Wenn Du nicht diskutieren möchtest (so nennt man das), ist vielleicht ein Diskussionsforum der falsche Ort?
    Wie gesagt, das ist jetzt wirklich nicht persönlich gemeint oder so, ich wollte nur darlegen, warum ich (und evtl. auch andere) manchmal ganz schön an Dir zu nagen haben. Das hat in der Regel wenig mit dem, was du inhaltlich schreibst zu tun, sondern viel mehr mit der Art und Weise.
    C++

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von zerm () aus folgendem Grund: Dreher korrigiert, danke Lucas :D

  • Es bietet dir in dem Fall einfach den Vorteil, dass du dich wirklich einen Dreck darum kümmern musst, wer jetzt die Berechnung ausführt, also als Parameter sender übergeben wird.
    Baust du sechs Monate später das Ganze um und nutzt einen eigenen zum Beispiel von NSControl direkt abgeleiteten Button, kannst du ihn einfach mit übergeben.
    Dein Code wird immer noch funktionieren, sofern dein eigener Button die Nachricht -title oder die Nachricht -stringValue irgendwie beantworten kann.

    Bei der Typabfrage musst du dann dafür sorgen, dass du deinen neuen Button als Klasse zur Deklaration mitgibst.

    Weiterhin (um bei deinem Beispiel zu bleiben) kannst du in der dynamisch typisierten Variante ganz einfach neue Bedienelemente mit der Action verketten: es wird mutmaßlich immer funktionieren.
    Egal ob Button, Textfeld, Menüeintrag, Label oder eigenes View.

    Beim statischen Typisieren muss das nicht gegeben sein.
    Weiterhin hast du mindestens eine zusätzliche Methode, die Vorbereitungen trifft, bevor die eigentliche Methode aufgerufen wird.

    Wenn in einem Programm ein Button 'Berechne' und ein Menüeintrag 'Berechne' existieren und man im Falle des 'Enter'-Drückens im Textfeld auch eine Berechnung haben möchte, kann das im Nachhinein verwirrend sein.
    Logisch möchtest du einfach nur eine Berechnung durchführen.

    Dafür kannst du bei dynamischer Bindung einfach die Methode -(IBAction)berechneDasErgebnis: (id)sender anpassen.
    "Ich möchte eine Berechnung durchführen, also suche ich die Methode für die Berechnung."

    Dagegen musst du dich bei der statischen Typisierung erst mal durch -(IBAction)vorbereitungBerechnungDurchButton: (NSButton*)sender, -(IBAction)vorbereitungBerechnungDurchMenuItem: (NSMenuItem*)sender und -(IBAction)vorbereitungBerechnungDurchTextfeld: (NSTextField*)sender ackern, um anschließend -(void)berechneDasErgebnis zu überarbeiten.
    "Ich möchte eine Berechnung durchführen. Dafür muss ich erst mal schauen, wer diese Berechnung aufruft und anschließend die Berechnungsmethode durchführen."

    Zugegeben ändert das nichts an der Tatsache, dass du deine Abfrage trotzdem erweitern musst, möchtest du irgendwie ein Control beeinflussen, das weder -title noch -stringValue kennt.
    Es macht die Sache dennoch übersichtlicher und einfacher.

    Andererseits: du willst nur etwas an der Berechnung ändern, nicht an der Anpassung des Controls.
    Dann könnte die statisch typisierte Variante wieder von Vorteil sein, denn in deiner Methode -(void)berechneDasErgebnis hast du ausschließlich die Berechnung stehen, während du bei -(IBAction)berechneDasErgebnis: (id)sender bei dem ganzen Rattenschwanz (oder -kopf) von Controlanpassungen erst mal die eigentliche Berechnung suchen musst.

    Da kann man allerdings wieder gegenhalten: Code kommentieren hilft.

    Ich persönlich bin der Meinung, dass es in diesem Fall kein 'richtig' oder 'falsch' gibt.
    Die Hauptsache ist, man macht es immer konsequent auf eine Art, wie Amin es so schön zusammengefasst hat.
    Diesen Knackpunkt hatte ich tatsächlich übersehen.

    Mir ist allerdings noch kein Anwendungsfall untergekommen, in dem ich diese Vorteile der komplett dynamischen Typisierung wirklich gebraucht habe.
    Selbst das delegate eines UIViewControllers ist nur pseudodynamisch, da es an ein Protokoll gebunden ist. Pseudodynamisch deshalb, weil die Angabe des Protokolls den Compiler wieder dazu bringt zu meckern, möchte man Methoden aufrufen, die nicht im Protokoll enthalten sind.
    Und genauso wie ich id<delegateProtokoll> delegate einfach auf (id)delegate casten kann, kann ich auch NSButton* sender auf (id) sender casten.
    Und genauso, wie ich <delegateProtokoll> erweitern kann, kann ich auch NSCustomizedButton* definieren.

    ---

    In diesem konstruierten Anwendungsfall mit den Berechnungen könnte man die angezeigte Meldung des Controls von 'Berechne' in 'Neuberechnung' anpassen. Halte ich persönlich aber für sinnfrei.
    «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

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Lucas de Vil ()

  • zerm schrieb:

    Wie bereits mehrfach geschrieben, ich bin lernwillig und frage nur. Ich behaupte hier nichts und gebe mir Mühe, nichts misszuverstehen.

    Amin Negm-Awad schrieb:


    Es ist einfach komplizierter, verursacht mehr Code und vor allem doppelten Code.

    Meinst Du? Ich stelle mir das so vor:

    Quellcode

    1. - (void)actionButton:(NSButton*)sender {
    2. [self machWasMitTitel:[sender title]];
    3. [self berechneWas];
    4. }
    5. - (void)actionWasAndres:(NSWasAndres*)sender {
    6. [self machWasMitWasAnderem:[sender wasAnderes]];
    7. [self berechneWas];
    8. }
    9. - (void) berechneWas {
    10. [self ganzAnstrengendeRechnungen];
    11. }
    Alles anzeigen

    vs.

    Quellcode

    1. - (void) berechneWas:(id)sender {
    2. if([sender respondsToSelector:@selector(title)]) {
    3. [self machWasMitTitel:[sender title]];
    4. }
    5. else if([sender respondsToSelector:@selector(wasAnderes)]) {
    6. [self machWasMitWasAnderem:[sender wasAnderes]];
    7. }
    8. [self ganzAnstrengendeRechnungen];
    9. }

    Sieht schon etwas kürzer aus, letzteres. Aber ist das wirklich soviel weniger kompliziert und deutlich klarer? Ich bin noch nicht ganz überzeugt :)

    Ich hatte von Buttons, Textfeldern und Menu-Items gesprochen.

    Mit Typen:

    Quellcode

    1. - (void)actionButton:(NSButton*)sender {
    2. [self machWasMitTitel:[sender title]];
    3. [self berechneWas];
    4. }
    5. - (void)actionMenuItem:(NSWasAndres*)sender {
    6. [self machWasMitWasAnderem:[sender title]];
    7. [self berechneWas];
    8. }
    9. - (void)actionWasAndres:(NSWasAndres*)sender {
    10. [self machWasMitWasAnderem:[sender wasAnderes]];
    11. [self berechneWas];
    12. }
    13. - (void) berechneWas {
    14. [self ganzAnstrengendeRechnungen];
    15. }
    Alles anzeigen


    Anwendung ohne Typen:

    Quellcode

    1. - (void) berechneWas:(id)sender {
    2. if([sender respondsToSelector:@selector(title)]) {
    3. [self machWasMitTitel:[sender title]];
    4. }
    5. else if([sender respondsToSelector:@selector(wasAnderes)]) {
    6. [self machWasMitWasAnderem:[sender wasAnderes]];
    7. }
    8. [self ganzAnstrengendeRechnungen];
    9. }


    Aber es geht nicht um Zelen Code. Es geht darum, dass das eigentlich keine Frage der Typhierarchie ist. Wie bereits oeben geschrieben, wäre es typisiert "sauber", wenn du Zwischenklassen wie "NSControlWithTextInTitle" und "NSControlWithTextInStringValue" bildest. Dann hättest du das wieder hierarchisiert. Und wie geht das weiter? Wie ich erwähnte: Gibt es dann einen Baum für die Backgroundcolor, weil die sich bei manchen Controls in backgroundColor in andern in color und in noch anderen in secondColor verbirgt? Letztlich kommst du hier – wenn du es mit Typen durchhalten willst – nur mit Merhfachvererbung weiter. Und du wirst das genau so sehen, dass es dass nicht besser, sondern wirrer macht. Das ist einfach kein Problem der Typisierung, weil es sich nicht hierarchisieren lässt.

    Protokolle helfen deshalb hier in der Regel auch wenig, weil du hier dann letztlich für fast jede Methode ein Protokoll definieren musst, dass du dann über <> "quer" hereintypisierst. Dann kannst du auch gleich Methoden einzen abfragen. Protokolle sind für Methodenbündel einer unbekannten Klasse gedacht. Im Falle des OP haben wir aber eher zufälig Methodenbündel und schon gar nicht unbekannte Klassen: Passt nicht.

    zerm schrieb:

    Amin Negm-Awad schrieb:


    Aber es ist natürlich einfacher, persönlich zu werden. Immerhin sprichst du hier von einem Thema, von dem du selbst angibst, keine Ahnung zu haben.

    Ich werde doch nicht persönlich, sei doch nicht albern.

    Das hatte ich egentlich Lucas geantwortet …

    zerm schrieb:

    Ich habe nur öfter das Gefühl, dass Du gerne auf Details herumreitest, die von anderen zugegebenermassen nicht vollkommen korrekt beschrieben wurden - aber ohne, dass dies auch nur einer Person irgendeinen Erkenntnisgewinn bringt.

    Nein, in diesem Falle geht es um das "Detail" Methodenabfrage/Typisierung. Das ist der Inhalt. Und ja, ich reite auf diesen Inhalt herum.

    zerm schrieb:

    In diesem Thread gerade stimme ich eigentlich mit Dir überein, aber ich kann verstehen, wie man an Deiner Art zu argumentieren verzweifeln kann.
    Aber, beispielsweise, um zu erleutern, wie Du auf andere (bzw. mich) manchmal wirkst:
    Du schreibst Dinge wie "Aber fwtag weigert sich ja hartnäckig, Objective-C zu lernen". So berechtigt das sein mag (ich will darüber jetzt nicht urteilen), ist das im Prinzip "geflame" und unredlich.

    Stimmt. War aber nur eine Reaktion auf seinen Beitrag hier:
    Mal ehrlich: Wir wissen doch beide, was ich meine, oder? Natürlich können wir unser beider Zeit mit Spitzfindigkeiten ausfüllen, aber das frisst genauso Deine Zeit wie meine, gell? Ich möchte nicht Gefahr laufen, dafür von Dir eine Anwalts-Rechnung zu erhalten ...;-)

    Insofern habe ich nur zurückgegeben, was ich bekam. Quatsch natürlich. Ich habe ihm schon häufig geholfen, er mir noch nie.

    zerm schrieb:

    Das kann man auch freundlicher formulieren bzw. ganz weglassen, weil es niemanden etwas bringt. Ein weiteres Beispiel sind Aussagen von Dir wie etwa "Doch steht zur Diskussion. Und zwar schon in meinem ersten Beitrag. Einfach noch einmal lesen." Wenn Du der Meinung bist, der Betreffende hätte Deinen früheren Beitrag nicht verstanden, kannst Du Doch einfach noch einmal versuchen zu erklären, was Du meinst. Eventuell war der erste Beitrag ja nicht so deutlich, oder es fällt schwer, das Ganze auf eine andere Tatsache anzupassen.

    Zwischen dem ersten Beitrag und dem Zitat lagen X Beiträge. Und ja: Ich erlebe es regelmäßig, dass die nicht ordentlich gelesen werden. Wieso soll ich es also immer und immer wieder hinschreiben? Es steht da ja schon.

    zerm schrieb:

    Wenn Du nicht diskutieren möchtest (so nennt man das), ist vielleicht ein Diskussionsforum der falsche Ort?
    Vielleicht richtig. Allerdings sind Leute, die auf etwas antworten ohne es vorher ordentlich gelesen zu haben, ganz gewiss am falschen Ort.

    zerm schrieb:

    Wie gesagt, das ist jetzt wirklich nicht persönlich gemeint oder so, ich wollte nur darlegen, warum ich (und evtl. auch andere) manchmal ganz schön an Dir zu nagen haben. Das hat in der Regel wenig mit dem, was du inhaltlich schreibst zu tun, sondern viel mehr mit der Art und Weise.

    Dann sollte man hin und wieder mehr Zeit aufbringen, es noch einmal durchzuarbeiten. Ganz gewiss sollte man mehr Zeit aufbringen, bevor man schreibt: "Das ist Schwachsinn." Dann sollte man sich nämlich ganz, ganz sicher sein.
    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 ()

  • Lucas de Vil schrieb:

    Nicht dein Lösungsansatz war Schwachsinn, sondern das Konstrukt deines 'Einstellungsgespräches'.
    Trotz zitierter Stelle siehst du es wieder im Gültigkeitsbereich des kompletten Threads, was es aber nicht ist.

    Ach komm, ich geb's auf.

    Ich hatte dir den Grund für das Beispiel in einem gesonderten Beitrag noch einmal mit Hervorhebung erläutert. Du wirst sehen, dass es mir gerade nicht auf die konkreten Tätigkeiten und Ausbildungen ankommt, sondern darauf, dass man das überhaupt vermischt.

    Vielleicht solltest du auch diesen Beitrag noch einmal lesen.
    osxentwicklerforum.de/index.ph…&postID=124909#post124909
    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 ()

  • Amin Negm-Awad schrieb:


    Ich hatte von Buttons, Textfeldern und Menu-Items gesprochen.

    Ja. Du. Das meine ich, mit Missverständnissen. Mir war nicht vollends klar, wie Du das meinst, darum hatte ich mein Beispiel gebracht, damit wir daran weiter diskutieren können. ;)

    Amin Negm-Awad schrieb:


    Aber es geht nicht um Zelen Code. Es geht darum, dass das eigentlich keine Frage der Typhierarchie ist. Wie bereits oeben geschrieben, wäre es typisiert "sauber", wenn du Zwischenklassen wie "NSControlWithTextInTitle" und "NSControlWithTextInStringValue" bildest. Dann hättest du das wieder hierarchisiert. Und wie geht das weiter? Wie ich erwähnte: Gibt es dann einen Baum für die Backgroundcolor, weil die sich bei manchen Controls in backgroundColor in andern in color und in noch anderen in secondColor verbirgt? Letztlich kommst du hier – wenn du es mit Typen durchhalten willst – nur mit Merhfachvererbung weiter. Und du wirst das genau so sehen, dass es dass nicht besser, sondern wirrer macht. Das ist einfach kein Problem der Typisierung, weil es sich nicht hierarchisieren lässt.

    Das ist mir klar. Worauf ich hinaus wollte, ist, wenn Deine Methode noch "backgroundColor" auswerten soll, macht sie ja etwas ganz anderes, und dieser Teil ergibt dann ja für Buttons etc. gar keinen Sinn (und ist ja auch abgetrennt durch if-respondsToSelector). Du kannst es ja meinetwegen als Prozess sehen:
    - Zuerst habe ich nur ein Button. Der löst eine Aktion aus: aendereTitelUndStarteBerechnung:
    - Gut, ich stelle im weiteren Verlauf fest, dass ich das auch über mein NSWasAuchImmer auch auslösen möchte, und mein NSWasAuchImmer mit foo: zuvor veränderen will.
    - In der if-respondsToSelector-Manier benenne ich dann meine Methode um in aendereTitelOderMachFooUndStarteBerechnung:
    - Huch, was für ein unsinniger Name. Genau, die beiden Dinge haben nicht viel miteinander zu tun. Warum also nicht aufteilen in zwei Methoden (und später noch mehr)? Dann fällt auch das if-respondsToSelector weg.
    Verstehst Du, worauf ich hinaus will?
    C++
  • Es geht aber nicht darum, dass du einmal -aendereTitelUndStarteBerechnung hast und einmal aendereTitelOderMachFooUndStarteBerechnung, also verschiedene Tätgkeiten. Das würde ich auch in zwei Methoden packen.

    Es geht darum, dass ich immer eine Berechnung starte, jedoch den Wert woanders her erhalte. Das wäre also in etwa: -macheBerechnungUndNehmeTitel und -macheBerechnungUndNehmeStringValue. Und da siehst du schon, dass die Tätigkeit (macheBerechnung) den Schwerpunkt bildet und die verschiedenen Quellen unnatürlich sind. (Weil Berechnungen nur selten davon abhängen, woher du deine Parameter nimmst.) Du wirst deinem Buchhalter ja auch nicht eine neue Ausbildung spendieren, weil er einmal die Zahlen bei dem Vertrieb und ein anderes mal bei der Produktion abfragen muss.
    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"?
  • Amin Negm-Awad schrieb:

    Es geht aber nicht darum, dass du einmal -aendereTitelUndStarteBerechnung hast und einmal aendereTitelOderMachFooUndStarteBerechnung, also verschiedene Tätgkeiten. Das würde ich auch in zwei Methoden packen.

    Es geht darum, dass ich immer eine Berechnung starte, jedoch den Wert woanders her erhalte. Das wäre also in etwa: -macheBerechnungUndNehmeTitel und -macheBerechnungUndNehmeStringValue. Und da siehst du schon, dass die Tätigkeit (macheBerechnung) den Schwerpunkt bildet und die verschiedenen Quellen unnatürlich sind. (Weil Berechnungen nur selten davon abhängen, woher du deine Parameter nimmst.) Du wirst deinem Buchhalter ja auch nicht eine neue Ausbildung spendieren, weil er einmal die Zahlen bei dem Vertrieb und ein anderes mal bei der Produktion abfragen muss.

    Ein gutes Argument. Aber in diesem Fall:
    Ich bin gewöhnt, prinzipiell zu kapseln. Das heisst, wenn meine Berechnung nur ein String bekommt, soll sie gar nicht wissen, wo der herkommt. Optimal wäre, wenn die Klasse gar nicht weiss, was ein NSButton überhaupt ist. Muss sie ja auch nicht.
    Hier könnte man dann meinetwegen eine Kategorie einfügen, die diese Klasse auf Titel von Buttons erweitert. Und eine, die auf sonstwas erweitert.
    C++
  • Ja, Kategorien sind eine Lösung. Aber überlege dir mal, wie schräg es ist, Button zu erweitern, weil $irgendwoeinemethode den Wert als -stringValue und nicht als -title haben will. Was interessiert das den Button.

    Natürlich kennt man normalerweise den Typen. Aber eben nicht immer. Und diese Methode kennt in der Tat Button nicht. Das ist ja das was du willst. Sie kennt nur -stringValue und -title und weiß, dass es wohl Klassen gibt, die ihre Informationen hierüber preis geben. Ja, eine solche Situation ist die Ausnahme. Normalerweise typisiert man natürlich auch in Objective-C. Es ist eben nur manchmal praktisch, das zu vergessen.
    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"?
  • Amin Negm-Awad schrieb:


    Michse schrieb:


    Nicht dein Lösungsansatz war Schwachsinn, sondern das Konstrukt deines 'Einstellungsgespräches'.
    Trotz zitierter Stelle siehst du es wieder im Gültigkeitsbereich des kompletten Threads, was es aber nicht ist.

    Ach komm, ich geb's auf.

    Ich hatte dir den Grund für das Beispiel in einem gesonderten Beitrag noch einmal mit Hervorhebung erläutert. Du wirst sehen, dass es mir gerade nicht auf die konkreten Tätigkeiten und Ausbildungen ankommt, sondern darauf, dass man das überhaupt vermischt.

    Vielleicht solltest du auch diesen Beitrag noch einmal lesen.
    osxentwicklerforum.de/index.php?p…4909#post124909

    Ich weiß, dass du das zusammengefasst hast. Wenn man weiß, dass du explizit auf die Vermischung hinweist, dann ist es in tatsächlich offensichtlich.
    Hast du aber nicht.

    Ich zitiere dich selbst:

    Amin Negm-Awad schrieb:

    Sein Einstellungsgespräch lautet in etwa:
    Frage: "Können Sie tippen?" (= Frage nach einer Methode -tippen)
    Antwort: "Ja!"
    Frage: "Gut,da Sie eine Sekretärin sind, können Sie auch Kaffee kochen." (= Fehlerhafte Unterstellung, dass daraus der Typ Sekretärin folgt)
    Antwort: "????"

    Aber fwtag weigert sich ja hartnäckig, Objective-C zu lernen …

    Hier wäre der Hinweis "Du vermischt dynamische und statische Typisierung, das kann nix werden." anstelle des Rumgeflames angebracht, um sämtliche Verwirrungen von vorn herein auszuschließen. Das hätte vermutlich auch dafür gesorgt, dass dir niemand Rumreiterei auf unwichtigen Details unterstellt hätte.

    Dein indirektes Umherunterstellen in der dritten Person in einem Beitrag, der damit eigentlich nüscht zu tun hat ohne mich direkt anzusprechen lasse ich einfach unkommentiert. Obwohl, nicht ganz. Du bekommst dafür von mir ein weiteres :rolleyes:.
    «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