Wofür abstract?

Reggie()

Bekanntes Mitglied
ich habe bisher in keinem Tut gefunden, was genau der Vorteil/Nutzen von einer abstrakten Klasse sein soll. Wenn ich den Teil Vererbung richtig verstanden habe, erben sub-klassen von den super-klassen, egal ob abstrakt oder nicht.

Reggie
 

njans

Top Contributor
Jap, aber bei Abstrakten Klassen wirst du "gezwungen" die vollständig abstrakten Methoden zu implementieren (wie bei einem Interface), bist aber gleichzeitig in der Lage Methoden vollständig zu erstellen, so dass die erbende Klasse diese direkt verwenden kann.
 

Gregorrr

Bekanntes Mitglied
ich habe bisher in keinem Tut gefunden, was genau der Vorteil/Nutzen von einer abstrakten Klasse sein soll. Wenn ich den Teil Vererbung richtig verstanden habe, erben sub-klassen von den super-klassen, egal ob abstrakt oder nicht.

Reggie

Abstrakte Basisklassen erlauben es vordefinierten Code, also Methoden, zu definieren, die in allen Unterklassen vorhanden sind, wie bei der normaler Vererbung. Allerdings können abstrakte Klassen auch abstrakte Methoden definieren, die von den Unterklassen, unbedingt implementiert werden müssen, d.h. das ist für Klassenspezifischen Code. Abstrakte Basisklassen kann man deswegen nicht instantiieren, da eine Implementierung nicht vorhanden sein muss. Das ist also ein Zwischending, zwischen Code-Wiederverwendung wie bei normaler Vererbung und Definition eines Typs wie bei Interfaces, ohne konkrete Implementierung angeben zu müssen.
 
M

maki

Gast
ich habe bisher in keinem Tut gefunden, was genau der Vorteil/Nutzen von einer abstrakten Klasse sein soll. Wenn ich den Teil Vererbung richtig verstanden habe, erben sub-klassen von den super-klassen, egal ob abstrakt oder nicht.
Ja, aber mit dem Schlüsselwort abstract ist eben klar dass diese Klasse nicht zum Instanziieren gedacht war ;)
 

muemmel_0811

Bekanntes Mitglied
ich auch noch :D

Stell Dir vor, Du hast folgende Klasse:
Java:
public abstract class Tier {
// irgendwas, was Tiere gemeinsam haben
}

public class Hund extends Tier {
}
Und warum ist die Klasse Tier nun abstract? Ganz einfach: stell Dir einfach die Frage, wie ein Tier aussieht. Ist es groß, klein, braun, lila usw. - schwierig. Im Gegensatz dazu ist ein Hund ein "greifbares" Objekt. Den kann man per Instanzvariablen so "beschreiben", dass es hinterher auch ein Hund ist und nicht eine bellend schwimmende Katze oder so.
 

Reggie()

Bekanntes Mitglied
keiner der oben stehenden Antworten beantwortet die eigentliche Frage
und
Stell Dir vor, Du hast folgende Klasse:
Java:
public abstract class Tier {
// irgendwas, was Tiere gemeinsam haben
}

public class Hund extends Tier {
}
Und warum ist die Klasse Tier nun abstract? Ganz einfach: stell Dir einfach die Frage, wie ein Tier aussieht. Ist es groß, klein, braun, lila usw. - schwierig. Im Gegensatz dazu ist ein Hund ein "greifbares" Objekt. Den kann man per Instanzvariablen so "beschreiben", dass es hinterher auch ein Hund ist und nicht eine bellend schwimmende Katze oder so.
ist doch das selbe wie:
Java:
public class Tier {
// Oberklasse
}

public class Hund extends Tier {
// Unterklasse
}
vielleicht sollte ich die Frage umformulieren:
Was kann ich mit abstrakten Klassen tun, was ich mit normalen Ober- und Unterklassen nicht kann?

Reggie
 

Michael...

Top Contributor
vielleicht sollte ich die Frage umformulieren:
Was kann ich mit abstrakten Klassen tun, was ich mit normalen Ober- und Unterklassen nicht kann?
Die Frage ist falsch herum gestellt: Was kann ich mit abstrakten Klassen nicht tun was ich mit konkreten Klassen kann? ;-)
Antwort: abstrakte Klassen können nicht instanziiert werden.

Die Verwendung und Eigenschaften abstrakter Klassen wurden allerdings bereits erläutert.

Mit abstrakten Klassen wird eine Schnittstelle definiert. Genauso wie mit Interfaces nur mit dem Unterschied, dass eine abstrakte Klasse teilweise bereits implementierte Methoden besitzen kann.

Ist Dir denn der Sinn und Zweck von Interfaces bekannt? Das wäre eine Voraussetzung für das Verständnis von abstrakten Klassen.

Abstrakte Klassen werden auch gerne als Adaption von Interfaces genutzt, wenn es nicht unbedingt notwendig ist alle durch ein Interface definierten Methoden zu implementieren. (siehe z.B. MouseAdapter). Dadurch bleibt der Code übersichtlicher und der Programmierer muss nur die Methoden implementieren, die in auch tatsächlich interessieren.
 

Illuvatar

Top Contributor
und
Stell Dir vor, Du hast folgende Klasse:
Java:
public abstract class Tier {
// irgendwas, was Tiere gemeinsam haben
}

public class Hund extends Tier {
}
ist doch das selbe wie:
Java:
public class Tier {
// Oberklasse
}

public class Hund extends Tier {
// Unterklasse
}

Ok, dann tun wir zu muemmels Beispiel mal etwas Inhalt:
Java:
public abstract class Tier {
  public abstract int getNumberOfLegs();
  // noch mehr
}

public class Hund extends Tier {
  public int getNumberOfLegs() {
    return 4;
  }
  // auch noch mehr
}
Was machst du jetzt?
 

Marco13

Top Contributor
Man braucht keine abstrakten Klassen. Und manche Leute postulieren sogar, dass es keinen Grund gibt, sie zu benutzen. Man kann mit Interfaces+NormalenKlassen alles machen, was man auch mit abtrakten Klassen machen kann. Die Begründung, DOCH abstrakte Klassen zu verwenden, ist, lapidar formuliert: Sie sparen Arbeit. Am schon angedeuteten Beispiel:
Java:
interface Tier {
    void friß();
    void gibLaut();
}

class AbstraktesTier implements Tier {
    public void friß() {
        System.out.println("Nom, nom, nom..."); // Ist bei allen Tieren gleich
    }

    public abstract void gibLaut(); // Ist nach wie vor abstract
}

class Hund extends AbstraktesTier implements Tier {
    public void gibLaut() {
        System.out.println("Wuff");
    }
}

class Katze extends AbstraktesTier implements Tier {
    public void gibLaut() {
        System.out.println("Muuuhhhh");
    }
}

Die Methode "friß()" ist bei allen Tieren gleich, und kann deswegen in der abstrakten Klasse stehen. Man KÖNNTE die abstrakte Klasse auch weglassen, und stattdessen die Methode (zwei mal gleich!) in den konkreten Klassen implementieren.

Das ist etwas vereinfacht, aber darauf läuft's meistens raus. Trotzdem sollte man sich überlegen, wie und wo man Abstrakte Klassen verwendet. Sie können die Strukturen ein bißchen "unschöner" machen. Ein bißchen was steht dazu auch in Practical API Design: Confessions of ... - Google Books
 

muemmel_0811

Bekanntes Mitglied
ohne abstract sollte es doch genauso gehen, oder? wenn nicht, dann bitte erklärt es mir. ich will wirklich lernen.

Reggie
Nein, denn durch die abstrakte Methode gibLaut() - schau mal genau hin - da ist ein Semikolon hinter der Methode und keine geschweiften Klammern, muss die Klasse abstract sein. Und abstrakte Methoden bedeuten, dass die Erben der Klasse diese Methoden implementieren müssen. In unserem Fall müssen also alle konkreten Tiere diese Methode implementieren.
Jetzt klar?
 

TheDarkRose

Gesperrter Benutzer
Man braucht keine abstrakten Klassen. Und manche Leute postulieren sogar, dass es keinen Grund gibt, sie zu benutzen. Man kann mit Interfaces+NormalenKlassen alles machen, was man auch mit abtrakten Klassen machen kann. Die Begründung, DOCH abstrakte Klassen zu verwenden, ist, lapidar formuliert: Sie sparen Arbeit. Am schon angedeuteten Beispiel:
[...]
Die Methode "friß()" ist bei allen Tieren gleich, und kann deswegen in der abstrakten Klasse stehen. Man KÖNNTE die abstrakte Klasse auch weglassen, und stattdessen die Methode (zwei mal gleich!) in den konkreten Klassen implementieren.

Das ist etwas vereinfacht, aber darauf läuft's meistens raus. Trotzdem sollte man sich überlegen, wie und wo man Abstrakte Klassen verwendet. Sie können die Strukturen ein bißchen "unschöner" machen. Ein bißchen was steht dazu auch in Practical API Design: Confessions of ... - Google Books

Warum haußt du da noch ein Interface dazwischen? Das macht es doch die Struktur erst unschon. Nur weil es vom Begriff eine Abstrakte Klasse ist, ist eine abstrakte Klasse von der Definition auch eine Schnittstellen Vereinbarung.


Java:
public abstract class AbstraktesTier {
    public void friß() {
        System.out.println("Nom, nom, nom..."); // Ist bei allen Tieren gleich
    }

    public abstract void gibLaut(); // Ist nach wie vor abstract
}

public class Hund extends AbstraktesTier {
    public void gibLaut() {
        System.out.println("Wuff");
    }
}

public class Katze extends AbstraktesTier {
    public void gibLaut() {
        System.out.println("Muuuhhhh");
    }
}
Das reicht ja vollkommen. Statt AbstraktesTier kann man auch einfach Tier schreiben
 

Marco13

Top Contributor
Genau das meinte ich mit der potentiell unschönen Struktur ;) OO-Nazis definieren eben ALLES erstmal als Interface. Eine Abstrakte Basisklasse als "Wurzel" der Vererbungshierarchie macht i.a. keinen Sinn - weil dadruch quasi das "erzwungen" wird, was bei der Hierarchie "Interface->Abstract->Impl" nur als unschöner Nebeneffekt auftritt: Es gibt Leute, die sich darauf verlassen, dass das, womit sie es da zu tun haben, von der Abstrakten Basisklasse erbt. Zumindest gibt es einige APIs, bei denen bestimmte abstrakte Basisklassen einfach "zu mächtig" sind (oder zu viele Methoden enthält, die eigentlich ins Wurzelinterface gepackt werden könnten oder sollten), und niemand mehr das Interface verwendet, sondern alle die abstrakte Klasse.

Am konkreten Beispiel: Wenn ein Tier nun eine andere Implementierung von "friß" haben sollte, würde man die (einzige) konkrete Methode aus der abstrakten Klasse überschreiben, und sie damit ad absurdum führen, und ihre Funktion auf das reduzieren, was sie von vornherein hätte sein sollen: Ein Interface.
 

TheDarkRose

Gesperrter Benutzer
Architektonisch sind Interfaces und abstrakte Klassen das selbe, nämlich Schnittstellen. Ich finde es ad absurdum, wenn man für eine abstrakte klasse noch extrig ein Interface macht.
 
M

Marcinek

Gast
Architektonisch sind Interfaces und abstrakte Klassen das selbe, nämlich Schnittstellen. Ich finde es ad absurdum, wenn man für eine abstrakte klasse noch extrig ein Interface macht.

Ich habe ein Interface "Remote", dieses wird hauptsächlich von einer abstrakten klasse implementiert. Also ich finde das nicht ganz absurd. Diese eine Klasse kann aber nicht alle Methoden implementieren.

public class Tier {
public int getNumberOfLegs();
// noch mehr
}

public class Hund extends Tier {
public int getNumberOfLegs() {
return 4;
}
// auch noch mehr
}

Was machst du jetzt?


ohne abstract sollte es doch genauso gehen, oder? wenn nicht, dann bitte erklärt es mir. ich will wirklich lernen.


Reggie

Nein das geht nicht. wenn du eine Instanz der Klasse Tier machen würdest, und dann die abstrakte Methode aufrufen würdest was dann?

Nein.
aber so wie ich das sehe brauche ich keine abstrakten Klassen.... zumindest bis ich mehr drauf habe

Reggie

Ja das stimmt. In einem kleinen Programm wird das sicher nicht notwendig sein. Wenn du etwas größeres programierst, dann wirst du ohne kaum auskommen. Es sei den du baust iwas, was nicht weit verbreitet werden soll und nix kostet ;D
 

Marco13

Top Contributor
Architektonisch sind Interfaces und abstrakte Klassen das selbe, nämlich Schnittstellen. Ich finde es ad absurdum, wenn man für eine abstrakte klasse noch extrig ein Interface macht.

Sie können in gewissen Grenzen gleichwertig sein. Man könnte sagen, sie sind gleichwertig, wenn die abstrakte Klasse keine nicht-privaten Methoden hat, die nicht auch im Interface stehen würden.
Java:
class AbstraktesTier {
    public void friß() { ... }
    public abstract void gibLaut();

    public void legDichInsKörbchen() { ... }
}
Das Funktioniert bei Hunden und Katzen, und jeder kann sich "Tier" holen und sich das Tier ins Körbchen Legen lassen, weil ... es ist ja ein AbstraktesTier. Bis jemand eine Kuh implementieren will.

Oder kurz: Ein Interface ist eine Schnittstelle. Eine Abstrakte Klasse ist eine Schnittstelle - UND (vielleicht) Implementierungen, die nicht notwendigerweise zur Schnittstelle gehören oder gehören sollten.
 

RySa

Bekanntes Mitglied
Also irgendwie hat der TO den Topic "verlassen" und ihr fangt an, sich selber noch zu "streiten" xD

@Marco13

Ich glaube du hast das abstract, bei der Klasse abstraktesTier vergessen (schreibst ja die ganze Zeit, "bei der abstrakten Klasse") - ist aber nicht so wichtig :p

Was ich aber lustig fand, ist, dass deine Katze eher eine Kuh ist ^^:
class Katze extends AbstraktesTier implements Tier {
public void gibLaut() {
System.out.println("Muuuhhhh");
}

Aber jetzt zum Thema:

Java:
public abstract class Tier {
  public abstract int getNumberOfLegs();
  // noch mehr
}
 
public class Hund extends Tier {
  public int getNumberOfLegs() {
    return 4;
  }
  // auch noch mehr
}
ohne abstract sollte es doch genauso gehen, oder? wenn nicht, dann bitte erklärt es mir. ich will wirklich lernen.

Reggie

Und wie bitte schön, willst du dann die Anzahl der Beine von Tier bestimmen ? Wie viele Beine hat deiner Meinung nach ein Tier ? Also für mich hängt das irgendwie von dem ab, was für ein Tier es ist. Und wieso soll deiner Meinung nach ein Tier instanziert werden können ? Hast du schon mal gesehen, dass ein Tier geboren wurde ? (also ein Tier, das weder ein Hund, noch ein anderes Tier ist, also keine Gattung hat und unbekannte Anzahl an beinen etc....) Also ich glaube auch wenn ich nichts mit Programmieren zu tun hätte, würde ich es nach all den deutlichen Erklärungen hier verstehen. Ich weiß nicht wirklich was dein Problem ist...
 

Reggie()

Bekanntes Mitglied
Und wie bitte schön, willst du dann die Anzahl der Beine von Tier bestimmen ? Wie viele Beine hat deiner Meinung nach ein Tier ? Also für mich hängt das irgendwie von dem ab, was für ein Tier es ist. Und wieso soll deiner Meinung nach ein Tier instanziert werden können ? Hast du schon mal gesehen, dass ein Tier geboren wurde ? (also ein Tier, das weder ein Hund, noch ein anderes Tier ist, also keine Gattung hat und unbekannte Anzahl an beinen etc....) Also ich glaube auch wenn ich nichts mit Programmieren zu tun hätte, würde ich es nach all den deutlichen Erklärungen hier verstehen. Ich weiß nicht wirklich was dein Problem ist...
wenn es um die Anzahl der Beine von der Oberklasse (oder halt abstract) "Tier" geht würde ich in der Tier-Klasse eine public static final int numberOfLegs = 4; eintragen. sollte man allerdings Tier-Unterklassen erstellen wollen mit Beine != 4, dann würde ich eine Konstante in jeder der Unterklassen definieren.
hier gehts doch um den exklusiven Nutzen von abstrakten klassen. und genau den habe ich bisher nicht gelesen. Gab ja schon einige Antworten und manche bestätigten diese Sicht und andere schrieben, dass sich eine normale oberklasse von einer abstrakten klasse nur darin unterscheidet, dass man diese nicht instanzieren kann. wenn man das auch nie vorhatte, macht es also keinen Unterschied, ob man eine abstrakte klasse benutzt.
aber ich schließe auch nicht aus, dass ich den Nutzen und die besondere Funktion von abstract nicht erkenne, weil ich mich noch zu wenig in java auskenne. statt mich zu fragen, wie ich das Beispielproblem sonst lösen wollte, würde ich mir lieber ein Beispiel wünschen, dass NUR mit abstract funktioniert UND erklärt, warum es ohne abstract nicht funktionieren würde.

Reggie
 

RySa

Bekanntes Mitglied
Es gibt kein Beispiel und es wird keins geben (soweit ich weiß), bei dem du unbedingt eine abstrakte Klasse nutzen musst. Wie es schon zig mal gesagt wurde, es ist alles auch mit normalen Klassen und Interfaces möglich zu realisieren.

Jetzt aber vielleicht mal von der anderen Seite. Du würdest kein Verwendungszweck dafür finden, da du sowieso nie vor hättest die Klasse zu instanzieren. Ist ja auch in Ordnung. Ich persönlich habe auch noch nie abstrakte Klassen benutzt. Jetzt stell dir aber mal vor, du willst ein Framework/Tool schreiben, der den anderen das Leben leicher machen soll. Du schreibst ne Klasse, die aber an sich nicht funktionieren wird, sondern von anderen Klassen (also von den Klassen, die die Benutzer schreiben) abgeleitet werden muss. In diesem Fall willst du verhindern, dass solche Klasse, ohne Ableitung Instanziert werden kann. Und das kannst du ja mit einer abstrakten Klasse realisieren. Außerdem, wird ja deine Klasse Methoden beinhalten, die Teilweise von dir implementiert sind, aber auch solche, die von der Konkreten Implementierung des Benutzers abhängen (also je nach seinen Anforderungen). Solch eine Klasse kann nicht ohne Ableitung Instanziert werden, und genau das ist ja dein Vorhaben.

Man kann das ganze aber auch mit einer "normalen" Klasse und Interfaces realisieren, in dem sie einfach mal die Interfaces implementiert. Solch eine Klasse kann man aber Instanzieren und das - nochmal zur Verdeutlichung, willst du ja verhindern, weil man mit solcher Klasse nichts machen kann, sie ist also unnützlich, solange man sie nicht mit den entsprechenden Implementierungen ableitet, und es also kein Sinn hat sie zu Instanzieren
Ist das jetzt vlt. klarer geworden ?
 
Zuletzt bearbeitet:
M

maki

Gast
Architektonisch sind Interfaces und abstrakte Klassen das selbe, nämlich Schnittstellen. Ich finde es ad absurdum, wenn man für eine abstrakte klasse noch extrig ein Interface macht.
Sie sind nicht 100% gleichwertig, der Unterschied machts, abstrakte Klassen die Schnittstellen implementieren sind üblich und oft vorteilhaft, siehe zB. das Collection Framework, Bloch hat das ganz gut in Effective Java beschrieben.

Interface <- abstrakte Klasse <- konkrete Implementierung 1..n

abstrakte Klassen sind nicht ganz so abstrakt wie Interfaces, d.h. wenn man von abstrakten Klassen abhängt ist man meist immer noch von einer Implementierung abhängig, das hat man bei Interfaces nicht mehr. Dafür kann man in abstrakten Klassen zB. Änderungen am Interface vor den konkreten Klassen "verstecken", wenn zB. das Interface erweitert wird, implementiert man diese neuen Methoden in der abtrakten Klasse, fertig, die konkreten Klassen brauchen keine Änderung, laufen genauso wie vorher und nix bricht.
Diese flexibilität bekommt man eben nur wenn man Interfaces und abstrakte Klassen kombiniert.
 

Reggie()

Bekanntes Mitglied
Du schreibst ne Klasse, die aber an sich nicht funktionieren wird, sondern von anderen Klassen (also von den Klassen, die die Benutzer schreiben) abgeleitet werden muss. In diesem Fall willst du verhindern, dass solche Klasse, ohne Ableitung Instanziert werden kann. Und das kannst du ja mit einer abstrakten Klasse realisieren. Außerdem, wird ja deine Klasse Methoden beinhalten, die Teilweise von dir implementiert sind, aber auch solche, die von der Konkreten Implementierung des Benutzers abhängen (also je nach seinen Anforderungen). Solch eine Klasse kann nicht ohne Ableitung Instanziert werden, und genau das ist ja dein Vorhaben.
[...]
Ist das jetzt vlt. klarer geworden ?
ja, eine gute Erklärung. danke :)

Reggie
 
G

Gonzo17

Gast
wenn man das auch nie vorhatte, macht es also keinen Unterschied, ob man eine abstrakte klasse benutzt.

Meiner Meinung nach ein wichtiger Satz. Du gehst im Moment vielleicht davon aus, dass du der einzige Entwickler an einem Programm bist und deshalb solche kleinen Unterschiede nicht tragisch sind, weil du ja weißt, was getan werden soll.

Jetzt stell dir mal vor du arbeitest in einem Team mit vier Entwicklern im gleichen Haus und nochmal vier Entwickler aus dem Ausland. Nicht jeder weiß, was dein Modul so genau kann und wie es funktioniert. Übergibst du nun die Aufgabe an jemand anderen, dann erwartet er, dass er alles machen darf, was der Code so zulässt. Also könnte er auf die blöde Idee kommen eine Instanz einer Klasse zu erstellen, die eigentlich abstrakt sein könnte. Und natürlich gibts da noch mehr Fälle, in denen etwas ungewolltes passieren könnte. Wenn du dein Design eben so sicher machst, dass sowas nicht passieren kann, dann ist der Code wartbar(er) und verständlich(er).
 

Noctarius

Top Contributor
Guice hat ein sehr schönes Beispiel welches ohne abstrakte Klasse möglich aber nicht schön wäre.

Wir gehen davon aus, es gibt ein Interface Module, welches ein Modul in irgendeiner Art und Weise definiert und einen Binder, welcher in irgendeiner Form Bindings erzeugt.

Java:
public interface Module {

    void configure(Binder binder);

}

So jetzt könnte man mit dem Interface Binder alles mögliche machen indem man das Interface Module implementiert.

Java:
 public class MyModule implements Module {

    @Override
    public void configure(Binder binder) {
        binder.bind(Foo.class).to(FooImpl.class);
        binder.bindProvider(SomeProvider.class);
        // ... whatever
    }

}

Das ist auch ganz nett aber irgendwie doof immer binder. davor zu schreiben, ergo wurde zusätzlich eine abstrakte Klasse eingeführt um die Konfiguration einfacher zu machen.

Java:
public abstract class AbstractModule implements Module {
    private Binder binder;

    @Override
    public final void configure(Binder binder) {
        try {
            this.binder = binder;
            configure();

        } finally {
            binder = null;
        }
    }

    protected abstract void configure();

    protected BindBuilder bind(Class<?> clazz) {
        return binder.bind(clazz);
    }

    protected void bindProvider(Class<? extends Provider> providerClass) {
        binder.bindProvider(providerClass);
    }

}

So ab hier sieht die das neue Modul nur noch so aus:

Java:
public class MyModule extends AbstractModule {

    @Override
    public void configure() {
        bind(Foo.class).to(FooImpl.class);
        bindProvider(SomeProvider.class);
        // ... whatever
    }

}

Wir sehen also, erstens zwingt uns die abstrakte Klasse in Subclasses die Methode configure() zu implementieren und zweitens haben wir den Code (wenn hier auch nicht viel) verkürzt und übersichtlicher gemacht. Die abstrakte Klasse könnte nun zusätzlich noch in den protected Methode Überprüfungen machen ohne, dass wir die Module anpassen müssten.

Auch werden abstrakte Klassen oft als Adapter genutzt um nachträglich zum Beispiel Interfaces weiterzuentwickeln. Alle Klassen die dann von der abstrakten Klasse erben (anstatt das Interface direkt zu implementieren) merken dann nichts davon, dass sich eventuell Methoden im Interface geändert haben, dazu muss die abstrakte Klasse halt nur eine passende Standardimplementierung mitbringen.

Der eigentliche Sinn von abstrakten Klassen ist also nur, wie meine Vorredner schon sagten, ANDERE (nicht dich selber) daran zu hindern diese Klassen direkt zu instanzieren und um eventuell zusätzliche Funktionalität oder Standardimplementierungen zu liefern.
 

RySa

Bekanntes Mitglied
Noch vielleicht kurz zur Ergänzung (weiß nicht ob das schon gesagt wurde):

Jetzt nehmen wir mal an, du bist kategorisch gegen abstrakte Klassen, und entscheidest dich für eine "normale" Hauptklasse, die ein Interface implementiert, du aber für die Methoden des Interfaces noch keine Implementierungen vornehmen kannst, da die Benutzer-spezifisch sind. Dann denkst du dir, joah, dann implementiere ich sie einfach mal leer. Nun gut, man kann die Methode in der Unterklasse immer noch überschreiben, dazu wird der Benutzer aber nicht mehr gezwungen, da die Methode schlichtweg sonst einfach mal nichts tut. Das mag in manchen Fällen sinnvoll und beabsichtigt sein, manchmal willst du aber den Benutzer "zwingen" die Methoden zu implementieren/überschreiben und gleichzeitig willst du manche Methoden schon "fertig zur Verfügung stellen". Und wenn du im gleichen Anwendungsfall eine abstrakte Klasse machen würdest, die das Interface implementiert (bzw. auch selber diese Methode als abstract definieren kann), wirst du gezwungen, in der ableitenden Klasse die Methoden zu überschreiben hast aber auch die "fertigen" Methoden der Klasse zur Verfügung.

Interface, für beide Beispiele gleich:
Java:
public interface Tier {

	public String gibLaut();
}

Beispiel 1 (gegen abstract Class):
Java:
public class AbstractTier implements Tier{

	private String name;
	private double gewicht;
	
	public double getGewicht(){
		return gewicht;
	}
	
	public String getName(){
		return name;
	}
	
	public void setName(String name){
		this.name = name;
	}
	
	public void setGewicht(double gewicht){
		this.gewicht = gewicht;
	}
	
	@Override
	public String gibLaut() {
		return null;
	}
	
}
Wenn jetzt eine Klasse Hund diese Klasse ableitet, kann der Entwickler vielleicht übersehen, dass es eine Methode gibLaut() gibt, die er eigentlich überschreiben müsste, und sein Hund wird nicht bellen können :p (also wird "null" bellen ^^):
Java:
public class Hund extends AbstractTier{

	String rasse;
	
	public Hund(String name, double gewicht){
		super();
		setName(name);
		setGewicht(gewicht);
	}
	
	public void setRasse(String rasse){
		this.rasse=rasse;
	}
}

Wenn du aber eine abstrakte Klasse dafür nimmst, wird der Entwickler in der Klasse Hund dazu gezwungen, gibLaut() zu implementieren

Beispiel 2 (für abstract Class):
Java:
public abstract class AbstractTier implements Tier{

	private String name;
	private double gewicht;
	
	public double getGewicht(){
		return gewicht;
	}
	
	public String getName(){
		return name;
	}
	
	public void setName(String name){
		this.name = name;
	}
	
	public void setGewicht(double gewicht){
		this.gewicht = gewicht;
	}
	
}
Und das obere Beispiel für Hund, wird nicht mehr funktionieren "The Type Hund must implement the inherited abstract method Tier.gibLaut()" , also wird es so aussehen müssen:
Java:
public class Hund extends AbstractTier{

	String rasse;
	
	public Hund(String name, double gewicht){
		super();
		setName(name);
		setGewicht(gewicht);
	}
	
	public void setRasse(String rasse){
		this.rasse=rasse;
	}

	@Override
	public String gibLaut() {
		return "woof";
	}
}

:)

Ps. Natürlich ist es eine Ansichtssache, ob der "Hund gezwungen werden soll Laut zu geben". Hängt alles von der Architektur des Programms ab.

Und @ den Post unter meinem

Ob du Vererbung/Interfaces schön findest oder nicht. Es ist ein sehr großes und wichtiges Gebiet in Java.Ich hatte auch glaube ich noch nie wirklich ein Nutzen von Vererbung/Interfaces machen können, es hängt aller dings mit der Art meiner Projekte. Es Ändert aber nichts an der frage des TO's, die hier doch noch von vielen ausführlich beantwortet wird. Wenn du mir/uns aber einreden willst, das Vererbung allgemein "böse" ist, dann bitte mal auch konkreter, mit Begründungen/Beispielen...
 
Zuletzt bearbeitet:
B

bygones

Gast
will mitstreiten :)

Vererbung ist eins der meistgehypten und meist missverstandenen/missbrauchten feature seit erfindung von Programmieren... lieber weglassen und nur nehmen wenns ueberhaupt nicht geht.

Die "alte" Frage von IS-A ist meiner ansicht nach so und so falsch.. nur bei "Behaves-like" kann man es in betracht ziehen.

Ansonsten immer beachten: Komposition >>>>> Vererbung.

-----
und nu schoen alle erzaehlen warum Vererbung doch gut ist bzw wie ich sachen denn ohne Vererbung machen will...
 

Marco13

Top Contributor
EDIT: Peinlich, ich hatte die komplette zweite Seite übersehen :oops: Hab ich wohl gepennt :gaen:

statt mich zu fragen, wie ich das Beispielproblem sonst lösen wollte, würde ich mir lieber ein Beispiel wünschen, dass NUR mit abstract funktioniert UND erklärt, warum es ohne abstract nicht funktionieren würde.

So ein Beispiel gibt es nicht (*). Jedes Programm, das eine abstract class verwendet, könnte auch ohne abstract class geschrieben werden.

(*) Zumindest gibt es so ein Beispiel nicht ohne Aspekte, die schwer zu vermitteln sein könnten. Ich versuch's trotzdem: Methoden, die in einem interface stehen, sind automatisch 'public'. Methoden, die einer Abstrakten Klasse stehen, können auch 'protected' oder 'package private' sein.
Java:
interface Tier
{
    void friß();       // Diese Methoden sind immer 'public'
    void gibLaut(); //  (auch wenn kein 'public' davor steht!)
}

abstract class AbstraktesTier implements Tier
{
    protected void verdaueFutter() 
    {
        // Diese Methode erfüllt eine Funktion, die "oft" gebraucht wird,
        // wenn man ein konkretes Tier implementieren will. Allerdings
        // ist die Methode 'protected', d.h. sie sollte NUR von Klassen
        // aufgerufen werden, die von "AbstraktesTier" erben - und 
        // nicht von irgendwelchen anderen Klassen!
    }

    // Diese Methoden sind immernoch abstrakt:
    //public abstract void friß();
    //public abstract void gibLaut();
    
}

class Hund extends AbstraktesTier implements Tier
{
    public void friß()
    {
        System.out.println("Nom, nom, nom");
        verdaueFutter(); // Ruft die 'protected'-Methode aus AbstraktesTier auf
    }
    public void gibLaut()
    {
        System.out.println("Wuff");
    }
}

IMHO ist dieser Aspekt auch die EINZIGE echte Existenzberechtigung für abstrakte Klassen, die mir spontan einfallen würde (wenn man das Vermeiden von Doppelimplementierungen nicht als solche ansieht)
 

Gregorrr

Bekanntes Mitglied
will mitstreiten :)

Vererbung ist eins der meistgehypten und meist missverstandenen/missbrauchten feature seit erfindung von Programmieren... lieber weglassen und nur nehmen wenns ueberhaupt nicht geht.

Die "alte" Frage von IS-A ist meiner ansicht nach so und so falsch.. nur bei "Behaves-like" kann man es in betracht ziehen.

Ansonsten immer beachten: Komposition >>>>> Vererbung.

-----
und nu schoen alle erzaehlen warum Vererbung doch gut ist bzw wie ich sachen denn ohne Vererbung machen will...

Bester Beitrag zum Thema, wie ich finde!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Fats Waller Wofür stehen diese Konstanten im Java Labyrinth ? Java Basics - Anfänger-Themen 5
G Wofür benötigt man die Umgebungsvariablen sowohl in Windows 10 als auch in Mac OS Catalina Java Basics - Anfänger-Themen 19
J Wofür dienen Interfaces ? Java Basics - Anfänger-Themen 1
F Mehrere Konstruktoren? Wofür? Java Basics - Anfänger-Themen 21
S "%s" oder "%n" - wofür nutzt man das? Java Basics - Anfänger-Themen 4
H Wofür benötigt man ByteBuffer? Java Basics - Anfänger-Themen 5
K Wofür wird heute noch die Stack Klasse in Java genutzt Java Basics - Anfänger-Themen 4
Z This() Wofür Java Basics - Anfänger-Themen 2
T Wofür ist ANT? Java Basics - Anfänger-Themen 5
T Wofür Parser?? Java Basics - Anfänger-Themen 39
V Wofür steht das args / arguments in Main Methode Java Basics - Anfänger-Themen 4
D Was ist ein StringReader und wofür braucht man ihn? Java Basics - Anfänger-Themen 2
N Look & Feel Nimbus wofür? Java Basics - Anfänger-Themen 10
G Wofür com package? + Welche eclipse - Plug Ins? Java Basics - Anfänger-Themen 3
K java syntax: wofür steht super(screen)? Java Basics - Anfänger-Themen 5
J Wofür steht \r? Java Basics - Anfänger-Themen 7
D argv Warum? Wofür? Weshalb? Java Basics - Anfänger-Themen 2
Say abstract class und Objekt erzeugen - Dringend Hilfe Java Basics - Anfänger-Themen 10
S Wann Methode abstract? Java Basics - Anfänger-Themen 10
O Verständniss Problem bei abstract class Java Basics - Anfänger-Themen 7
H abstract und interface Java Basics - Anfänger-Themen 4
H abstract - Wozu? Java Basics - Anfänger-Themen 6
B Interface vs Abstract Java Basics - Anfänger-Themen 2
B Objekte zählen/ Vererbung/ Kopplung/ Interface/ Abstract Class Java Basics - Anfänger-Themen 5
W Vererbung, abstract und Konstruktoren Java Basics - Anfänger-Themen 30
J OOP Wie sollte ich das organisieren (Abstract? Interface?) Java Basics - Anfänger-Themen 33
Azazel Ist die abstract class das selbe wie ein interface ? Java Basics - Anfänger-Themen 33
S Compiler-Fehler not abstract and does not override Java Basics - Anfänger-Themen 9
M abstract method does not override or implement.... Java Basics - Anfänger-Themen 7
B Fehler : class is abstract and does not overwrite Java Basics - Anfänger-Themen 2
B klasse abstract Java Basics - Anfänger-Themen 9
E Klasse abstract machen Java Basics - Anfänger-Themen 3
G Schlüsselworte Bedeutung von abstract Java Basics - Anfänger-Themen 2
C Liste mit Attribut Abstract vererben Java Basics - Anfänger-Themen 11
Y Theorie: Abstract Method Java Basics - Anfänger-Themen 6
P Problem mit Eclipse "must be declared as abstract" Java Basics - Anfänger-Themen 3
O Abstract Method & Generics Java Basics - Anfänger-Themen 10
B abstract static Java Basics - Anfänger-Themen 16
T abstract class Java Basics - Anfänger-Themen 8
K abstract Java Basics - Anfänger-Themen 8
W abstract static Java Basics - Anfänger-Themen 3
F does not overwride abstract method Java Basics - Anfänger-Themen 2
G Verständnisfrage zum Interface und Abstract Java Basics - Anfänger-Themen 3
A in abstract Klasse private Variablen Java Basics - Anfänger-Themen 3
J abstract & Polymorphismus Java Basics - Anfänger-Themen 11
K Problem mit Abstract Table Model Java Basics - Anfänger-Themen 5
D Fehlermeldung "Time is not abstract" Java Basics - Anfänger-Themen 6
T Problem mit Abstract Windowing Toolkit(simples Problem) Java Basics - Anfänger-Themen 8
P Adaptor, Abstract Factory Java Basics - Anfänger-Themen 12
K <class> is not abstract and does not override abstract Java Basics - Anfänger-Themen 5
S Brauche Hilfe bei "abstract" Java Basics - Anfänger-Themen 12
G fenster abstract Java Basics - Anfänger-Themen 18
R abstract class <-> instance Java Basics - Anfänger-Themen 6
G Abstract Class - Abstract Method Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben