abstrakte Klasse implementiert ein Interface

Diskutiere abstrakte Klasse implementiert ein Interface im Java Basics - Anfänger-Themen Bereich.
mihe7

mihe7

Abgesehen davon: wenn die Klasse gegeben ist, muss der Programmierer ja nichts mehr programmieren.
 
T

temi

Abgesehen davon: wenn die Klasse gegeben ist, muss der Programmierer ja nichts mehr programmieren.
Was ja durchaus ein Grund für abstrakte Klassen ist: Man gibt dem Programmierer eine Basis zur Hand, die bereits Teile der Lösung umsetzt, so das er weniger Arbeit hat, die vollständige Funktionalität bereitzustellen. Siehe dazu auch die Klassen in der Java Bibliothek: z.B. List<> ➡ AbstractList<>
 
mihe7

mihe7

Was ja durchaus ein Grund für abstrakte Klassen ist: Man gibt dem Programmierer eine Basis zur Hand, die bereits Teile der Lösung umsetzt, so das er weniger Arbeit hat, die vollständige Funktionalität bereitzustellen. Siehe dazu auch die Klassen in der Java Bibliothek: z.B. List<> ➡ AbstractList<>
Du hast mich falsch verstanden. Wenn die Klasse Tier gegeben ist, muss der Programmierer in Klasse Tier nichts mehr programmieren :)

"Gegegen ist: die abstrakte Klasse Tier. [...] Wenn die Methode nicht in Tier ausprogrammiert wird, soll der Compiler eine Fehlermeldung bringen."
 
T

temi

Du hast mich falsch verstanden. Wenn die Klasse Tier gegeben ist, muss der Programmierer in Klasse Tier nichts mehr programmieren :)

"Gegegen ist: die abstrakte Klasse Tier. [...] Wenn die Methode nicht in Tier ausprogrammiert wird, soll der Compiler eine Fehlermeldung bringen."
Das hatte ich auch so verstanden. Ich wollte nur noch einen sinnvollen Anwendungsfall für gegebene abstrakte Klassen nennen.
 
E

ernst

print() muß nicht in Tier implementiert werden:
Java:
package testabstractinterface10;
public class Startklasse {
    public static void main(String[] args) {
        Tier [] tiere = new Tier[1];
        tiere[0]=new Kuh("Milka", 100);
        tiere[0].print();
    }
}

abstract class Tier implements IDruck{
    protected String name;

    public Tier(String name){
        this.name=name;
    }
}

class Kuh extends Tier implements IDruck{
    private int gewicht;

    public Kuh(String name, int gewicht){
        super(name);
        this.gewicht=gewicht;
    }

    public void print(){
        System.out.println("Name="+name+" gewicht="+gewicht);
    }
}
Soweit ist alles ok.
Aber warum meckert der Compiler, wenn man in der Klasse Tier print() nicht ausprogrammiert ?

Java:
package testabstractinterface10;

public class Startklasse {

    public static void main(String[] args) {
        Tier [] tiere = new Tier[1];
        tiere[0]=new Kuh("Milka", 100);
        tiere[0].print();
    }
}

abstract class Tier{    
    protected String name;

    public Tier(String name){
        this.name=name;
    }
}

class Kuh extends Tier implements IDruck{
    private int gewicht;

    public Kuh(String name, int gewicht){
        super(name);
        this.gewicht=gewicht;
    }

    public void print(){
        System.out.println("Name="+name+" gewicht="+gewicht);
    }
}
mfg
Ern
 
mihe7

mihe7

Mal ganz einfach: ein Interface deklariert eine Schnittstelle, d. h. eine Menge öffentlicher Methoden. Eine Klasse kann diese Schnittstelle implementieren. Das bedeutet nicht zwangsläufig, dass die Methoden der Schnittstelle in dieser Klasse auch implementiert werden müssten, sondern, dass Instanzen der Klasse oder einer von ihr abgeleiteten Klassen über diese Methoden verfügen. Ein "implements X" kann man übersetzen zu "ist nach Spezifikation X verwendbar".

Somit bedeutet class Tier implements IDruck nichts anderes als, dass jedes Objekt von Tier (oder einer von Tier abgeleiteten Klasse) so verwendbar ist, wie es in IDruck spezifiziert wurde. Jedes Tier-Objekt ist also nach Spezifikation von IDruck verwendbar.

Da Du von abstrakten Klassen keine Instanzen erzeugen kannst, muss die Methode in diesen auch nicht ausprogrammiert werden.
 
E

ernst

Mal ganz einfach: ein Interface deklariert eine Schnittstelle, d. h. eine Menge öffentlicher Methoden. Eine Klasse kann diese Schnittstelle implementieren. Das bedeutet nicht zwangsläufig, dass die Methoden der Schnittstelle in dieser Klasse auch implementiert werden müssten, sondern, dass Instanzen der Klasse oder einer von ihr abgeleiteten Klassen über diese Methoden verfügen.
Was ebdeutet dann "dass Instanzen der Klasse oder einer von ihr abgeleiteten Klassen über diese Methoden verfügen" konkret, wenn sie nicht in der Klasse ausprogrammiert werden müssen ? Was meinst du dann mit "verfügen" ?

mfg
Ern
 
T

temi

Was bedeutet dann "dass Instanzen der Klasse oder einer von ihr abgeleiteten Klassen über diese Methoden verfügen" konkret, wenn sie nicht in der Klasse ausprogrammiert werden müssen ? Was meinst du dann mit "verfügen" ?
Irgendwo muss die Methode natürlich ausprogrammiert werden, spätestens, wenn eine Instanz erzeugt werden soll. Dazu muss es nicht einmal eine unmittelbare Klasse geben, wenn man z.B. die Instanz einer anonymen Klasse erzeugt
Java:
public class Main {

    public static void main(String[] args) {

        // "printer" ist vom Typ IDruck und verfügt damit über die Methode print()
        // auch wenn die im Interface noch nicht ausprogrammiert ist.
        IDruck drucker;
       
        // Hier wird der Variablen die Instanz einer anonymen Klasse zugewiesen.
        // Spätestens jetzt, muss die Methode implementiert werden.
        drucker = new IDruck() {
            @Override
            public void print() {
                System.out.println("Ich bin eine anonyme Klasse, die auch druckt.");
            }
        };

        drucker.print();
    }
}
 
C

CSHW89

Um die Methode "print" einer Variablen des Typs "IDruck" aufzurufen, benötigst du eine Instanz einer Klasse, die IDruck implementiert und die die Methode "print" als vollständige Implementierung besitzt.

- Irgendeine Klasse, die IDruck nicht implementiert spielt keine Rolle
- Eine abstrakte Klasse (die IDruck implementiert) kann nicht instantiiert werden, daher muss "print" nicht implementiert werden. Die erste Bedingung ist nicht erfüllt, daher muss der Compiler die zweite auch nicht sicherstellen.
- Eine konkrete Klasse (die IDruck implementiert) muss "print" implementieren, da sie instantiiert werden kann. Dies muss der Compiler bei der Definition der Klasse bereits sicherstellen, damit ein Aufruf von "print" auf einer "IDruck"-Variablen funktioniert.
 
T

temi

Um die Methode "print" einer Variablen des Typs "IDruck" aufzurufen, benötigst du eine Instanz einer Klasse, die IDruck implementiert und die die Methode "print" als vollständige Implementierung besitzt.

- Irgendeine Klasse, die IDruck nicht implementiert spielt keine Rolle
- Eine abstrakte Klasse (die IDruck implementiert) kann nicht instantiiert werden, daher muss "print" nicht implementiert werden. Die erste Bedingung ist nicht erfüllt, daher muss der Compiler die zweite auch nicht sicherstellen.
- Eine konkrete Klasse (die IDruck implementiert) muss "print" implementieren, da sie instantiiert werden kann. Dies muss der Compiler bei der Definition der Klasse bereits sicherstellen, damit ein Aufruf von "print" auf einer "IDruck"-Variablen funktioniert.
Gut erklärt, ich schlage vor die Bedeutung den Wortes "implementiert" zur Klarheit noch zu trennen (auch wenn die Begriffe synonym verwendet werden können):

implementiert = implements (eine Klasse mit dem Schlüsselwort implements)
ausprogrammiert = hier wird die implementierte Methode tatsächlich in Code umgesetzt.

- Irgendeine Klasse, die IDruck nicht implementiert spielt keine Rolle. Ergänzung: Es sei denn, sie ist die Kindklasse einer Klasse, die IDruck implementiert und ausprogrammiert hat (siehe auch nächster Punkt).
- Eine abstrakte Klasse, die IDruck implementiert, kann nicht instantiiert werden, daher muss print() nicht ausprogrammiert werden. Die erste Bedingung ist nicht erfüllt, daher muss der Compiler die zweite auch nicht sicherstellen. Ergänzung: Die abstrakte Klasse kann allerdings print() ausprogrammieren. In dem Fall erben die davon abgeleiteten Kindklassen sowohl die implementierte Schnittstelle, als auch die ausprogrammierte Methode.
- Eine konkrete Klasse, die IDruck implementiert, muss print() ausprogrammieren, da sie instantiiert werden kann. Dies muss der Compiler bei der Definition der Klasse bereits sicherstellen, damit ein Aufruf von print() auf einer "IDruck"-Variablen funktioniert.
 
T

temi

Java:
interface Foo {
    void doSomething();
}

class Bar {
    void doSomething() {
        // irgendein Code...
    }
}

Foo foo = new Bar(); // Fehler! Bar implementiert nicht Foo, auch wenn es über (irgend)ein doSomething() verfügt.
Java:
interface Foo {
    void doSomething();
}

class Bar implements Foo {
    @Override
    public void doSomething() {
        // irgendein Code...
    }
}

Foo foo = new Bar(); // Passt!
foo.doSomething(); // Passt!
Java:
interface Foo {
    void doSomething();
}

abstract class AbstractBar implements Foo {
    // die Methode muss hier nicht ausprogrammiert werden, weil die Klasse abstrakt ist
}

Foo foo = new AbstractBar(); // Fehler! Abstrakte Klasse kann nicht instantiiert werden.

class Bar extends AbstractBar {
    // Hier muss die Methode ausprogrammiert werden, weil eine Instanz erzeugt werden kann
    // und noch keine Ausprogrammierung der Methode vorliegt.
    @Override
    public void doSomething() {
        // irgendein Code...
    }
}

Foo foo = new Bar(); // Passt!
foo.doSomething();

class AnotherBar extends Bar {

}

Foo foo = new AnotherBar(); // Passt! AnotherBar erbt sowohl die Schnittstelle, als auch die Ausprogrammierung von Bar
foo.doSomething();
Java:
interface Foo {
    void doSomething();
}

abstract class AbstractBar implements Foo {
    // die Methode kann hier ausprogrammiert werden
    @Override
    public void doSomething() {
        // irgendein Code...
    }
}

Foo foo = new AbstractBar(); // Fehler! Abstrakte Klasse kann nicht instantiiert werden.

class Bar extends AbstractBar {
    // Hier muss die Methode nicht mehr ausprogrammiert werden, sie wurde von AbstractBar geerbt
}

Foo foo = new Bar(); // Passt!
foo.doSomething();
 
E

ernst

Danke für die vielen konketen Beispiele.
Man könnte noch den Fall bringen, wenn
void doSomething()
in einer abstrakten Klasse als abstrakte Methode deklariert wird.

mfg
Ern
 
T

temi

Java:
interface Foo {
    void doSomething();
}

abstract class AbstractBar {
    // die Methode muss hier nicht ausprogrammiert werden, weil sie abstrakt ist
    public abstract void doSomething();
}

Foo foo = new AbstractBar(); // Fehler! Abstrakte Klasse kann nicht instantiiert werden.

class Bar extends AbstractBar {
    // Hier muss die Methode ausprogrammiert werden, weil eine Instanz erzeugt werden kann
    // und noch keine Ausprogrammierung der Methode vorliegt.
    @Override
    public void doSomething() {
        // irgendein Code...
    }
}

Foo foo = new Bar(); // Fehler! Weder AbstractBar noch Bar implementieren Foo
 
E

ernst

abstract class AbstractBar {
// die Methode muss hier nicht ausprogrammiert werden, weil sie abstrakt ist
public abstract void doSomething();
}

besser:
// die Methode darf hier nicht ausprogrammiert werden, weil sie abstrakt ist
 
Thema: 

abstrakte Klasse implementiert ein Interface

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben