"to MI or not to MI"
-
Xin schrieb:
volkards Posting verstehe ich nicht
Das ist ein ideologisches Problem.
Lies meins bitte noch mehrmals ganz unvoreingenommen. Es müßte "klick" machen. Bitte, bitte.Ich habe mir so eine Mühe gegeben. Das MUSS man doch verstehen. Ich *kann* Dich auch mit Deinen Beispielen zu widerlegen versuchen, aber es dauert wirklich mir jedesmal zehnmal so viel Zeit, eine jedem (außer Dir) verständliche Widerlegung zu bauen, als Dir es dauert, den Müll reinzupusten. Das ist nicht fair. Und wenn Du dann alles ingnorierst, immer und immer wieder, haben wir konstant ein 1:10-Verhältnis. Das ist nicht ok. Sei mir nicht böse, aber da muss eine andere Basis her, um konstruktiv zu bleiben. Denke, eine Woche habe ich noch Geduld. Danach müssen wir aufgeben und zum Beispiel gegenseitig ein Fachbuch empfehlen, das der andere kauft, nebst Seitenangabe.
-
volkard schrieb:
Xin schrieb:
volkards Posting verstehe ich nicht
Das ist ein ideologisches Problem.
Lies meins bitte noch mehrmals ganz unvoreingenommen. Es müßte "klick" machen. Bitte, bitte.Dass Programme, die nicht fertig geschrieben sind, fehlerhaft funktionieren, halte ich für ziemlich normal.
Ich fasse Deine Kritik aber durchaus auf, sehe da durchaus auch einen interessanten Beitrag, der aber nichts mit Mehrfachvererbung zu tun hat. Das kann Dir auch bei Sprachen passieren, die Mehrfachvererbung gar nicht unterstützen, dafür reicht Vererbung alleine und eben zu vergessen, eine Funktion entsprechend anzupassen.
volkard schrieb:
Ich habe mir so eine Mühe gegeben.
Stimmt, für fünf Zeilen Text dreimal zu korrigieren, fällt eindeutig unter die Kategorie 'Mühe gegeben'.
volkard schrieb:
Denke, eine Woche habe ich noch Geduld. Danach müssen wir aufgeben und zum Beispiel gegenseitig ein Fachbuch empfehlen, das der andere kauft, nebst Seitenangabe.
Das funktioniert nur unter zwei Bedingungen. Erstens: Es gibt ein sinnvolles Fachbuch und zweitens: Es ist nicht abgeschrieben.
Das nennt sich wissenschaftliches Arbeiten. Die Diskussion hatte ich mit einem meiner Profs mal. Man stellt eine Behauptung auf und belegt sie damit, dass ein anderes Fachbuch diese These stützt. So arbeitet man wissenschaftlich.
Blöderweise kommt man irgendwann am ersten Fachbuch an. Der Erste hat sich das aus den Fingern gesaugt, er kann nämlich nichts belegen.
Mein Prof hatte damals ein Argumentationsproblem. Jedenfalls konnte er mir nicht erklären, wieso die zweite Autorengeneration richtig liegen muss, wenn der erste Generation keine Belege für ihre Behauptungen hat und dem Gesichtsausdruck nach, ist ihm das da zum ersten Mal aufgefallen. Er ist Professor, man könnte meinen, dass er sich mit wissenschaftlichen Arbeiten schonmal beschäftigt hat. Ich bin als Student da vergleichsweise Amateur.
Ich bin sicher, Du löst dieses argumentative Problem.Ich schrieb bereits: Unser Verständnis von Programmierung hängt davon ab, was wir die letzten 60 Jahre getan haben, wenn wir programmiert haben. Für meine Sprache habe ich eine ausführliche Umfrage gemacht. Diejenigen, die am wenigsten zum Thema beizutragen hatten, waren Informatiker und erfahrene Programmierer. Die wissen nämlich, wie man's "richtig" macht, die machen das nämlich schon immer so und deswegen denken sie auch nichts anderes. Mathematiker, Ingenieure, Schüler haben da teilweise ganz andere Vorstellungen. Die sind in ihren Vorstellung nicht beschränkt. Die Informatiker fielen mit einem Satz auf "Habe ich mir nie Gedanken drüber gemacht.", denn sie haben ja gelernt, was richtig ist. Wir haben aber nie gelernt unser Verständnis in Frage zu stellen.
Gib mir ein Argument, das ich noch nicht kenne. Fachbücher habe ich selbst genug. Gerade im Bereich Compilerbau und Sprachdesign steht in den meisten nicht viel Interessantes drin. Wenn Du was Gutes für mein Thema weist, nur zu.
-
Xin schrieb:
volkard schrieb:
Xin schrieb:
volkards Posting verstehe ich nicht
Das ist ein ideologisches Problem.
Lies meins bitte noch mehrmals ganz unvoreingenommen. Es müßte "klick" machen. Bitte, bitte.Dass Programme, die nicht fertig geschrieben sind, fehlerhaft funktionieren, halte ich für ziemlich normal.
lölchen
Daß wergen Unfertigkeit Programme Fehler werfen, halte ich für normal. Daß sie einfach fehlerhaft laufen, halte ich für Sünde.
HIER haben wir ein ganz entschiedenes Problem. Mir sind schon Projekte gestorben. Ich weiß, daß es darum geht, so zu programmieren, daß der Compiler Flüchtigkeitsfehler aufdeckt.Xin schrieb:
Ich fasse Deine Kritik aber durchaus auf, sehe da durchaus auch einen interessanten Beitrag, der aber nichts mit Mehrfachvererbung zu tun hat. Das kann Dir auch bei Sprachen passieren, die Mehrfachvererbung gar nicht unterstützen, dafür reicht Vererbung alleine und eben zu vergessen, eine Funktion entsprechend anzupassen.
Das ist auch mein Kritikpunkt.
Mit
class Address : protected Id , public Street , public HouseNumber , public ZipCode , public Town {};
drückst Du aus, daß die Adresse eine Hausnummer IST (und nicht HAT). Mit allen KOnsequenzen. Alles, was eine Hausnummer KANN (Funktion), KANN auch eine Adresse tun. Das ist doch Unfug. Und tödlich.
Java-mäßige Interfaces reinzuerben ist hingegen ok, so mehrfach Du magst. Selten schlau, aber auch selten tödlich.
Xin schrieb:
Ich bin als Student da vergleichsweise Amateur.
Ich bin sicher, Du löst dieses argumentative Problem.Klar doch. Ganz pragmatisch: Es geht nicht anders. Worauf müßte sich zuguterletzt ein Richter im Zivilprozess verlassen, der kein eigenes Fachwissen hat? Bitte auf die Bücher und nicht auf die Wünschelrutengänger, Naturkeilkundler, Verschwörungstheoretiker und Mehrfachvererber.
Xin schrieb:
Ich schrieb bereits: Unser Verständnis von Programmierung hängt davon ab, was wir die letzten 60 Jahre getan haben, wenn wir programmiert haben. Für meine Sprache habe ich eine ausführliche Umfrage gemacht. Diejenigen, die am wenigsten zum Thema beizutragen hatten, waren Informatiker und erfahrene Programmierer.
Mhhm. Vielleicht haben die erfahrenen Programmierer nicht ernst genommen?
Xin schrieb:
Die wissen nämlich, wie man's "richtig" macht, die machen das nämlich schon immer so und deswegen denken sie auch nichts anderes. Mathematiker, Ingenieure, Schüler haben da teilweise ganz andere Vorstellungen.
Klar. Und junge Programmierer auch. Denen ist noch kein Projekt gestorben. :p
Xin schrieb:
Die sind in ihren Vorstellung nicht beschränkt. Die Informatiker fielen mit einem Satz auf "Habe ich mir nie Gedanken drüber gemacht.", denn sie haben ja gelernt, was richtig ist. Wir haben aber nie gelernt unser Verständnis in Frage zu stellen.
Und deswegen hörst Du nicht auf gute Programmierer? Unlogisch. Was soll die Sprache werden? Eine, mit der sich Anfänger schnell anfreunden können, die aber ganz sicher nicht für nicht-winzig-kleine Programme taugt? Ähm haben wir mit Java doch schon. Gut, man müßte noch ein paar Fehler einbauen, um die Anforderung ganz zu erfüllen. MI wäre ganz toll, in der Tat.
Xin schrieb:
Gib mir ein Argument, das ich noch nicht kenne. Fachbücher habe ich selbst genug. Gerade im Bereich Compilerbau und Sprachdesign steht in den meisten nicht viel Interessantes drin. Wenn Du was Gutes für mein Thema weist, nur zu.
Meyers, Effektiv C++ programmieren.
So, und nur zum Positiven:
struct ZipCode : public Integer {};
Das ist eine gute Idee. Allerdings brauchen die eingebauten Typen auch einen gewissen Bestandsschutz. Wie das Verbot der Überladung von Operatoren für eingebaute Typen, denn sonst kommt so ein Schlawiener drauf und definiert die um und alles geht kaputt.
Wenn ich jetzt den Wertebereich für ZipCodes einschränke auf nur 00000 bis 99999, dann können ZipCodes nicht mehr alles, was Integers können. Ich bin sicher, Dir fällt auf, wie bedenklich das ist.
Du hast vererbt, Du hast VERSPROCHEN, daß jeder ZipCode alles kann, was ein Integer kann. Völlig unpassende Dinge wie die Rechenoperationen, falsche Dinge wie Ein-Ausgabe und gute Dinge: das Speicherlayout Konstruktorern, Destruktor und die Vergleichsoperationen. Ähm. Wir weh muss man Dir tun, bis Du anfängst, es andersrum zu machen? Zieh Dir doch nur die Sachen rein, die Du haben magst und als richtig auch absegnen kannst und nur die.
-
@Xin: Wie würde man in deiner Sprache die Klassen "Rectangle" und "Square" in einem Vektorzeichenprogramm definieren. Könnte man diese voneinander ableiten?
MfG SideWinder
-
SideWinder schrieb:
@Xin: Wie würde man in deiner Sprache die Klassen "Rectangle" und "Square" in einem Vektorzeichenprogramm definieren. Könnte man diese voneinander ableiten?
Doppelspoiler. http://pastebin.de/33083
-
SideWinder schrieb:
@Xin: Wie würde man in deiner Sprache die Klassen "Rectangle" und "Square" in einem Vektorzeichenprogramm definieren. Könnte man diese voneinander ableiten?
Wen ableiten wovon?
Rechteck "ist ein" Quadrat mit zusätzlicher Komponente? Quadrat "ist ein" Rechteck mit zwei Komponenten, die identisch sein müssen?
Das hat nichts mit meiner Sprache zu tun, das ist eine sprachunabhängige Designfrage. Ich würde es wohl so modellieren, wobei das hier kein Beispiel von Codeeffizienz darstellt, sondern ein Beispiel meiner Denke:
class X : public Double {} class Y : public Double {} class Punkt : public X , public Y {} class Greifpunkt : public Punkt {} class Grafikobjekt : public Greifpunkt {} class ViereckigesGrafikObjekt : public Grafikobjekt {} class Strecke : public Double {} class Seitenlänge : public Strecke {} class SeitenlängeX : public Strecke {} class SeitenlängeY : public Strecke {} class SeitenlängeXY : public SeitenlängeX {} : public SeitenlängeY {} class Radius : public Strecke {} class Quadrat : public ViereckigesGrafikObjekt , public Seitenlänge {} class Rechteck : public ViereckigesGrafikObjekt , public SeitenlängeXY {} class Kreis : public GrafikObjekt , public Radius {}
Jetzt sagst Du natürlich erstmal zurecht "Was ist das für'n Scheiß, da klassifiziere ich mich ja kaputt, das geht mit Membern VIEL schnell". Das ist richtig, aber Du kannst aber viel weniger Informationen statisch im Datentyp transportieren. Ein Double ist XKoordinate, YKoordinate, Seitenlänge für X und Y oder Seitenlänge für X oder Y... Funktionen fragen immer nur nach double. Möchte ich die Kreisfläche berechnen, frage ich nach Radius, nicht nach double. Ich kann auch nicht versehentlich Quadrate reinwerfen, die ja genauso wie Kreise sind: Ein Punkt mit zusätzlichem Double.
Hier kam das Argument auf, dass die IDE für das Schreiben von Code hilfreich ist. Leider kann die IDE aber nicht bestimmen, welche Funktion die richtige ist und manchmal findet sie zuerst die falsche, dann übergebe ich mein Double und der Bug ist fertig. Das geht hier nicht. Ein Viereck hat keinen Radius => der Compiler verweigert die Kompilierung.In meiner Sprache ist das bedeutend kürzer. Stell Dir das hier nicht als Ziel, sondern als Ausgangspunkt vor, an Du losgehst. Ich schrieb, dass ich in der Mehrfachvererbung Potential sehe, nicht, dass C++ es optimal nutzt. Dies zeigt das zu erreichende Ziel, wie man es in C++ formulieren muss - also leider mit viel Boilerplate: Jedes Datum hat seinen eigenen, eindeutigen Typ.
Ich stelle meine Sprache vor, wenn ich der Meinung bin, es zeigen zu wollen. Für dieses Konzept habe ich die Syntax komplett umgebaut und vielleicht fällt mir irgendwann noch etwas Interessantes ein, was wieder Änderungen mit sich bringt.
Ich habe noch nicht alles ausprobiert und ich habe keinen Bock mit volkard & Co rumzudiskutieren, ob meine Syntax jetzt schon perfekt ist oder nicht. Ich muss so oder so ausprobieren und in der Zwischenzeit hat volkard mir schon oft genug erklärt, dass er - freundlich formuliert - meinen Ansatz nicht schätzt.
Also probiere ich lieber mit ausgewähltem Publikum, das spart mir Zeit. Das Posting gestern waren 2 Stunden, die ich auch für anderes gut hätte gebrauchen konnte - sich aber dank Dir wenigstens gelohnt haben, weil es eben doch immer mal wieder noch kleine "Aha"-Effekte gibt, wenn sich Leute konstruktiv mit den Dingen auseinander setzen. Bedauerlicherweise wissen die meisten aber schon, wie man es richtig macht. Nicht umsonst haben wir soviele Bundestrainer im LandEDIT:
Ich habe diese Klassenhierarchie jetzt mal in meiner Sprache definiert, das sind 9 (durchaus lesbare) Zeilen in der kürzesten Form, bzw. 17, wenn ich die Leerzeilen zwischen jeder einzeiligen Definition dazupacke. Es sind weniger explizite Definitionen erforderlich. 11 Zeilen, wenn ich die Mehrfachvererbungen untereinander schreibe, also 19 mit Leerzeilen.
-
Wie genau verhinderst du jetzt dass ich den Radius von einem Kreis negativ setze?
-
Shade Of Mine schrieb:
Wie genau verhinderst du jetzt dass ich den Radius von einem Kreis negativ setze?
<sarcasm>
Ich glaube, Du hast da ein wesentliches K.O. Kriterium erkannt.Man kann auch keinen Kaffee damit kochen. Ich glaube, ich sollte die Programmierung aufgeben, wenn's nichtmals Kaffee kochen kann.
</sarcasm>PS: Wenn das jetzt ernsthaft die schärfste Kritik von Dir war, die Dir für dieses Beispiel eingefallen ist, dann kann ich so falsch ja gar nicht liegen.
-
Ich fang an zu glauben, dass Xin prädikativ Typen will wie in Cecil.
-
Xin schrieb:
PS: Wenn das jetzt ernsthaft die schärfste Kritik von Dir war, die Dir für dieses Beispiel eingefallen ist, dann kann ich so falsch ja gar nicht liegen.
Es ist eine ernste Frage.
Ich stelle sie mal allgemeiner: wie garantierst du Invarianten?Wenn Postleitzahl von Integer erbt, wie beschraenke ich Postleitzahlen auf 0 bis 99999 ? Oder woher weiss der Kreis, dass sich sein Ursprung geaendert hat um sich neu zuzeichen? Etc.
-
Zeus schrieb:
Ich fang an zu glauben, dass Xin prädikativ Typen will wie in Cecil.
Cecil? Da finde ich Damenmode!? ^^
Habe noch eine Mono-Library gefunden.
Shade Of Mine schrieb:
Es ist eine ernste Frage.
Ich stelle sie mal allgemeiner: wie garantierst du Invarianten?Wie garantiere ich Invarianten mit Membern?
Wenn ich einem Kreis ein double als Radius mitgebe, wie garantiere ich da, dass der Kreis einen positiven Radius besitzt?
Shade Of Mine schrieb:
Wenn Postleitzahl von Integer erbt, wie beschraenke ich Postleitzahlen auf 0 bis 99999 ?
In dem Fall muss ich wohl für PLZ einen Konstruktor schreiben, der das verifiziert und eine Initialisierung mit unzulässigen Werten ggfs. ablehnt, wie ich für Radius auch tun müsste, wenn ich ein Problem mit negativen Radien habe.
Ich sehe hier keinen Unterschied zur Initialisierung von Membern in der Initialisierungsliste - und, je nach Implementierung auch nicht im Konstruktor der Address-Klasse.
Shade Of Mine schrieb:
Oder woher weiss der Kreis, dass sich sein Ursprung geaendert hat um sich neu zuzeichen? Etc.
Auch hier sehe ich das Problem erstmal nicht im Aufbau der Datentypen, Du kannst genauso Events verwenden oder eben den Zugriff auf den Schreibzugriff von Punkt im Grafikobjekt erstmal abfangen. Das wäre allerdings in C++ wieder nicht formulierbar, ohne dass man überladbare Methoden hat. Ich selbst mache zwischen Getter- und Setter-Funktionen und dem direkten Zugriff auf Variablen keinen so großen Unterschied.
Aber es gibt vermutlich noch eine weitere vorstellbare Lösung, die in C++ aber gar nicht formulierbar ist und ich bei mir noch nicht ausprobieren konnte. Soweit ist meine Sprache leider noch nicht. Vielleicht kann ich dazu Ende des Jahres was sagen.
-
Xin schrieb:
Shade Of Mine schrieb:
Wenn Postleitzahl von Integer erbt, wie beschraenke ich Postleitzahlen auf 0 bis 99999 ?
In dem Fall muss ich wohl für PLZ einen Konstruktor schreiben, der das verifiziert und eine Initialisierung mit unzulässigen Werten ggfs. ablehnt, wie ich für Radius auch tun müsste, wenn ich ein Problem mit negativen Radien habe.
Hier sehe ich zwei Probleme. Das erste ist sowas (Pseudocode):
func(Integer& i1, Integer i2) { i1 -= i2; // gültig und definiert für Integer } func(kreis1.radius, kreis2.radius); // huch, plötzlich Fehler, obwohl ein Radius ein Integer ist
Radius ist hier Integer statt Double der Einfachheit halber, das Argument ist dasselbe.
Das Problem hat man mit Membern nicht, da beikreis1.setRadius(kreis1.getRadius() - kreis2.getRadius())
eben nicht garantiert ist, dass das keinen Fehler wirft, im Gegensatz zum
-=
bei Integern.Das zweite ist, dass es bei deiner Klassenhierarchie ja eigentlich heißen müsste:
func(kreis1, kreis2)
Aber welcher Integer beim Kreis ist denn gemeint? Radius, Durchmesser, Umfang? Gut, hier könnte man es sich eventuell denken, aber was ist beim Rechteck?
Das „is-a“, was immer so runtergebetet wird, hat ja einen Grund: A is-a B ⇒ A kann wie ein B behandelt werden. Und ich sehe hier nicht, dass ich einen Kreis oder ein Rechteck wie einen Integer behandeln kann.
-
Xin schrieb:
In dem Fall muss ich wohl für PLZ einen Konstruktor schreiben, der das verifiziert und eine Initialisierung mit unzulässigen Werten ggfs. ablehnt, wie ich für Radius auch tun müsste, wenn ich ein Problem mit negativen Radien habe.
Ich sehe hier keinen Unterschied zur Initialisierung von Membern in der Initialisierungsliste - und, je nach Implementierung auch nicht im Konstruktor der Address-Klasse.
Was wenn ich jetzt aber:
void add(Integer& lhs, Integer& rhs) { lhs+=rhs; } Postleitzahl plz(12345); add(plz, 700000);
schreibe?
Der Ctor von Postleitzahl validiert 12345 korrekt und es passt. Nun addiert add aber 700000 drauf und wir haben eine ungueltige Postleitzahl. Was tust du hier um das zu verhindern?
In Postleitzahl kannst du den operator+= fuer Integer ja nicht neu definieren - es sei denn der waere virtual. Ist er das?
Bzw: wie verhinderst du, dass ich Sachen mache die keinen Sinn ergeben: zB eine Postleitzahl mit einer Telefonnummer zumultiplizieren?
Mich interessiert dabei die Umsetzung in C++ (wir koennen uns auch gerne auf eine andere Sprache einigen). Deine Sprache wuerde ich aus der Diskussion lieber raus lassen, da es keine Sprache ist die wir beide kennen.
-
ipsec schrieb:
Xin schrieb:
Shade Of Mine schrieb:
Wenn Postleitzahl von Integer erbt, wie beschraenke ich Postleitzahlen auf 0 bis 99999 ?
In dem Fall muss ich wohl für PLZ einen Konstruktor schreiben, der das verifiziert und eine Initialisierung mit unzulässigen Werten ggfs. ablehnt, wie ich für Radius auch tun müsste, wenn ich ein Problem mit negativen Radien habe.
Hier sehe ich zwei Probleme. Das erste ist sowas (Pseudocode):
func(Integer& i1, Integer i2) { i1 -= i2; // gültig und definiert für Integer } func(kreis1.radius, kreis2.radius); // huch, plötzlich Fehler, obwohl ein Radius ein Integer ist
Radius ist hier Integer statt Double der Einfachheit halber, das Argument ist dasselbe.
Das Argument ist sehr gut und bekannt.
Fakt ist, dass ein Klasse, die eine Einschränkung ihrer Basis hat, natürlich nicht public erben darf. Ein Kreis mit einem öffentlichen Member double Radius kann auch zerlegt werden und zwar genauso, wie Du es beschrieben hast. Es gilt also Inhalt von Integer zu schützen.
Eine Klasse Radius darf diese Operationen also nicht öffentlich erben, wenn sie Einschränkungen macht. Im Prinzip ist das eine protected Ableitung mit einem operator Integer & const(). Radius darf Integer modifizieren, externe haben kein Zugriffsrecht. Du kannst zum Beispiel einen (Integer const &) zurückgeben, aber den bekommst Du nicht mit dem -= Operator verbogen. Also entweder beschreibst Du in Radius, was Du mit dem Radius machen darfst oder Du kannst ihn nicht in eine Funktion packen,
ipsec schrieb:
Das zweite ist, dass es bei deiner Klassenhierarchie ja eigentlich heißen müsste:
func(kreis1, kreis2)
Aber welcher Integer beim Kreis ist denn gemeint? Radius, Durchmesser, Umfang? Gut, hier könnte man es sich eventuell denken, aber was ist beim Rechteck?
Auch ein schöner Punkt, der aber durchaus auch in C++ bekannt und gelöst ist. Wenn Du das in C++ so formulierst, wird Dir C++ sagen, dass er eben auch nicht weiß, welchen Integer er hier jetzt reinwerfen soll. Da die Funktion nicht klar festlegt, welchen Integer sie wünscht, also ob Radius, Durchmesser oder Umfang, muss sie ja so allgemein gehalten sein, dass ihr ein beliebiger Integer zur Verarbeitung reicht.
Und da haben wir natürlich Auswahl und müssen uns selbst festlegen.
In C++ müsstest Du Dich über ein Casting eindeutig ausdrücken. Da sieht in C++ unschön aus, ist aber an der Stelle das Gleiche wie this->Radius: eine Addition auf die Adresse auf die this zeigt.ipsec schrieb:
Das „is-a“, was immer so runtergebetet wird, hat ja einen Grund: A is-a B ⇒ A kann wie ein B behandelt werden. Und ich sehe hier nicht, dass ich einen Kreis oder ein Rechteck wie einen Integer behandeln kann.
Bitte die Bibel weglegen und das beten einstellen. Die Gedanken sind frei!
"is-a" ist nur ein Konzept, dass mit Vererbung beschrieben wird. Stell Dir Kreis als Ableitung von RadiusInterface vor. Damit ist Kreis ein "GetRadiusFunctionProvider" und das wiederum ist ein Integer. Und jetzt lassen wir den ganzen Unsinn weg wieder und sagen "einfach":
printInteger( this->Radius::Value );
oder
printInteger( this->Umfang::Value );Wohlgemerkt: Das ist C++... die Sprache, die für Member ausgelegt ist und ich behaupte, dass Mehrfachvererbung und Member erstmal beide die gleiche Aufgabe erfüllen. Das heißt nicht, dass die Syntax in C++ wunderschön ist, noch dass ich ausschließlich alles public machen will. Ich will nur Vorteile von Mehrfachvererbung allgemeiner nutzen.
Trotzdem: das war bisher eins der besten Postings, die zu dem Thema jemals gekommen sind.
-
Xin schrieb:
Eine Klasse Radius darf diese Operationen also nicht öffentlich erben, wenn sie Einschränkungen macht.
OK. Jetzt verwirrst du mich.
Kannst du dein Rechteck/Kreis Beispiel dann nochmal herzeigen mit protected Vererbung?Weil bis jetzt bin ich von public Vererbung ausgegangen...
-
-.- bitte löschen, danke
-
Xin schrieb:
Fakt ist, dass ein Klasse, die eine Einschränkung ihrer Basis hat, natürlich nicht public erben darf.
Und private auch nicht.
Deswegen schrieb ich mein Beispiel so, daß der Mensch tot wird aus einer Mensch::-Funktion aufgerufen! Auch privat haben wir den Ärger, wenn man Konzepte vermischt. Plötzliches Frühableben ist ehrlich suboptimal.Zugegeben, C++ ist schwach und unterstützt native weder Mixins noch Interfaces.
Du solltest nicht den Fehler begehen, das zu ignorieren. Mach doch Sprachmittel dafür. Du kannst es. Für beide!
-
@Xin: Ich befürchte du missbrauchst Vererbung für eine Art von Typsicherheit die man einfacher, besser und "richtiger benannt" haben kann.
Ein Quadrat ist nunmal keine Seitenlänge, und genau das sagt aber deine Vererbung aus. Ein Quadart "HAT" eine Seitenlänge, es besitzt eine Seitenlänge.Wenn du eigentlich sagen willst, "dieser int ist vom Typ Seitenlänge und hier dürfen damit nur Werte >0 eingetragen werden und ich kann die Seitenlänge nur mit einem expliziten Cast auch als Radius in einen Kreis schreiben" dann willst du nict Vererbung sondern etwas anderes.
BTW: Mit Vererbung könntest du irgendwie niemals ein Quadrat auf die Seitenlänge eines Radius setzen, oder? Schreibt man da dann tausende Konvertierungs-Operatoren in deiner Sprache?
Ich hoffe auch, dass die Typsicherheit in Server-lastigen Programmiersprachen (also Sprachen wie Java/C# und auch C++ (client ja erstmal nur noch JS...)) noch weiter erhöht wird. Aber bitte nicht durch Missbauch von Vererbung.
Da nimmst du ja quasi eine Krücke die dir C++ dafür bieten kann und baust an der Krücke solange außen dran bis sie in deiner Sprache mehr schlecht als recht kann was du willst, obwohl es viel einfachere Möglichkeiten gäbe.
Ich kann mich leider nicht mehr zu 100% an meine Haskell-Stunden erinnern, aber afaik bietet das Haskell-Typsystem da einige Möglichkeiten die du suchst...
(Teilweise geschieht dies btw auch schon in Hochsprachen> durch Attributes für Validierung, etc. Teilweise werden asserts() in Konstruktoren geschrieben, usw., aber ja, die "Hochsprachen" sind leider noch nicht ganz bereit dafür)
MfG SideWinder
-
Shade Of Mine schrieb:
Der Ctor von Postleitzahl validiert 12345 korrekt und es passt. Nun addiert add aber 700000 drauf und wir haben eine ungueltige Postleitzahl. Was tust du hier um das zu verhindern?
Irgendwie scheint mir dieses Gegenargument überhaupt nicht zu passen. Eine Programmiersprache oder auch nur Programmierkonzepte hindern einen Entwickler doch nicht daran, dumme Sachen zu machen? Und Postleitzahl von Integer erben zu lassen ist doch eher eine unsinnige Sache. Zumindest kann ich da jetzt nicht erkennen, inwiefern das als Gegenargument dienen soll?
Da man PLZ niemals addieren wird, macht es auch absolut keinen Sinn, die von Integer erben zu lassen.
-
Abgesehen davon sind längst nicht alle Zahlen zwischen 0 und 99999 valide PLZ.