Funktion, Methode... Unterschied? in Klasse

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Funktion, Methode... Unterschied? in Klasse

    Hallo mal wieder,

    ich hab mal wieder eine (Anfänger-) Frage. Ich erarbeite zurzeit mit Methoden und wollte mal wissen was der Unterschied zwischen
    Methoden und Funktionen ist... weil ich theoretisch ja das gleiche mit ihnen machen kann.

    Hier zum Beispiel:

    // EineBerechnung.h
    // option no. 1
    int rechneAus(int,int);

    // option no. 2
    -(int)rechneAus2:(int)lange:(int)breite;

    --------------------------------------------------------------

    // EineBerechnung.m
    // option no. 1
    int rechneAus(lange, breite)
    {
    return lange * breite;
    }

    // option no. 2
    -(int)rechneAus2:(int)lange:(int)breite;
    {
    return lange * breite;
    }

    ----------------------------------------

    // main.m
    int lange = 4;
    int breite = 6;

    // option no. 1
    int ergebnis = rechneAus(lange, breite);
    NSLog(@"Ergebnis: %i", ergebnis);

    // option no. 2
    EineBerechnung *eiBerechnung = [[EineBerechnung alloc] init];
    int ergebnis2 = [eiBerechnung rechneAus2:lange :breite];
    NSLog(@"Ergebnis2: %i", ergebnis2);


    Soo, ich hab natürlich schon bisschen gegoogelt aber den Unterschied nicht ganz verstanden...


    MfG
    xChillTime

    Dieser Beitrag wurde bereits 9 mal editiert, zuletzt von xChillTime ()

  • Aus den Gründen, die Michael bereits genannt hat, ist der zweite Code vom Design her irgendwas zwischen schlecht und fehlerhaft. Rcithigerweise wäre eine Additionasmethode eine Methode von int. Was natürlich nicht geht, aber dann etwa von NSNumber oder NSDecimalNumber. Huch, da gibt es das sogar.

    Eine Methode, die kein self benutzt, ist eigentlch schon ein Designfehler. (Das ist jetzt etwas übertrieben, aber der richtige Ansatz.) Eine Solche Additionsmethode gehört daher als Helfer nicht in die Klasse, die das benötigt, sondern in die Klasse, deren Instanz behandelt wird, also eben in int (geht nicht), NSNumber oder NSDecimalNumber.

    Ich schreibe gerade an einem Projekt, welches sich sehr in die bestehende Cocoa-Infrastruktur (Core Data) integriert. Ich habe fast nur Kategorien …
    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"?
  • Und wenn ich das ganze so mache:

    // EineBerechnung.h
    @interface EineBerechnung : NSObject {
    int lange;
    int breite;
    }


    // option no. 3
    -(void)setlange:(int)value;
    -(void)setbreite:(int)value;

    -(int)calculateFlaecheninhalt;

    ------------------------------------------------

    //EineBerechnung.m
    // option no. 3

    -(void)setlange:(int)value
    {
    if (value != lange) {
    lange = value;
    }
    -(void)setbreite:(int)value
    {
    if (value != breite) {
    breite = value;
    }


    -(int)calculateFlaecheninhalt
    {
    return breite * lange;
    }

    ---------------------------------------

    //main.m
    // option no. 3

    [eiBerechnung setlange:lange];
    [eiBerechnung setbreite:breite];

    int ergebnis3 = [eiBerechnung calculateFlaecheninhalt];
    NSLog(@"Ergebnis3: %i", ergebnis3);

    --------------------------------------------------------------

    Ist natürlich nur ein Beispiel für komplexere Mathematische Berechnungen....
    Wäre das hier vom Design her immer noch "irgendetwas zwischen schlecht und fehlerhaft"?
  • Ich weiß nicht, wozu du so eine Klasse benötigst. Aber gut, unterstellen wir das mal.

    Von Design her wäre es dann ok. Von der Implementierung her nicht.

    1. Bei Settern von Skalaren benötigt man kein if.

    2. Du hältst mehrfach die Naming-Rules nicht ein:
    2.1. Es muss setLaenge heißen.
    2.2. Es muss setBreite heißen.
    2.3. -calculate… muss etwas berechnen, nicht etwas liefern. Hier böte sich ein Getter -flaecheninhalt an.
    2.4. Deutsch ist scheiße.

    3. Zu Settern gehören auch Getter.

    4. Wieso verwendet du keine Propertys?

    Mal in schön (aka weniger Farbe, mehr guter Code):

    Quellcode

    1. @interface SurfaceCalculator : NSObject
    2. @property (nonatomic) int length;
    3. @property (nonatomic) int width;
    4. @property (readonly, nonatomic) int surface;
    5. @end
    6. @implementation SurfaceCalculator
    7. @synthesize length = _length;
    8. @synthesize width = _width;
    9. - (int)surface
    10. {
    11. return self.length * self.width;
    12. }
    Alles anzeigen


    Welches Buch verwendest du?
    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"?
  • Erstmal danke für deine Antwort. Achja und die Klasse ist natürlich ein Beispiel aus meine Buch
    um zu zeigen wie sie grundlegend funktionieren.

    1. Bei Settern von Skalaren benötigt man kein if.
    Hmm... ich zitiere mein Buch: "In der Regel sollte überprüft werden, ob der als value übergebene Wert unterschiedlich
    zu den bereits gespeicherten Daten ist, um so unnötige Zuweisungen zu verhindern ... den Speicherverwaltung ist ein sehr
    komplexes Thema und das Anlegen und Freigeben für Speicherplatz für den Computer sehr aufwändig." ???

    2. Du hältst mehrfach die Naming-Rules nicht ein:2.1. Es muss setLaenge heißen.
    2.2. Es muss setBreite heißen.
    2.3. -calculate… muss etwas berechnen, nicht etwas liefern. Hier böte sich ein Getter -flaecheninhalt an.
    Ja, ich muss zugeben das war jetzt schnell dahin geklatscht... außerdem -(int)calculateRectangleArea; ist doch ein Getter, oder?

    2.4. Deutsch ist scheiße.
    Kann ich so jetzt nicht sagen... von mir aus auch setLength, setWidth...etc.

    3. Zu Settern gehören auch Getter.
    Ja, das ist schon klar ... aber hier brauchte ich sie doch nicht?

    4. Wieso verwendet du keine Propertys?
    Soweit bin ich im Buch noch nicht... hab aber schon von gehört und werde es später dann auch so machen...
    Mein Buch: Objective-C und Cocoa Praxiseinstieg - Holger Hinzberg (amazon.de )
  • Zu 1:
    Die Anmerkung in deinem Buch (welches st das) ist falsch. Es geht nicht um unnötig Zuweisungen. Es geht um Speicherverwaltung, wie dann ja auch im nächsten Satz korrigiert wird. Fehlerhaft ist dann allerdings wieder, dass das bei Skalaren dein Problem ist. Mutmaßlich hat der Autor die Speicherverwaltung nicht verstanden.

    Zu 2.3:
    Nein, es ist kein Getter. Es hat aber einen Rückgabewert. Die Methode klingt aber so, als ob sie etwas tut (technisch: Den State des Objektes ändert), während genau das nicht geschieht. Du kannst sie dann etwa auch calculatedSurface nennen.

    Zu 3.
    Wenn du etwas mit einem Setter setzt, musst du es mit einem Getter holen. Etwas setzen zu können, ohne es wieder lesen zu können, ist ja ziemlich sinnfrei. Dein Fehler liegt darin, dass du den Getter nicht benutzt. Als Folgefehler brauchst du ihn dann nicht.

    Zu 4.:
    Propertys sind wichtiger als Instanzvariablen. Inzwischen sind INstanzvariablen in aller Regel nur noch ein Implementierungsdetail, während Propertys die Klasse benutzbar machen.

    Ah, Hinzberg. Ja, das erklärt einiges.
    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"?
  • xChillTime schrieb:

    1. Bei Settern von Skalaren benötigt man kein if.
    Hmm... ich zitiere mein Buch: "In der Regel sollte überprüft werden, ob der als value übergebene Wert unterschiedlich zu den bereits gespeicherten Daten ist, um so unnötige Zuweisungen zu verhindern ... den Speicherverwaltung ist ein sehr komplexes Thema und das Anlegen und Freigeben für Speicherplatz für den Computer sehr aufwändig." ???

    Aber das hat nur wenig bis nichts mit Skalaren zu tun...
    Außerdem ist die Verwendung der Speicherverwaltung von ObjC nicht besonders kompliziert, wenn man sich an die Regeln hält


    xChillTime schrieb:

    2. Du hältst mehrfach die Naming-Rules nicht ein:2.1. Es muss setLaenge heißen.
    2.2. Es muss setBreite heißen.
    2.3. -calculate… muss etwas berechnen, nicht etwas liefern. Hier böte sich ein Getter -flaecheninhalt an.
    Ja, ich muss zugeben das war jetzt schnell dahin geklatscht... außerdem -(int)calculateRectangleArea; ist doch ein Getter, oder?

    Mutmaßlich: Nein. - Wenn doch, ist er als solcher nicht klar zu erkennen. Siehe Naming Rules.
    Passender wäre imho -(int)rectangleArea.


    xChillTime schrieb:

    3. Zu Settern gehören auch Getter.
    Ja, das ist schon klar ... aber hier brauchte ich sie doch nicht?

    Wenn Du keinen Getter hast, wozu gibt es einen Setter? Merke: Ohne Getter, keinen Setter.


    xChillTime schrieb:

    Welches Buch verwendest du?

    Mein Buch: Objective-C und Cocoa Praxiseinstieg - Holger Hinzberg (amazon.de )

    Autsch.

    P.S.: Da war ich wohl etwas langsam beim Kommentieren...
    * Kann Spuren von Erdnüssen enthalten.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von NSObject ()

  • NSObject schrieb:

    Wenn Du keinen Getter hast, wozu gibt es einen Setter? Merke: Ohne Getter, keinen Setter.

    Ist das immer so? Ich habe Objekte, bei denen ich eine Eigenschaft zwar ändere, nicht aber auslese: Sie wird wiederum objektintern herangezogen, um andere Eigenschaften zu ermitteln. Meistens gebe ich diese Eigentschaft (den Pointer darauf) direkt beim Initialisieren der Objekte als Parameter mit, aber es gibt dazu auch eine Setter-Methode. Einen (unnötigen) Getter hinzuzufügen, nur um obiger Aussage zu genügen, wäre m. E. Unsinn.

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Dann benutzt du innerhalb der Klasse die iVar direkt. Und das solltest du nicht tun. Auch da solltest du immer über den Getter gehen. Deswegen ist eine iVar auch eigentlich veraltet. Bei einer synthetisierten Property hast du immer Setter und Getter direkt dabei. Ich nutze eigentlich nichts anderes mehr.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Thallius schrieb:

    Dann benutzt du innerhalb der Klasse die iVar direkt. Und das solltest du nicht tun. Auch da solltest du immer über den Getter gehen.

    Guter Punkt! Das hatte mir vor kurzem auch ziemliche Probleme bereitet, die nach Umstellung auf Getter gelöst waren ... in dem Zuge habe ich diverse "Altlasten" auf Properties umgestellt. Das sollte ich zumindest beim nächsten Ändern der übrigen Sourcen zu Ende führen ...

    Danke für's Erinnern, Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Na, ja es gibt schon Dreiecksfälle, in denen das Lesen der Egenschaft keinen rechten Sinn ergibt. (Irgendwo meine ich mich auch zu erinnern, so einen Fall mal NSVew-Subclass gefunden zu haben!?) Aber das sollte die absolute Ausnahme bleiben. Viel wahrscheinlicher ist es, dass die Setter nicht ordentlich benutzt werden. Und immerhin haben wir das jetzt schon in 2 von 2 Fällen, was 100 % sind. ;)

    Man muss dann aber KVO extrem im Auge behalten und bekommt das meist auch nicht hin. Bleibt die Kommentarlösung. ;) Am besten man macht dsa dann nicht über eine property/Getter, sondern über eine explizite Methode. Die bneutzt dann Setter – alles wird gut.
    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"?
  • Eine Frage hab ich nochmal: Warum verwendest du hier "nonatomic" ?


    Quellcode

    1. @interface SurfaceCalculator : NSObject @property (nonatomic) int length;
    2. @property (nonatomic) int width;
    3. @property (readonly, nonatomic) int surface; @end

    Ah, Hinzberg. Ja, das erklärt einiges.
    Autsch.
    Achja... und was soll das denn heißen?
  • Standard ist atomic. Das führt dazu, dass erstens ein objektweiter Lock geschlossen wird und zweitens bei der Rückgabe des Getters ein zusätzliches Retain erfolgt, welches sogleich wieder mit einem Autorelease entsichert wird. Das betrift Threading und benötigst du daher nicht.

    Der Hinweis von mir und von NSObject (?) bedeutet ganz einfach, dass Hinzberg über etwas schreibt, wovon er keine Ahnung hat. Siehe oben. Das nächste Beispiel gibt es ja in einem Parallelthread.
    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"?
  • Ich habe dsa Buch nicht durchgearbeitet. Mir laufen nur immer wieder Klöpse über den Weg. Ein Blick in das Inhaltsverzeichnis zeigt mit einfach, dass m. E. wichtige Themen einfach gar nicht bearbeitet werden.
    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"?