const in Java und interface's ...



  • Hi,

    wie erziele ich sowas in Java:

    class MyClass {
    
      public:
         void print() const { }
    };
    

    Wenn es dann auch irgendwie funktionieren würden und ich mein const MyClass hätte, also in Java final MyClass bringt es mir doch nicht irgendwie viel, da final nur dafür sorgt das ich die Objektreferenz nicht ändern kann, aber trotzdem über Member-Aufrufe das Objekt ändern kann 🙄

    Klärt mich mal bissl in dieser Geschichte auf ...



  • http://de.geocities.com/uweplonus/faq/lang.html#const Das habe ich gerade gefunden, besonders schön ist es nicht aber immerhin 😉

    interface KonstanterTyp {
        public int get();
    }
    
    public class NichtKonstanterTyp implements KonstanterTyp {
    
        int i;
    
        public void set(int i) {
            this.i = i;
        }
    
        public int get() {
            return this.i;
        }
    }
    

    Was würde hier dagegen Sprechen extends KonstanterTyp zu schreiben. Immerhin ist doch NichtKonstanterTyp ein KonstanterTyp.

    Ich habe es so verstanden das ich ein Interface benutze wenn es keine ist-ein Beziehung ist, also eine etwa andere Komposition. Was genau ein Interface im gegensatz zu einer abstract class bringt, weiß ich auch noch nicht so genau. Hoffe mal jemand erklärts mir mal 😉



  • @Topic: Daß die const-correctness in Java eine Katastrophe ist, habe ich schon nach den letzten C++ vs. Java Diskussionen festgestellt (zu finden in den Untiefen des rudpf). Der Lösungsansatz dort endete genau bei dem Weg, den du dort genannt hast, alle anschließenden Fragen blieben unbeantwortet:

    class test
    {
      int val;
    public:
      int get() const
      {
        val=0;//nicht erlaubt (zu Recht)
        return val;
      }
      void set(int v)
      {
        val=v;
      }
    };
    
    void create_testvec(vector<test>& target);
    void display_testvec(const vector<test>& data);
    
    //ich bitte, Syntax-Fehler im folgenden Quelltest zu entschuldigen
    interface const_test
    {
    public int get();
    };
    
    class test implements const_test
    {
    private int val;
    public int get()
      {
        val=0;//das verbietet niemand, aber damit werfe ich alle const-Garantien über Bord
        return val;
      }
    public void set(int v)
      {
        val=v;
      }
    };
    

    a) niemand kann mir garantieren, daß die Methoden des const-Interfaces das Objekt nicht doch verändern (in C++ verhindert der Compiler, daß const-Methoden das Objekt ändern)
    b) wie kann ich die Funktion display_testvec() in Java umsetzen (ich glaube kaum, daß Java eine implizite Umwandlung von vector<test> nach vector<const_test> zulässt)?

    @Interfaces: Ein Interface ist (vereinfacht) die Java-Bezeichnung für "abstrakte Klasse" 😉



  • CStoll schrieb:

    @Interfaces: Ein Interface ist (vereinfacht) die Java-Bezeichnung für "abstrakte Klasse" 😉

    Und was ist dann mit "abstract class" ? Dann habe ich einmal die Interface Möglichkeit und die abstract class Möglichkeit.

    Einziger Unterschied, dass ich mehrere Interfaces implementieren kann aber nur von einer Klasse extenden darf.

    Edit: Soll ich mal in einem Java-Forum wegen der const-Geschichte fragen und dann hier den Link reinsetzen 😃



  • const-correctness ist in Java keine Katastrophe, sondern einfach ein nicht vorhandenes Konzept.

    es macht keinen sinn irgendwie es zu simulieren zu versuchen - denn solange man ein objekt nicht als const bezeichnen kann, funktioniert es ja doch nicht. es bringt nur einen false sense of security mit sich.

    PS:
    ein interface ist einfach nur eine schnittstellen schablone ohne code beinhalten zu dürfen. man kann von beliebig vielen interfaces erben. eine abstrakte klasse ist einfach nur eine abstrakte klasse wie in c++. man kann aber immer nur von einer klasse erben.



  • Shade Of Mine schrieb:

    PS:
    ein interface ist einfach nur eine schnittstellen schablone ohne code beinhalten zu dürfen. man kann von beliebig vielen interfaces erben. eine abstrakte klasse ist einfach nur eine abstrakte klasse wie in c++. man kann aber immer nur von einer klasse erben.

    Wäre sowas dann design-technisch korrekt:

    public interface Fahren
    {
        public void brumbrum();
    }
    
    abstract class Fahrzeug
    implements Fahren
    {
       ...
    }
    
    public class auto
    extends Fahrzeug
    {
    }
    

    Wäre sowas Korrekt? Also das meine Interface's bestimmte Eigenschaften von meinen Klassen sind und demnach kein Sinn machen von diesen zu erben.

    Wenn ich ja jetzt Autos fahren lassen will würde ich ein:

    public void drive(Fahren obj) { .. }
    

    machen.

    In C++ würde man es doch aber eher so machen:

    class Fahrzeug {
       virutal void brumbrum() = 0;
    };
    
    class Auto : public Fahrzeug {
    ...
    };
    
    void drive(Fahrzeug& obj);
    

    Also könnte man Interfaces doch als eine weitere Ebene der Abstraktion ansehen oder ?



  • Shade Of Mine schrieb:

    const-correctness ist in Java keine Katastrophe, sondern einfach ein nicht vorhandenes Konzept.

    Randfrage: Warum? (ich meine, Java rühmt sich ja dafür, besonders sicher zu sein. Wieso gibt es dann einem Anwender keine Möglichkeiten, von dieser Sicherheit zu profitieren?)

    PS: Ich habe nicht vor, hier einen neuen Flamewar zum Thema loszutreten. Ich will nur gerne eine objektive Antwort (wenn das möglich ist).



  • Ich bin Java-Programmierer, deshalb eine Gegenfrage: Wozu braucht man eigentlich so eine const-Funktion? Mir hat es noch nie Schwierigkeiten bereitet, dass eine Funktion nicht const ist. Wenn ich Methoden implementiere, weiß ich doch, was ich verändern oder was ich nicht verändern will.

    Noch eine Erklärung zu Interfaces:

    Haben verschiedene Klassen beispielsweise dieselben Methodendefinitionen, so kann es sinnvoll sein, eine Schnittstelle daraus zu extrahieren. So kann man beispielsweise bei einer Parameterübergabe verlangen, dass man nur Objekte akzeptiert, deren Klassen eine bestimmte Schnittstelle (also eine Sammlung öffentlicher Methoden) implementieren, wenn man sich nur für diese bestimmte Eigenschaft, die durch das Interface beschrieben wird, interessiert.

    Zum Beispiel implementieren die Klassen String, CharBuffer und StringBuffer das CharSequence-Interface, womit man den Klassen die Eigenschaft gibt, eine bestimmte char-Folge zu repräsentieren. So ist es Objekten der Klasse java.util.regex.Pattern auch egal, ob sie einen String, CharBuffer oder StringBuilder splitten (siehe Methode split(CharSequence input)), schließlich interessiert ja nur die char-Folge.

    Damit ist man wesentlich flexibler als mit abstrakten Klassen. Wäre CharSequence eine abstrakte Klasse, könnte beispielsweise java.nio.CharBuffer die char-Folge-Eigenschaft nicht mehr haben, da sie eine Subklasse von java.nio.Buffer ist und es nun mal keine Mehrfachvererbung gibt.



  • Varus schrieb:

    Ich bin Java-Programmierer, deshalb eine Gegenfrage: Wozu braucht man eigentlich so eine const-Funktion? Mir hat es noch nie Schwierigkeiten bereitet, dass eine Funktion nicht const ist. Wenn ich Methoden implementiere, weiß ich doch, was ich verändern oder was ich nicht verändern will.

    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.

    Damit ist man wesentlich flexibler als mit abstrakten Klassen. Wäre CharSequence eine abstrakte Klasse, könnte beispielsweise java.nio.CharBuffer die char-Folge-Eigenschaft nicht mehr haben, da sie eine Subklasse von java.nio.Buffer ist und es nun mal keine Mehrfachvererbung gibt.

    Und das ist wohl auch der Grund, warum es in C++ keine gesonderte Betrachtung für "Interfaces" gibt 😉 (wir haben Mehrfachvererbung)



  • CStoll 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.

    Hm, somit können die Eigenschaften eine const-Objekts von einer fremden Funktionen nicht oder oder nur temporär geändert werden. So hat der Programmierer also Sicherheit, dass an seinem Objekt keine ungewollten Veränderungen durchgeführt werden.

    Aber was soll ein const-Methode? So, wie ich das verstehe, habe ich innerhalb einer solchen Methode keine Möglichkeit Eigenschaften von this zu ändern, oder? Aber, was bringt mir das? Ich weiß doch selbst am besten, was ich verändern darf und welche Veränderungen sinnvoll ist.

    Ich persönlich finde die Handhabung von const in C oder C++ auf den ersten Blick etwas verwirrend. So wie ich das überschaue, kann man dieses Schlüsselwort ja "überall" hinschreiben, und es hat überall eine andere Wirkung. Und ich hatte auch noch keine Probleme damit, dass es dieses Schlüsselwort und seine Möglichkeiten in Java nicht gibt.



  • Varus schrieb:

    CStoll 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.

    Hm, somit können die Eigenschaften eine const-Objekts von einer fremden Funktionen nicht oder oder nur temporär geändert werden. So hat der Programmierer also Sicherheit, dass an seinem Objekt keine ungewollten Veränderungen durchgeführt werden.

    Aber was soll ein const-Methode? So, wie ich das verstehe, habe ich innerhalb einer solchen Methode keine Möglichkeit Eigenschaften von this zu ändern, oder? Aber, was bringt mir das? Ich weiß doch selbst am besten, was ich verändern darf und welche Veränderungen sinnvoll ist.

    Die fremde Funktion darf meine Objekte zwar nicht ändern, aber sie darf Statusinformationen meiner Objekte auslesen - und damit sie dafür nicht an meinen Methoden vorbeigehen muß, gibt es const Methoden (die dürfen zwar interne Daten auslesen, aber nicht ändern - und von einem konstanten Objekt dürfen nur const-Methoden aufgerufen werden).

    Sprich: Wer das Objekt ändern darf, bekommt eine "normale" Referenz übergeben und kann alle Methoden des Objekts nutzen. Wer ein Objekt nicht verändern darf, bekommt eine const-Referenz und darf nur mit dem const-Methoden umgehen (oder das Objekt kopieren und sich an der Kopie austoben).



  • Interfaces und abstrake Klassen unterscheiden sich letztendlich eigentlich nur von der Semantik her. Ich persönlich finde es eigentlich schon gut, dass es das in Java gibt, da man so eben doch semnatische Unterschiede kennzeichnen kann. Ansonsten ist es aber auch kein Weltuntergang, dass es das in C++ nicht gibt. Egal.

    Und bei der const-Geschichte denke ich auch, dass es in Java einfach aus Gründen der Einfachheit weggelassen wurde, bzw. dass es nicht so wie in C++ ist. 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. Den Mechanismus so wie in C++ zu simulieren (bzw. es zu versuchen) macht IMHO tatsächlich keinen Sinn, da soetwas eben einfach nicht vorgesehen wurde.
    Der Mechanismus ist IMHO schon sinnvoll und praktisch, aber auch hier ist das analog kein Weltuntergang dass es das in Java nicht gibt 😉



  • CStoll schrieb:

    Sprich: Wer das Objekt ändern darf, bekommt eine "normale" Referenz übergeben und kann alle Methoden des Objekts nutzen. Wer ein Objekt nicht verändern darf, bekommt eine const-Referenz und darf nur mit dem const-Methoden umgehen (oder das Objekt kopieren und sich an der Kopie austoben).

    OK, danke für die Erklärung. Bin ich wieder ein Stückchen schlauer 🙂



  • CStoll schrieb:

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

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



  • 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 🤡 👎




Anmelden zum Antworten