Hallo, ich bin neu hier und habe eine Frage zu Java-Interfaces:
Es gibt eine Klasse, die enthält zwei Methoden M1 und M2 und sie
implemetiert ein Interface, in dem aber nur der Kopf von M1 drinsteht.
Trotzdem verfügt ein aus der Klasse abgeleitetes Objekt über beide
Methoden. Wieso? Sollte denn nicht nur M1 "sichtbar" sein?
Dank für Erhellendes.
Hast du mal Beispielcode?
Wenn deine Variable vom Typ des Interfaces ist, sollte M2 nicht so ohne
weiteres Sichtbar sein, wenn es jedoch vom Typ des Objektes ist, muss M2
sichtbar sein. (Vorrausgesetzt M2 ist public)
Korrektur: Die beiden Methoden in Democlass sind NICHT mehr privat, die
sind public, das warnur ein Versuch. Ich kann als Gast den Beitrag
nicht mehr korrigieren.
yesitsme schrieb:>> DemoClass dc>> Natürlich ist in DemoClass Method2() bekannt.>> Versuch mal>> Interface_1 dc = new DemoClass();
Bingo! Danke. Und eigentlich auch logisch ... :-)
Genauso verhält es sich übrigens auch mit Klassen.
Angenommen du hast eine einfache Klasse (nennen wir sie mal Simple) mit
der Methode m1().
Jetzt leitest du davon eine Klasse ab (class Extended extends Simple)
und implementierst dort die Methode m2().
Ein Objekt der Klasse Extended hat selbstverständlich die Methoden m1
und m2.
Wenn du es in einer Variable vom Typ Simple speicherst kannst du jedoch
nur auf m1 zugreifen.
Anfänger schrieb:> Tilo R. schrieb:>> Wenn du es in einer Variable vom Typ Simple>> Welchem Datentyp entspricht denn der Simple-Typ in C?
Natürlich keinem. C ist keine OOP-Sprache und hat dementsprechend keine
Ahnung von Klassen, Vererbung und Polymorphie.
Die Funktionalität kann man in C zwar nachbauen, aber das ist Sackstand.
Anfänger schrieb:> Tilo R. schrieb:>> Wenn du es in einer Variable vom Typ Simple>> Welchem Datentyp entspricht denn der Simple-Typ in C?
Alles was in ein CPU-Register passt, wie z.B. int.
Anfänger schrieb:> Tilo R. schrieb:>> Wenn du es in einer Variable vom Typ Simple>> Welchem Datentyp entspricht denn der Simple-Typ in C?
Der sollte ja nur ein Beispiel sein, ein placeholder für einen
beliebigen Datentyp.
Datentypen/Datenstrukturen hat man auch in C. Methoden und Vererbung
aber nicht. Dies ist jedoch ein Vorteil, es macht die Sprache simpler,
und vermeidet fundamentale Logikprobleme, die OOP Inhärent sind, wie
z.B. das Kreis-Ellipse-Problem
https://de.wikipedia.org/wiki/Kreis-Ellipse-Problem
Alle Vererbungssachen (ausser die Diamond-Vererbung) kann man in C durch
Komposition ersetzen. In C kommt garantiert niemand auf die absurde
Idee, ein Kreis könne eine Ellipse sein oder umgekehrt, (Obwohl, man
könnte eine Ellipse als 2 Kreise beinhaltend betrachten, das löst das
Problem aber auch ganz von alleine.). Bei klassischer
"Mehrfachvererbung", enthält das strukt halt nachher mehrere Member
variablen des "Basistypes", die Ambiguität, auf welche Instanz man sich
bezieht, entfällt automatisch.
Das echte Killerfeature ist aber die Absenz von Methoden. Bei OOP sind
Methoden an ein Objekt gebunden, wegen der absurden Notion, die Objekte,
also die Daten, können Aktionen ausführen. In den meisten
fällen/sprachen heisst das unter anderem, Methoden müssen schon bei der
Definition der Klasse bekannt sein. Zudem kommt es zu
Zuständigkeitsproblemen, wenn mehrere Objekte involviert sind (z.B.
Klont sich A nach B, oder B von A?) (und dass sind erst 2 Objekte!). In
C hingegen hat man Funktionen, diese nehmen die Objekte als Argumente.
Funktionen tun also Dinge, und verändern dabei Daten. So kann man auch
Methoden direkt nach Funktionen konvertieren, aber ohne die
Limitationen, man kann zwar die Argumente anders anordnen, aber das
macht keinen Unterschied mehr, anders, als wenn man eine Methode in eine
andere Klasse verschieben würde! Und wenn man eine neue Funktion
braucht, kein Problem, die kann man überall, oder in bestimmten
Kontexten einfach dazupacken/linken! Und wenn man gemeinsamen Code in
Funktionen auslagert, hat wo man diese ablegt später meist ebenfalls
weniger problematische Seiteneffekte, weil es effektiv egal sind, wo
diese Stehen. (Was aber nicht heisst, dass man sein Projekt nicht auch
ohne Methoden kaputtdesignen/Kaputabstrahieren könnte.)
Auch Interfaces sind in C sehr schön. Je nach Anwendungsfall nimmt man
ein Headerfile mit Funktionsdeklarationen, oder ein paar Simple
Funktionspointer in einem Strukt. Zugegeben, Java Interfaces sind
schöner, aber was man in C++ bekommt ist definitiv eine Katastrophe.
Es gäbe schon ein paar dinge, die in C noch schön gewesen wären, diese
sind aber nicht unbedingt typisch OOP. z.B. schon beim Linken aus
mehreren Orten zusammengesetzte Listen. Oder Namespaces, ich liebe
Namespaces. Aber man kann halt nicht alles haben.
DPA schrieb:> Datentypen/Datenstrukturen hat man auch in C. Methoden und Vererbung> aber nicht. Dies ist jedoch ein Vorteil, es macht die Sprache simpler,> und vermeidet fundamentale Logikprobleme, die OOP Inhärent sind, wie> z.B. das Kreis-Ellipse-Problem
Nein, natürlich vermeidet es das nicht. Denn die besten der OOP-Lösungen
"scheitern" nur daran, dass entweder die Vererbungstiefe um eins erhöht
werden muss oder alternativ redundanter Code entsteht.
Genau so sehen die Alternativen allerdings auch in C aus. Wenn du OO in
C nachbaust, hast du immerhin auch diese beiden Alternativen, wenn
nicht, hast du IMMER den redundanten Code.
> Alle Vererbungssachen (ausser die Diamond-Vererbung) kann man in C durch> Komposition ersetzen.
Genau das ist der Sackstand. OOP macht letztlich ja auch nix anderes.
Der Vorteil ist: man braucht sich nicht selber drum zu kümmern, sondern
einfach nur die richtigen Sprachelemente zu verwenden und der ganze
Prassel läuft von allein...
> Das echte Killerfeature ist aber die Absenz von Methoden. Bei OOP sind> Methoden an ein Objekt gebunden
Nö. Das stimmt schlicht nicht. Hast du noch nie was von statischen
Methoden gehört? Die sind nicht an ein Objekt gebunden. Merke: ein
Klasse ist KEIN Objekt, sondern üblicherweise der Bauplan für eins.
Und es gibt aber auch Klassen, die taugen (absichtlich) nicht als
Objektbaupläne, sondern nur als Sammlung statischer Methoden.
Heraus kommt (auf Maschinenebene) letztlich genau dasselbe, als wenn du
in C einen Arschvoll Funktionen in eine Lib packst.
Kurzfassung: du hast einfach keine wirkliche Ahnung von OOP...
c-hater schrieb:> DPA schrieb:>>> Datentypen/Datenstrukturen hat man auch in C. Methoden und Vererbung>> aber nicht. Dies ist jedoch ein Vorteil, es macht die Sprache simpler,>> und vermeidet fundamentale Logikprobleme, die OOP Inhärent sind, wie>> z.B. das Kreis-Ellipse-Problem>> Nein, natürlich vermeidet es das nicht. Denn die besten der OOP-Lösungen> "scheitern" nur daran, dass entweder die Vererbungstiefe um eins erhöht> werden muss oder alternativ redundanter Code entsteht.>> Genau so sehen die Alternativen allerdings auch in C aus. Wenn du OO in> C nachbaust, hast du immerhin auch diese beiden Alternativen, wenn> nicht, hast du IMMER den redundanten Code.
Obwohl man die klassischen OOP Fehler in C auch absichtlich nachbauen
könnte, sind C Programme aufgrund der fehlenden Vererbung auf
Sprachbasis auf andere Grund primitive aufgebaut, womit sich ändert, wie
man Code schreibt und darüber denkt. Und doch, das effektiv vermeidet
die OOP Probleme in der Praxis sehr wohl. Sag mal einem C und einem Java
Programmierer, er solle ein Programm mit einen Kreis und eine Ellipse
modellieren, was glaubst du, wird der Programmierer am
wahrscheinlichsten tun? Natürlich, das eine vom andern ableiten! Die OOP
Strukturen des Programms verleiten ja regelrecht dazu, den Fehler zu
machen. Nun, wenn ein C Programmierer den Fehler absichtlich nach
programmieren wollte, wie sähe das aus? Vermutlich etwa so:
1
structcircle{
2
floatr;
3
};
4
5
structellipsis{
6
structcirclebase;
7
intdy;
8
};
Oder halt umgekehrt, je nachdem, wie herum man das Problem betrachtet:
1
structellipsis{
2
floatdx,dy;
3
};
4
5
structcircle{
6
structellipsisbase;
7
};
Wenn man das so liest, dann kann man gar nicht übersehen, was für ein
Schwachsinn das ist. In C denkt keiner als erstes "Oh, ja, ein Kreis ist
eine Ellipse" oder "Oh, ja, eine Ellipse ist ein Kreis", und merken dann
später "Oh, mist, da passt was nicht zusammen...". Die machen einfach
einen Kreis und eine Ellipse, fertig:
1
structellipsis{
2
floatdx,dy;
3
};
4
structcircle{
5
floatr;
6
};
Eventuell kommt einer noch auf die Idee, die Ellipse mit In-, Umkreis
und Winkel zu definieren, oder durch 2 Kreise, die die Ecken an den
Achsen berühren, aber das sind auch eine valide Lösung:
[c]
struct circle {
float r;
};
struct ellipsis {
struct circle circle_touching_x_axis;
struct circle circle_touching_y_axis;
};
[c]
Man merke die Architektonische Änderung zu von "ist" zu "hat"
Beziehungen, und wie diese das Problem praktisch von selbst lösten.
(Die 2 falschen C++ Vererbungsvarianten lasse ich mal weg, die währen
länger, und wie die aussehen würden weiss ja wohl jeder.
>> Alle Vererbungssachen (ausser die Diamond-Vererbung) kann man in C durch>> Komposition ersetzen.>> Genau das ist der Sackstand. OOP macht letztlich ja auch nix anderes.> Der Vorteil ist: man braucht sich nicht selber drum zu kümmern, sondern> einfach nur die richtigen Sprachelemente zu verwenden und der ganze> Prassel läuft von allein...
Ja, es schreibt sich quasi ganz von alleine falsch, beeindruckend! Wenn
man dann merkt, dass man Vererbung und Komposition vertauscht, oder die
Hirarchie/Abstraktionsebene falsch gewählt hat, und den Designfehler
(man merke, ich rede nicht von Programmfehlern, sondern von den
aufwendiger zu behebenden Designfehlern), darf man all die Orte, wo das
vorher verwendet wurde, wieder Neuschreiben, eventuell sogar das ganze
Projekt, wenn es was fundamentales war!
>> Das echte Killerfeature ist aber die Absenz von Methoden. Bei OOP sind>> Methoden an ein Objekt gebunden>> Nö. Das stimmt schlicht nicht. Hast du noch nie was von statischen> Methoden gehört?
Ja, die kenne ich, ich Argumentiere hier aber über die den üblichen,
ganz normalen Methoden, nicht über die Statischen. Das es die auch gäbe,
ist für mein Argument irrelevant.
> Die sind nicht an ein Objekt gebunden. Merke: ein> Klasse ist KEIN Objekt, sondern üblicherweise der Bauplan für eins.> Und es gibt aber auch Klassen, die taugen (absichtlich) nicht als> Objektbaupläne, sondern nur als Sammlung statischer Methoden.
Ja, kenne ich, wenn etwa nicht in das OOP Schema "Alles ist ein Objekt"
passt, macht man einfach eine utillity Klasse mit statischen Methoden.
Aus nicht-OOP sicht sind das einfach nur Funktionen in Namespaces.
> Heraus kommt (auf Maschinenebene) letztlich genau dasselbe, als wenn du> in C einen Arschvoll Funktionen in eine Lib packst.
Ich hab auch nie etwas anderes behauptet. Aber da ich ja nicht auf
Maschinenebene Code schreibe, geht mir was hinten raus kommt ehrlich
gesagt ziemlich am Arsch vorbei.
> Kurzfassung: du hast einfach keine wirkliche Ahnung von OOP...
Doch, ich hatte das sowohl formal in der Schule, inklusive UML
Diagrammen und dem Mist, als auch in der Praxis, damals, als ich meine
Programme noch hauptsächlich mit C++ und Java geschrieben habe. (Ich
kenne jedes Sprachelement in Java, jedes in C++ (aber nur bis und mit
C++11)). Ich bin auch sehr gut in der Prototypenbasierten Sprache
JavaScript aus, sowohl die alten Versionen, wie auch mit den neuen ES6,
ES7, etc. die mittlerweile auch "echte" Klassen haben. Trotzdem bleib
ich dabei, dass Vererbung und Methoden als Sprachfeature ein Fehler
waren. Aber wie sagt man so schön, wenn dein einziges Werkzeug ein
Hammer ist, sieht jedes Problem wie ein Nagel aus. Objektorientierte
Programmierung ist nur eines von tausenden Paradigmen, erweitere deinen
Horizont mal etwas!
c-hater schrieb:> wenn nicht, hast du IMMER den redundanten Code.
Man braucht kein Objekt, um identischen Code in 2 Funktionen in 1
Funktion auszulagern.