Polymorphie Interfaces und statischer Typ

Bitte aktiviere JavaScript!
Habe eine Frage zur Vererbung von Interfaces, nehmen wir an ich habe eine Klasse die ein Interface implementiert mit einer Methode x und diese Klasse hat mehrere Methoden wie foo bar etc.

Sagen wir ich habe eine high modul Klassen die dieses Interface instanzieren.

Meine Frage ist kann diese high modul klasse nur auf diese eine Methode x zugreifen von dem Objekt welches das interface implementiert oder kann er auch auf foo und bar zugreifen.


Ich würde ausprobieren aber sitze in der Uni und kein Laptop.

Also ich glaube der kann nur auf x zugreifen aber.
 
A

Anzeige


Vielleicht hilft dir dieser Kurs hier weiter: (hier klicken)
Also was verstehst Du unter "auf die Methode zugreifen"? Das ist nicht ganz deutlich.

Generell: Da die Instanz diese Methoden hat, kannst Du diese auch aufrufen. Diese Aufrufe kannst Du in Java aber nicht direkt machen, da Java ja erst einmal nur weiß, dass die Variable vom Typ des Interfaces ist. Daher musst Du entweder:
- Die Instanz zu dem eigentlichen Typ casten und dann kannst Du die Methoden aufrufen.
- Reflection nutzen um die Methoden zu bekommen und um diese dann aufzurufen.
 
Also was verstehst Du unter "auf die Methode zugreifen"? Das ist nicht ganz deutlich.

Generell: Da die Instanz diese Methoden hat, kannst Du diese auch aufrufen. Diese Aufrufe kannst Du in Java aber nicht direkt machen, da Java ja erst einmal nur weiß, dass die Variable vom Typ des Interfaces ist. Daher musst Du entweder:
- Die Instanz zu dem eigentlichen Typ casten und dann kannst Du die Methoden aufrufen.
- Reflection nutzen um die Methoden zu bekommen und um diese dann aufzurufen.
Aber die Klasse hat nur das Interface als Instanz nicht das Objekt welches das Interface implantiert.

Dann kann diese Klasse doch nur auf die Methoden zugreifen Die auch in Interface implementiert wurden.
 
Die Bitte, die bei deinen Beiträgen etwas Mühe zu geben und nicht X Beiträge mit gleichem Inhalt direkt hintereinander zu posten, gilt immer noch...
 
Habe eine Frage zur Vererbung von Interfaces, nehmen wir an ich habe eine Klasse die ein Interface implementiert mit einer Methode x und diese Klasse hat mehrere Methoden wie foo bar etc.

Sagen wir ich habe eine high modul Klassen die dieses Interface instanzieren.

Meine Frage ist kann diese high modul klasse nur auf diese eine Methode x zugreifen von dem Objekt welches das interface implementiert oder kann er auch auf foo und bar zugreifen.


Ich würde ausprobieren aber sitze in der Uni und kein Laptop.

Also ich glaube der kann nur auf x zugreifen aber.
Ich würde mal bitten, die Fragen nachvollziehbar zu stellen. Bis jetzt weiß ich immer noch nicht, was du willst. Nutze den CODE-Tag, und schreibe Pseudocode, dann kann man nachvollziehen, was du genau wissen willst.

Gegeben sein ein "Interface inter{/*...*/}", und eine Klasse "class imp implements inter{/* ...*/}" usw.
 
Aber die Klasse hat nur das Interface als Instanz nicht das Objekt welches das Interface implantiert.

Dann kann diese Klasse doch nur auf die Methoden zugreifen Die auch in Interface implementiert wurden.
Also eigentlich solltest Du doch inzwischen ein gewisses Basiswissen zu Java haben. Aber Dir scheinen ja die wichtigsten Grundlagen zu fehlen!

Java:
SomeType variableName;
Dies deklariert eine Variable "variableName" vom Typ SomeType.
Wir gehen jetzt davon aus, dass SomeType ein Interface oder eine Klasse ist!
Nun kann man diese Variable nutzen.
Zuweisung: Man kann dieser Variablen nur Instanzen zugewiesen werden von einer Klasse, die entweder SomeType ist, SomeType implementiert (SomeType ist ein Interface) oder von SomeType erbt (SomeType ist eine Klasse). Umgangssprachlich sagt man dann, dass die Instanz ein SomeType ist. (Ausnahme: null kann auch zugewiesen werden!)

Zugriff auf Elemente von SomeType: Da nur Instanzen zugewiesen werden können, die SomeType sind, kann man in Java nun alle Elemente (Methoden, Felder, ...) direkt nutzen, so die Sichtbarkeit entsprechend gegeben ist.

Also ein kleiner Test:
Java:
import java.io.*;

public class Test {
   
    public interface A {
        void a();
    }
   
    public class AImpl1 implements A {
        public void a() { System.out.println("AImpl1"); }
    }

    public class AImpl2 implements A {
        public void a() { System.out.println("AImpl2"); }
    }
   
    public void test() {
        A test; // Eine Variable vom Typ A.
        test = new AImpl1(); // Wir weisen eine neue Instanz von AImpl1 zu.
        test.a(); // AImpl1 wird natürlich ausgegeben.
        System.out.println(test.getClass().getName()); // Test$AImpl1
        test = new AImpl2(); // Wir weisen eine neue Instanz von AImpl2 zu.
        test.a(); // AImpl2 wird natürlich ausgegeben.
        System.out.println(test.getClass().getName()); // Test$AImpl2

        test = new A() {
            public void a() { System.out.println("Ohne Name"); }
        };
        test.a(); // Ohne Name
        System.out.println(test.getClass().getName()); // Test$1 weil 1. annonyme Klasse in Test
    }

    public static void main (String[] args) {
        new Test().test();
    }
}
Also hier sieht man: Auch wenn ich die neue Instanz von AImpl1 in die Variable vom Typ A stecke: Es ist immer noch eine AImpl1 Instanz!

Oder mal ganz einfach visuell für Dumme:
Du hast eine Tüte, da kannst Du nur Obst rein tun.
Und nun tust Du da einen Apfel rein. Apfel ist ja Obst.

Was hast Du jetzt in der Tüte? Doch immer noch einen Apfel. Und natürlich kannst Du den nun auch schälen. Obst selbst bietet das nicht an, den gewisse Obstsorten werden nun einmal nicht geschält. Das ist der Fall mit dem Cast:

Du packst also "Obst" aus der Tüte aus.
-> Ist es ist ein Apfel? Ja! Toll, nun behandel ich es wie ein Apfel und schäle den Apfel.

Reflection wäre etwas anderes:
-> Ich hole das Objekt aus der Tüte. Mir ist absolut egal, was es ist aber ich prüfe, ob es dieses Objekt "Schälen" anbietet. Wenn ja, dann wird das Objekt einfach geschält.
Klar, in der Tüte kann kein gekochtes Ei sein, aber dieser Reflection Code würde auch bei einem gekochten Ei funktionieren, einfach nur, weil es geschält werden kann.

Edit: Noch den Fall der Annonymen Klasse hinzugefügt!
 
Zuletzt bearbeitet:
Also kann er nicht auf andere Methoden zugreifen die in Interface nicht deklariert sind.
Das kommt darauf an, wie du das Objekt hälst. Beispiel:

Java:
public Interface Schwimmfähig {
    public void schwimmen();
}


public class Panzer implements Schwimmfähig{
    
    public void fahren(){
    }
    
    public void schießen(){
    }
    
    @Override
    public void schwimmen(){
    }
}

public class Ente implements Schwimmfähig{
    
    public void quaken(){
    }
    
    @Override
    public void schwimmen(){
    }
}

public void schwimmÜberDenTeich(Schwimmfähig schwimmer){
    schwimmer.schwimmen(); //Ist das jetzt ein Panzer? Oder eine Ente? Oder was anderes?
}


public static int main(String[] args){
    //Das geht:
    Panzer schwimmfähigerPanzer = new Panzer();
    Panzer.schwimmen();
    Panzer.schießen();
    
    //Das geht auch:
    Ente entchen = new Ente();
    entchen.schwimmen();
    entchen.quaken();
    
    //Schaue dir jetzt die Methodenaufrufe an:
    schwimmÜberDenTeich(schwimmfähigerPanzer);
    schwimmÜberDenTeich(entchen);
}
Es kann dir - dem Interface sei Dank - völlig egal sein mit was du die Methode schwimmÜberDenTeich() fütterst. Du weißt, daß du bei einem Objekt, daß das Interface implementiert hat, einen bestimmten Satz an Methoden erwarten kannst und damit irgendwas tun kannst. Stell dir vor, es soll irgendwann mal eine Klasse 'Schiff' erstellt werden, von der du heute noch gar nichts weißt. Aber das Schiff soll über den Teich schwimmen, mit deiner Methode schwimmÜberDenTeich().
Da du über den Rest des Objekts ja nichts wissen mußt - außer daß es die Methode schwimmen() implementiert hat - kann dir das ganz entspannt egal sein.
 
Das kommt darauf an, wie du das Objekt hälst. Beispiel:

Java:
public Interface Schwimmfähig {
    public void schwimmen();
}


public class Panzer implements Schwimmfähig{
   
    public void fahren(){
    }
   
    public void schießen(){
    }
   
    @Override
    public void schwimmen(){
    }
}

public class Ente implements Schwimmfähig{
   
    public void quaken(){
    }
   
    @Override
    public void schwimmen(){
    }
}

public void schwimmÜberDenTeich(Schwimmfähig schwimmer){
    schwimmer.schwimmen(); //Ist das jetzt ein Panzer? Oder eine Ente? Oder was anderes?
}


public static int main(String[] args){
    //Das geht:
    Panzer schwimmfähigerPanzer = new Panzer();
    Panzer.schwimmen();
    Panzer.schießen();
   
    //Das geht auch:
    Ente entchen = new Ente();
    entchen.schwimmen();
    entchen.quaken();
   
    //Schaue dir jetzt die Methodenaufrufe an:
    schwimmÜberDenTeich(schwimmfähigerPanzer);
    schwimmÜberDenTeich(entchen);
}
Es kann dir - dem Interface sei Dank - völlig egal sein mit was du die Methode schwimmÜberDenTeich() fütterst. Du weißt, daß du bei einem Objekt, daß das Interface implementiert hat, einen bestimmten Satz an Methoden erwarten kannst und damit irgendwas tun kannst. Stell dir vor, es soll irgendwann mal eine Klasse 'Schiff' erstellt werden, von der du heute noch gar nichts weißt. Aber das Schiff soll über den Teich schwimmen, mit deiner Methode schwimmÜberDenTeich().
Da du über den Rest des Objekts ja nichts wissen mußt - außer daß es die Methode schwimmen() implementiert hat - kann dir das ganz entspannt egal sein.
das was ich meinte habe ich gerade ausprobiert und das funz net.

@mrBrown danke du hast meine Frage verstanden :)

ich gratuliere dir dass du die sonderschüler sprache sprechen kannst haha.
 
Das kommt darauf an, wie du das Objekt hälst. Beispiel:

Java:
public Interface Schwimmfähig {
    public void schwimmen();
}


public class Panzer implements Schwimmfähig{
   
    public void fahren(){
    }
   
    public void schießen(){
    }
   
    @Override
    public void schwimmen(){
    }
}

public class Ente implements Schwimmfähig{
   
    public void quaken(){
    }
   
    @Override
    public void schwimmen(){
    }
}

public void schwimmÜberDenTeich(Schwimmfähig schwimmer){
    schwimmer.schwimmen(); //Ist das jetzt ein Panzer? Oder eine Ente? Oder was anderes?
}


public static int main(String[] args){
    //Das geht:
    Panzer schwimmfähigerPanzer = new Panzer();
    Panzer.schwimmen();
    Panzer.schießen();
   
    //Das geht auch:
    Ente entchen = new Ente();
    entchen.schwimmen();
    entchen.quaken();
   
    //Schaue dir jetzt die Methodenaufrufe an:
    schwimmÜberDenTeich(schwimmfähigerPanzer);
    schwimmÜberDenTeich(entchen);
}
Es kann dir - dem Interface sei Dank - völlig egal sein mit was du die Methode schwimmÜberDenTeich() fütterst. Du weißt, daß du bei einem Objekt, daß das Interface implementiert hat, einen bestimmten Satz an Methoden erwarten kannst und damit irgendwas tun kannst. Stell dir vor, es soll irgendwann mal eine Klasse 'Schiff' erstellt werden, von der du heute noch gar nichts weißt. Aber das Schiff soll über den Teich schwimmen, mit deiner Methode schwimmÜberDenTeich().
Da du über den Rest des Objekts ja nichts wissen mußt - außer daß es die Methode schwimmen() implementiert hat - kann dir das ganz entspannt egal sein.
Meinte nicht dieses Problem aber danke
 
Also kann ich nicht auf Methoden zugreifen die im Interface nicht implementiert wurden?
Zur Übersetzungszeit steht der Typ von Objekten bzw. Variablen fest (= kann man unmittelbar aus dem Code ableiten). Du kannst nur die Methoden verwenden, die der Typ (inkl. seiner Supertypen) deklariert hat.

Das solltest Du eigentlich den Kommentaren und Beispielen von @kneitzel und @White_Fox entnehmen können.

Der new Operator erzeugt ein neues Objekt vom angegebenen Typ und gibt eine Referenz darauf zurück. Man kann also die Methoden dieses Typs verwenden (ich knüpfe mal an das Beispiel von @White_Fox an):
Java:
new Panzer().schießen();
new Panzer() liefert also eine Referenz auf eine Instanz vom Typ Panzer, daher kann die in Typ Panzer deklarierte Methode schießen verwendet werden.

Diese Referenz (=Adresse des Objekts im Hauptspeicher) kann einer Variablen zugewiesen werden, sofern der Typ dieser Variablen zuweisungskompatibel ist. Bei komplexen Datentypen ist das der Fall, wenn es sich um den gleichen Typ oder einer seiner Supertypen handelt.

Java:
Panzer p = new Panzer();  // Variable p vom Typ Panzer speichert Referenz auf Instanz vom Typ Panzer
Schwimmfähig f = new Panzer(); // Variable f vom Typ Schwimmfähig speichert Referenz auf Instanz vom Typ Panzer
Soll nun eine Methode über eine dieser Variablen aufgerufen werden, ist der Typ der Variablen ausschlaggebend. So hat p den Typ Panzer, man kann also über p alle Methoden von Panzer (oder einer seiner Supertypen) aufgerufen werden. Variable f hat dagegen den Typ Schwimmfähig, es können also nur die Methoden von Schwimmfähig (oder einer ihrere Supertypen) aufgerufen werden.
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben