mikrocontroller.net

Forum: PC-Programmierung Java: Interfaces


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: JavaNeuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: yesitsme (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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)

Autor: JavaNeuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
yesitsme schrieb:
> Hast du mal Beispielcode?
class DemoClass implements Interface_1{
  public DemoClass() {}
  
  private void Method1()
  {
    System.out.println("Methode 1");
  }
  
  private void Method2()
  {
    System.out.println("Methode 2");
  }    
}
Interface Interface_1{
  public void Method1();
}
Interface Interface_2{
  public void Method2();
}
public class Interface1 {

  public static void main(String[] args){
    DemoClass dc = new DemoClass();
    dc.Method1();
    dc.Method2(); //<--- keine Fehlermeldung
  }
}

Autor: JavaNeuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: yesitsme (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> DemoClass dc

Natürlich ist in DemoClass Method2() bekannt.

Versuch mal
> Interface_1 dc = new DemoClass();

Autor: JavaNeuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
yesitsme schrieb:
>> DemoClass dc
>
> Natürlich ist in DemoClass Method2() bekannt.
>
> Versuch mal
>> Interface_1 dc = new DemoClass();

Bingo! Danke. Und eigentlich auch logisch ... :-)

Autor: Tilo R. (joey5337) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tilo R. schrieb:
> Wenn du es in einer Variable vom Typ Simple

Welchem Datentyp entspricht denn der Simple-Typ in C?

Autor: c-hater (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: yesitsme (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: DPA (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
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.

Autor: c-hater (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: DPA (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
struct circle {
  float r;
};

struct ellipsis {
  struct circle base;
  int dy;
};
Oder halt umgekehrt, je nachdem, wie herum man das Problem betrachtet:
struct ellipsis {
  float dx, dy;
};

struct circle {
  struct ellipsis base;
};

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:
struct ellipsis {
  float dx, dy;
};
struct circle {
  float r;
};

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!

Autor: DPA (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.