const in Java und interface's ...



  • nachgefragt schrieb:

    CStoll schrieb:

    ...(oder das Objekt kopieren und sich an der Kopie austoben).

    gibts da in c++ nicht dieses const cast zeugs?

    Ja, gibt es auch - aber wer sowas verwendet, soll in der Hölle schmoren.

    @nep: Interfaces braucht man in C++ nicht wirklich. Die wurden afaik nur in Java eingeführt, um eine (stark abgespeckte) Version von Mehrfachvererbung zu ermöglichen, ohne die normale Klassenhierarchie unnötig zu verkomplizieren.



  • Interfaces sind in Java auch der einzige Weg für Polymorphie. Deshalb sehen Hierachien in Java meistens komplett anders aus als in C++. Man hat deutlich mehr Vererbung und implementiert sehr viele Interfaces.

    zB eine delegate/functor wird als Interface implementiert. Es ist ein ziemlich anderer Ansatz als man in C++ hat wo man vererbung fast mit der Lupe suchen muss.

    const-correctness wurde nicht eingeführt, da es die komplexität der sprache erhöhen würde. inwieweit das argument zu zeiten von generics und annotations noch zählt, sei mal dahin gestellt. und jetzt hat man probleme es einzubauen weil es den bytecode ändern würde - und solche features werden aus verständlichen gründen sehr sehr ungern eingebaut.



  • @kasf: leider gescheitert, aber da gut getarnt kriegst du von mir trotzdem eine 5/10 <°))))o><

    @const: das sieht für mich nur wie ein fieser workaround aus um die mischung von objektorientiertem und funktionalem code in c++ vernünftig auf die reihe zu kriegen. die interne repräsentation eines objekts sollte nur das objekt selbst kennen demnach sollte es auch keine "(nicht-) verändernden" methoden geben 👎



  • Ich weiß, dass man Interfaces nicht braucht in C++. Hab ich ja auch nicht behauptet 😉
    Ich finde es trotzdem nicht schlecht, da es halt einen gewissen semantischen Unterschied darstellt, ob man nun ein Interface oder eine abstrakte Klasse verwendet. Aber wie gesagt, in C++ kommt man genauso zum Ziel.



  • hmmm++ schrieb:

    @kasf: leider gescheitert, aber da gut getarnt kriegst du von mir trotzdem eine 5/10 <°))))o><

    ? Auf was beziehst du das ?



  • KasF schrieb:

    hmmm++ schrieb:

    @kasf: leider gescheitert, aber da gut getarnt kriegst du von mir trotzdem eine 5/10 <°))))o><

    ? Auf was beziehst du das ?

    auf deinen trollversuch 🤡 👎





  • Es ist eine Zusicherung für mich, daß jemand anderes meine Objekte nicht ändern wird. Wenn ich einer fremden Funktion ein 'const test&' übergebe, kann diese nur die const-Methoden meiner Klasse verwenden.

    Das habe ich auch noch nie verstanden.
    Mir, als Benutzer einer Klasse, ist es total egal, ob intern in der Klasse irgendwelche privaten Felder veraendert werden.
    Umgekehrt, weis ich, als Programmierer der Klasse, dass wenn der Benutzer eine get Methode aufruft, er keine Interna veraendern kann. Es seih denn ich gestatte es ihm.
    Also wozu dann const-Methoden?

    Den Weg mit "nur get-Interface" ist dazu da einen Immutable und einen Mutable -Typ zu haben. Das hat den Vorteil, dass die immutable Klasse einfacherer uebergeben werden kann, also weniger komplex sein kann.
    Siehe dazu String und StringBuilder/StringBuffer.

    In Java gibts ja auch das Schlüsselwort "final", was im Prinzip das Äquivalent zu const darstellen soll, aber natürlich lange nicht so weitreichend.

    Nein, ist es nicht. C++ const und Javas final verhalten sich anders. In C++ ist const auch abhaenig vom Kontex, in Java ist final einfach nur ein Referenz-Konstant.



  • Of course, some consider the STL a bletcherous wart on the backside of C++, and others consider C++ a bletcherous wart on the back side of ComputerScience--so that would make const_iterator a ThirdDegreeWart

    ROFL



  • DEvent schrieb:

    Of course, some consider the STL a bletcherous wart on the backside of C++, and others consider C++ a bletcherous wart on the back side of ComputerScience--so that would make const_iterator a ThirdDegreeWart

    ROFL

    ja, c2.com ist nur noch geil 👍
    alles sehr lesenswert...
    🙂



  • Nehmen wir doch mal als Beispiel die Klasse String.
    Die kann ich einfach nich veraendern. Egal was ich mache. Es gibt dafuer einfach kein Interface. Wenn ich Strings manipulieren muss, dann muss StringBuilder/StringBuffer her:

    StringBuilder b = new StringBuilder(meinstring);
    b.insert b.append b. sonstwas...
    meinstring = b.toString();
    

    Wo wuerde nun ein C++-Hacker gerne ein const in der String-Klasse sehen?



  • DEvent schrieb:

    In C++ ist const auch abhaenig vom Kontex, in Java ist final einfach nur ein Referenz-Konstant.

    final ist in java auch sehr stark vom Kontext abhängig.

    final class Foo {
      final void bar(final Baz baz) {
        final int i=5;
      }
    }
    


  • DEvent schrieb:

    Es ist eine Zusicherung für mich, daß jemand anderes meine Objekte nicht ändern wird. Wenn ich einer fremden Funktion ein 'const test&' übergebe, kann diese nur die const-Methoden meiner Klasse verwenden.

    Das habe ich auch noch nie verstanden.

    Es geht um viel mehr. Auch als Hilfe für einen selber. Wie allen bekannt sein sollte, ist das übergeben von Referenzen wesentlich effizienter als Kopien. Jetzt schreibst du dir eine Funktion die etwas mit diesem Objeket machen soll, zB Ausgeben.

    Da du gar nicht vor hast dieses Objekt in der Funktion zu verändern deklarierst du den Parameter natürlich als const-Ref. ( Und jetzt nicht sagen ich pass schon auf das ich nicht falsches in der Funktion mache, bei komplexeren Funktion ist da schnell mal was passiert, zudem ist es doch viel schöner wenn man gar nicht drauf aufpasse muss )
    Nun hast du aber das Problem das du zB keine get-Methoden aufrufen könntest die nicht const sind. Deswegen deklarierst du die Funktion als const und stellst für dich selber auch ne Sicherheit auf, dass du this in get() nicht änderst.

    Es geht aber noch weiter. Häufig stellst du zwei Elementfunktion zur Verfügung, eine const und eine normal. Dadurch hast du auch die Möglichkeit die Funktion im Rückgabewert zu verändern. Nehmen wir mal an du hast ein Matrix Klass oder einfach deinen eigenen Vector:

    class MyIntVec {
    
       private:
               int *data;
       public:
               int& operator[](size_t i) { return data[i]; }
    };
    

    Nun arbeitest du ganz normal damit:

    MyIntVec vec;
    // fill vec
    cout << vec[3];
    vec[3] = 23;
    

    Alles noch ok, aber was ist wenn du ein konstantes Objekt haben willst, das irgendwas repräsentieren soll und deswegen fest und unveränderbar sein muss:

    const MyIntVec const_vec(othervec.begin(),othervec.begin() + 4);
    cout << const_vec[3]; // funktioniert nicht
    

    Der Compiler lässt das nicht zu, da er nicht weiß ob op[] nicht doch das Objekt ändern würde.

    Ist das nicht toll, das er das für einen prüft.
    Nun noch ein :

    int& operator[](size_t i) const { return data[i]; }
    

    und es funktioniert.
    Nun ist op[] const zwar bitweise Konstant aber nicht logisch Konstant.

    const_vec[3] = 3; // ohh
    

    ->

    const int& operator[](size_t i) const { return data[i]; }
    

    Schon besser 🙂

    Das sind zwar einfach Beispiele aber es sollte reichen. Ein const mehr hilft einem sehr zumal man so die Möglichkeit hat auf konstante und nicht konstante Objekte unterschiedlich zu reagieren ...



  • Es geht um viel mehr. Auch als Hilfe für einen selber. Wie allen bekannt sein sollte, ist das übergeben von Referenzen wesentlich effizienter als Kopien. Jetzt schreibst du dir eine Funktion die etwas mit diesem Objeket machen soll, zB Ausgeben.

    Da habe ich aufgehoert zu lesen. In Java werden zu 90% Referenzen uebergeben (bis auf die Primitiven). Komischer weise wird das ganz einfach ueber das Interface der Klasse geloest.

    final ist in java auch sehr stark vom Kontext abhängig.

    Ja, schon klar. Aber es ging eigentlich um Variablen/Parameter. Da ist final eindeutig, anders als das C++ const.



  • DEvent schrieb:

    Ja, schon klar. Aber es ging eigentlich um Variablen/Parameter. Da ist final eindeutig, anders als das C++ const.

    in gewisser weise nicht 😉
    final int == const int
    und
    final Foo == Foo* const

    aber ja: das was man in C++ mit const bewerkstelligt gibt es in java nicht.

    Mir, als Benutzer einer Klasse, ist es total egal, ob intern in der Klasse irgendwelche privaten Felder veraendert werden.

    Genau das ist im Sinne der const-correctness falsch. wenn ich eine lila kuh and die funktion: mache_ein_bild_von_kuh() übergebe, erwarte ich wieder eine lila kuh zu bekommen und keine grüne. const correctness garantiert mir genau das. wenn ich sage: niemand darf meine lila kuh umfärben, sprich:

    Kuh lila;
    Kuh const& konstante_lila_kuh=lila;
    

    dann weiss ich, dass meine lila kuh immer lila bleiben wird.

    das ist deshalb vorhanden da man bei primitiven typen ja nichts ändern kann:

    int i=3;
    gib_zahl_aus(i);
    

    i kann sich ja nicht ändern. ich habe die garantie dass i auch nach dem ausgeben 3 ist, weil gib_zahl_aus ja per value nimmt, es kann also i nicht ändern.

    bei

    Kuh lila=new Kuh();
    gib_kuh_aus(lila);
    

    ist diese garantie plötzlich weg.

    also haben sich ein paar leute gedacht: eigentlich ist es garnicht so dumm wenn gib_kuh_aus die kuh nicht ändern darf. sprich: wir schützen uns gegen murphy.

    dieser schutz ist aber nicht zwingend erforderlich. er erleichtert es sicheren code zu schreiben, aber es ist nicht mehr als ein versprechen. denn um alle verbote kommen wir herum - machiavelli lässt grüßen.

    java ist den weg gegangen: es ist nicht 100% erforderlich, also sparen wir uns dieses ganze konzept und halten die sprache simpel.

    Da habe ich aufgehoert zu lesen. In Java werden zu 90% Referenzen uebergeben (bis auf die Primitiven). Komischer weise wird das ganz einfach ueber das Interface der Klasse geloest.

    und das macht 0 sinn. was wird in java bezüglich const correctness bitte über das interface gelöst?

    PS:
    in java hat man in manchen situationen eine primitive form der const correctness wenn es mal nötig wird. wenn man einen privaten member von aussen zugänglich machen will, dann braucht man eine kopie oder man bricht die sicherheit der klasse. in c++ hätte man hier einfach ein const T& zurückgegeben und gut ist, da es ein const in java nicht gibt, muss man kopieren.

    kommt nicht oft vor, aber es kommt vor.

    PS2:
    genau aus diesem grund gibt es in java vermehrt immutable objekte. diese sind ja quasi konstant. ich kann zB problemlos ein immutable object nach aussen exposen ohne es kopieren zu müssen.



  • Shade Of Mine schrieb:

    Mir, als Benutzer einer Klasse, ist es total egal, ob intern in der Klasse irgendwelche privaten Felder veraendert werden.

    Genau das ist im Sinne der const-correctness falsch.

    genau das ist im sinne der objekt orientierten programmierung aber richtig. ich weiß nichts über den inneren zustand des objekts. const ist wie gesagt nur ein fieser workaround. das kannst du übrigens auch durch dein ganzes beispiel durchziehen. eine methode die eine kuh als parameter bekommt und die dann ausgibt ist anti-oop. die kuh gibt sich selbst aus. in java ist das z.b. mit der toStrign() methode geregelt. das gleiche kannst du so auch für alle anderen möglichen operationen durchziehen. ich schreib auch keine operation gibMilch(Kuh kuh)
    http://de.wikipedia.org/wiki/Objektorientierte_Programmierung



  • Ich versuch mich mal an einem anderen Beispiel:

    ConstMessage msg = new ConstMessage("Blubba");
    
    MessageDistributer md = getMD();
    for(MessageReceiver recv : md.getReceivers())
    {
        recv.notify(msg);
    }
    

    Stille Post...der letzte Receiver hat leider nicht mehr die Originalnachricht in der Hand.

    Edit: Naja, blödes Beispiel, außerdem könnte ConstMessage einfach kein Interface für setNewMessage() anbieten...

    ...aber bist du dir da auch ganz sicher, dass du nie in die Situation kommst wo ein const sinnvoll wäre?

    MfG SideWinder



  • ich bin nich angemeldet schrieb:

    genau das ist im sinne der objekt orientierten programmierung aber richtig.

    Nein 😉
    der zustand eines objektes ist durchaus relevant. es geht dabei um änderungen. ich muss nicht wissen wie es um die kuh steht, ich muss aber sehr wohl wissen ob ihr zustand stabil ist.

    es gibt dabei 2 zustände: der externe und der intern. was intern abgeht ist mir total egal. aber wenn ich zB ein auto habe und ihm sage:

    Farbe f=mercedes.getFarbe();
    

    dann will ich die garantie haben, dass mein schoener neuer mercedes nicht auf 200 km/h beschleunigt.

    ob er jetzt bei getFarbe interne werte setzt, wie zB einen farben cache einführt oder aehnliches - ist mir egal.

    es geht dabei darum: ich habe ein objekt und zeige es her - danach will ich es in exakt dem zustand haben indem ich es hergegeben habe. denn eine änderung des zustandes des objekts könnte meine klasse kaputt machen.

    Beispiel:
    Wenn ich eine Garage habe und jemand fragt mich nach der Farbe meines Mercedes:

    Farbe f = garage.getAutoFarbe("mercedes");
    

    dann erwarte ich, dass der mercedes sich dadurch nicht verfaerbt. denn wenn er das tun wuerde, waere meine garage kaputt da ich nicht mehr:

    int num = garage.getAnzahlAnAutosMitFarbe("weiss");
    

    machen kann. denn der cache in garage zählt nicht jedesmal alle farben. wäre ja dumm. er zählt nur beim reinfahren und beim rausfahren der autos. nun wurde der weisse mercedes durch

    Farbe f = garage.getAutoFarbe("mercedes");
    f.set("rot");
    

    auf rot umgefärbt.
    PENG
    ich habe mein garagen objekt zerschossen.

    Java geht nun den weg, dass Farbe einfach immutable ist. das löst das problem natürlich, da ich kein set machen kann. manchmal hat man aber komplexe objekte die nicht immutable sein können, weil ich sie verändern muss. was macht man dann?



  • [quote="Shade Of Mine"]es gibt dabei 2 zustände: der externe und der intern. was intern abgeht ist mir total egal. aber wenn ich zB ein auto habe und ihm sage:

    Farbe f=mercedes.getFarbe();
    

    dann will ich die garantie haben, dass mein schoener neuer mercedes nicht auf 200 km/h beschleunigt.{/quote]
    nein, das willst du nicht. was die klasse innerhalb ihrere methoden macht ist *ihre* sache. wenn sie es für nötig hält bei einem getFarbe() aufruf zu beschleunigen soll sie das tun. das ist eine sache der konvention und der implementierung 👎

    Beispiel:
    Wenn ich eine Garage habe und jemand fragt mich nach der Farbe meines Mercedes:

    Farbe f = garage.getAutoFarbe("mercedes");
    

    dann erwarte ich, dass der mercedes sich dadurch nicht verfaerbt. denn wenn er das tun wuerde, waere meine garage kaputt

    nein, deine garage wär nicht kaputt. entweder die garage verhält sich so wie sie sich verhält oder du brauchst eine neue garage.

    PENG
    ich habe mein garagen objekt zerschossen.

    falsch, das ganze beispiel ist nämlich blödsinn. woher und wieso sollte die garage überhaupt die farben ihrer autos kennen und speichern? wenn dann gäb es eine methode garage.findeAuto("mercedes") und eine methode auto.getFarbe() und/oder auto.setFarbe(Farbe). mal mir mal bitte zu deinem beispiel ein vernünftiges uml klassendiagramm *lol*

    irgendwie glaub ich aber das hat keinen sinn hier, ihr (du) denkt einfach zu sehr in euren funktionalen schemata.

    gruß

    ps: bist du der kleine mti den roten haaren ? 😃 🤡



  • SideWinder schrieb:

    Ich versuch mich mal an einem anderen Beispiel:

    ConstMessage msg = new ConstMessage("Blubba");
    
    MessageDistributer md = getMD();
    for(MessageReceiver recv : md.getReceivers())
    {
        recv.notify(msg);
    }
    

    Stille Post...der letzte Receiver hat leider nicht mehr die Originalnachricht in der Hand.

    Edit: Naja, blödes Beispiel, außerdem könnte ConstMessage einfach kein Interface für setNewMessage() anbieten...

    ja das beispiel ist schon irgendwie blöd wenn die klasse selber schon ConstMessage heißt wär eine methode setMessage() bissl blöde

    ...aber bist du dir da auch ganz sicher, dass du nie in die Situation kommst wo ein const sinnvoll wäre?

    ja. ich habe ein const noch nie gebraucht weder in java noch in c++ und auch in meinen wenigen c# ausflügen nicht. das hat sich immer durch vernünftiges design vermeiden lassen.


Anmelden zum Antworten