Abstrakte Klasse: vererbte Klasse; instance of?

Kababär

Top Contributor
Hi,

ich habe mir eine Abstrakte Klasse geschrieben

Code:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package financing.konto;

import financing.verwaltung.AuftragObject;
import java.util.ArrayList;
import java.util.List;

/**
*
* @author Blackace
*/
public abstract class AKonto {

    private String kontoName;
    private final String IBAN;
    private final String BIC;
    private double amount;
    private boolean allowsDisp;
    private double dispLimit;
    private List<AuftragObject> auftragList = new ArrayList<>();

    public AKonto(String IBAN, String BIC, double amount) {
        this.IBAN = IBAN;
        this.BIC = BIC;
        this.amount = amount;
    }

    public AKonto(String k, String IBAN, String BIC, double amount) {
        this.kontoName = k;
        this.IBAN = IBAN;
        this.BIC = BIC;
        this.amount = amount;
    }

    public AKonto(String k, String IBAN, String BIC, double amount,
            boolean canDispo) {
        this.kontoName = k;
        this.IBAN = IBAN;
        this.BIC = BIC;
        this.amount = amount;
        this.allowsDisp = canDispo;
    }

    public AKonto(String k, String IBAN, String BIC, double amount,
            boolean canDispo, double dispLimitation) {
        this.kontoName = k;
        this.IBAN = IBAN;
        this.BIC = BIC;
        this.amount = amount;
        this.allowsDisp = canDispo;
        this.dispLimit = dispLimitation;
    }

    public String getIBAN() {
        return IBAN;
    }

    public String getBIC() {
        return BIC;
    }

    public void pushAmount(AuftragObject i) {

        amount += i.getAmount();
    }

    public void popAmount(AuftragObject i) {
        amount -= i.getAmount();
    }

    public void transferAmount(AKonto from, AKonto to, AuftragObject a) {
        addAuftrag(a);
        from.popAmount(a);
        to.pushAmount(a);
    }

    public double getAmount() {
        return amount;
    }

    public String getKontoName() {
        return kontoName;
    }

    public void setKontoName(String k) {
        this.kontoName = k;
    }

    public boolean isAllowsDisp() {
        return allowsDisp;
    }

    public void setAllowsDisp(boolean allowsDisp) {
        this.allowsDisp = allowsDisp;
    }

    public double getDispLimit() {
        return dispLimit;
    }

    public void setDispLimit(double dispLimit) {
        this.dispLimit = dispLimit;
    }

    @Override
    public String toString() {
        return kontoName + "(" + IBAN + ")" + amount;
    }

    public List<AuftragObject> getAuftragList() {
        return auftragList;
    }

    public void setAuftragList(List<AuftragObject> auftragList) {
        this.auftragList = auftragList;
    }

    public void addAuftrag(AuftragObject a) {
        this.auftragList.add(a);
    }
}

und mehrere Klassen (Girokonto, Kreditkonto, Sparbuch), die von dieser Klasse erben.
Bei dem Konkreten Fall, dass ich ein Konto erstellen will, habe ich in meinem Model eine add-Methode.
Des Weiteren sind dort alle Listen für diese Konten gespeichert:

Code:
public class KontoModel {

    private List<Girokonto> giroList = new ArrayList<>();
    private List<Kreditkonto> kreditList = new ArrayList<>();
    private List<Sparbuch> sparList = new ArrayList<>();

    public List<Girokonto> getGiroList() {
        return giroList;
    }

    public void setGiroList(List<Girokonto> giroList) {
        this.giroList = giroList;
    }

    public List<Kreditkonto> getKreditList() {
        return kreditList;
    }

    public void setKreditList(List<Kreditkonto> kreditList) {
        this.kreditList = kreditList;
    }

    public List<Sparbuch> getSparList() {
        return sparList;
    }

    public void setSparList(List<Sparbuch> sparList) {
        this.sparList = sparList;
    }
   
   

    public void addKonto(AKonto konto) {
        switch () {
            case "Girokonto":

                break;
            case "Kreditkonto":

                break;
            case "Sparbuch":

                break;
            default:
                throw new AssertionError();
        }
    }

}

Bei dem unteren Teil hängt es nun, in der Add-Methode, denn ich weiß nicht wie ich herausfinden kann, welche Klasse AKonto nun explizit ist. Also ich gebe entweder im Parameter ein Girkonot, Sparbuch oder Kreditkonto mit.
Je nachdem welches Konto es ist, will ich es in die dementsprechende Liste packen.
Kann mir wer helfen?
Die Add-Methode ist noch unvollständig und fehlerhaft.
 

flopalko

Bekanntes Mitglied
Du kannst dies entweder mit dem instanceof Operator oder per getClass machen. Schau dir diese zwei Möglichkeiten mal an, wenn du dann noch Fragen dazu hast frag ruhig nach.
 

Tobse

Top Contributor
Du kannst dies entweder mit dem instanceof Operator oder per getClass machen. Schau dir diese zwei Möglichkeiten mal an, wenn du dann noch Fragen dazu hast frag ruhig nach.
Instanceof bitte nicht und getClass() auf gar keinen Fall! Man sollte nie ein instanceof für Awnendungslogik brauchen, nie!

Die Klasse KontoModel ist absolut schlecht designed! Siehe dazu: sie macht das Open/Close- und das Liskovschke Substitutionsprinzip zunichte.

Mein Alternativvorschlag für ModelKonto, davon ausgehend, dass die Methodensignaturen von der Aufgabenstellung vorgeschrieben sind. (Denn die Methodensignaturen an sich verletzen die beiden oben genannten Gesetze):

Java:
public class KontoModel {

    private Set<AKonto> konten = new ArrayList<>();

    private Collection<T> <T extends AKonto> getAKontosOfType(Class<T> type) {
        return (Collection<T>) (konten.stream().filter(k -> k instanceof T).collect(Collectors.toCollection(ArrayList::new)));
    }
  
    private void <T extends AKonto> setTypeList(Collection<T> typedList) {
        Set<T> toBeRemoved = new HashSet<>();
        // entferne alle AKonto vom Typ T von konten, welche nicht in typedList sind
        for (AKonto k : konten) {
            if (k instanceof T && !typedList.contains(k)) {
                toBeRemoved.add(k);
            }
        }
        konten.removeAll(toBeRemoved);
      
        // die neuen konten hinzufügen
        konten.addAll(typedList);
    }
  
    public List<Girokonto> getGiroList() {
        return getAKontosOfType(Girokonto.class);
    }

    public void setGiroList(List<Girokonto> giroList) {
        setTypeList(giroList);
    }

    public List<Kreditkonto> getKreditList() {
        return getAKontosOfType(Kreditkonto.class);
    }

    public void setKreditList(List<Kreditkonto> kreditList) {
        setTypeList(kreditList);
    }

    public List<Sparbuch> getSparList() {
        return getAKontosOfType(Sparbuch.class);
    }

    public void setSparList(List<Sparbuch> sparList) {
        setTypeList(sparList);
    }
  
    public void addKonto(AKonto konto) {
        konten.add(konto);
    }
}

Mit dieser Version kann man mal zumindest neue Konten-Typen einführen, ohne KontoModel anfassen zu müssen. Aber instanceof ist immernoch in Verwendung, wenn auch die Vernwendung hier unkritisch ist.

Wenn die Methoden von KontoModel nicht vorgeschrieben sind, möchte ich diese Version vorschlagen:

Java:
public class KontoModel extends Set<AKonto> {
    public Collection<T> <T extends AKonto> getKontenVomTyp(Class<T> type) {
        return (Collection<T>) (stream().filter(k -> k instanceof T).collect(Collectors.toCollection(ArrayList::new)));
    }
}

Das kann imho genau die gleichen Anwendungsfälle abdecken und ist aus Design-Sicht (zwar nicht perfekt aber) deutlich besser als der Entwurf vom TE.

P.S.:
Es sieht so aus, als ob die Anwendung darauf angewiesen ist, die Konten nach Typ zu behandeln. Dort sitzt der Kern des Problems: Wenn man einmal eine Abstraktion einführt (in diesem Fall ist das die Methode addKonto(AKonto)), kann man sie an anderer Stelle nicht rückgängig machen, ohne sich tief ins eigene Fleisch zu schneiden. Die Abstraktion der Kontoarten zu AKonto sollte also an einer anderen Stelle stadtfinden.
 

Kababär

Top Contributor
Danke für deine ausführliche Antwort! Dass meine Designs von Projekten schlecht sind, merke ich selbst.. spätestens dann, wenn ich überlegen muss, wie ich nun an gewisse Objekte oder Klassen rankomme und wenn über zu viele Ecken geht oder wenn viele Klassen viele weitere Klassen importieren müssen, um an die Daten zu kommen..
Aber anders haben wir es bisher an der FH nicht gelernt. Model, Presenter (Controller), View.
Dabei war die Struktur jeweils so wie ich sie hatte.. immer ohne Generics. Wobei mir deine Version besser gefällt, auch wenn sie nicht durchsichtlich ist wie meine.

Also die Behandlung, um welchen Typ Konto es sich handelt, habe ich nun in meinen Controller gepackt und die jeweiligen Methoden in das Model gepackt:

Code:
public class KontoModel {

    private List<Girokonto> giroList = new ArrayList<>();
    private List<Kreditkonto> kreditList = new ArrayList<>();
    private List<Sparbuch> sparList = new ArrayList<>();
    private ListView giroLV, kreditLV, sparLV;

    public void addGiro(Girokonto g) {
        if (!giroList.contains(g)) {
            this.giroList.add(g);
            giroLV.getItems().setAll(giroList);
        }
    }

    public void addKredit(Kreditkonto k) {
        if (!kreditList.contains(k)) {
            this.kreditList.add(k);
            kreditLV.getItems().setAll(kreditList);
        }
    }

    public void addSpar(Sparbuch s) {
        if (!sparList.contains(s)) {
            this.sparList.add(s);
            sparLV.getItems().setAll(sparList);
        }
    }

    public List<Girokonto> getGiroList() {
        return giroList;
    }

    public void setGiroList(List<Girokonto> giroList) {
        this.giroList = giroList;
    }

    public List<Kreditkonto> getKreditList() {
        return kreditList;
    }

    public void setKreditList(List<Kreditkonto> kreditList) {
        this.kreditList = kreditList;
    }

    public List<Sparbuch> getSparList() {
        return sparList;
    }

    public void setSparList(List<Sparbuch> sparList) {
        this.sparList = sparList;
    }

    public ListView getGiroLV() {
        return giroLV;
    }

    public void setGiroLV(ListView giroLV) {
        this.giroLV = giroLV;
    }

    public ListView getKreditLV() {
        return kreditLV;
    }

    public void setKreditLV(ListView kreditLV) {
        this.kreditLV = kreditLV;
    }

    public ListView getSparLV() {
        return sparLV;
    }

    public void setSparLV(ListView sparLV) {
        this.sparLV = sparLV;
    }
}

Code:
@FXML
    public void createNewKonto() {
        if (createNewKontoNameFilled) {
            if (selectedDispoLimit == 0 && selectedIBAN.isEmpty()) {
                switch (createNewKontoArt) {
                    case "Girokonto":
                        kModel.addGiro(new Girokonto(selectedKontoname, selectedKap));
                        GUIUpdater.forceListRefreshOn(kModel.getGiroLV());
                        break;
                    case "Kreditkonto":
                        kModel.addKredit(new Kreditkonto(selectedKontoname, selectedKap));
                        GUIUpdater.forceListRefreshOn(kModel.getKreditLV());
                        break;
                    case "Sparbuch":
                        kModel.addSpar(new Sparbuch(selectedKontoname, selectedKap));
                        GUIUpdater.forceListRefreshOn(kModel.getSparLV());
                        break;
                }
            } else if (selectedDispoLimit == 0) {
                switch (createNewKontoArt) {
                    case "Girokonto":
                        kModel.addGiro(new Girokonto(selectedKontoname, selectedIBAN, selectedBIC, selectedKap));
                        GUIUpdater.forceListRefreshOn(kModel.getGiroLV());
                        break;
                    case "Kreditkonto":
                        kModel.addKredit(new Kreditkonto(selectedKontoname, selectedIBAN, selectedBIC, selectedKap));
                        GUIUpdater.forceListRefreshOn(kModel.getKreditLV());
                        break;
                    case "Sparbuch":
                        kModel.addSpar(new Sparbuch(selectedKontoname, selectedIBAN, selectedBIC, selectedKap));
                        GUIUpdater.forceListRefreshOn(kModel.getSparLV());
                        break;
                }
            } else if (selectedIBAN.isEmpty()) {
                switch (createNewKontoArt) {
                    case "Girokonto":
                        kModel.addGiro(new Girokonto(selectedKontoname, selectedKap, canDispo, selectedDispoLimit));
                        GUIUpdater.forceListRefreshOn(kModel.getGiroLV());
                        break;
                    case "Kreditkonto":
                        kModel.addKredit(new Kreditkonto(selectedKontoname, selectedKap, canDispo, selectedDispoLimit));
                        GUIUpdater.forceListRefreshOn(kModel.getKreditLV());
                        break;
                    case "Sparbuch":
                        kModel.addSpar(new Sparbuch(selectedKontoname, selectedKap, canDispo, selectedDispoLimit));
                        GUIUpdater.forceListRefreshOn(kModel.getSparLV());
                        break;
                }
            }
        }
    }

Das funktioniert zwar, gefällt mir aber auch nicht..
 

Tobse

Top Contributor
Dass meine Designs von Projekten schlecht sind, merke ich selbst. [...] Aber anders haben wir es bisher an der FH nicht gelernt. Model, Presenter (Controller), View.
Dass du es selbst merkst ist schon ein guter Anfang ;) Und ich helfe dir auch gerne, das zu verbessern :)


Zu deinem Model:
Dass das Model an der View rumschraubt gefällt mir garnicht (siehe SRP = Single-Responsibility-Prinzip (aka SoC = Separation of Concerns Principle)). Wie geht das besser? Mein Vorschlag:

Im MVC ist das Model für die Datenhaltung zuständig. Und nach SRP sollte es nicht mit der View interagieren (denn die Haltung der Daten hat mit der Darstellung der selbigen erstmal nix zu tun). Das Model kann aber sehr wohl Listener aufrufen, wenn es sich ändert (Listener sind ja komplett unabhängig). Und das View kann darauf reagieren und sie Darstellung korrigieren:

Java:
/**
* Ersetzt KontoModel; in einer Enterprise-Anwendung passiert hier auch die DB-Kommunikation (und NUR hier, wieder SRP).
*/
class AccountRepository {
    private Set<Konto> accounts = new HashSet<>();

    private Set<Consumer<Konto>> accountAddedListeners = new HashSet<>();
    private Set<Consumer<Konto>> accountRemovedListeners = new HashSet<>();
  
    public void addAccount(AKonto konto) {
        if (accounts.add(konto)) {
            accountAddedListeners.forEach(c -> c.accept(konto));
        }
    }
  
    public void removeAccount(AKonto konto) {
        if (accounts.add(konto)) {
            accountRemovedListeners.forEach(c -> c.accept(konto));
        }
    }
  
    public void onAccountAdded(Consumer<AKonto> l) {
        accountAddedListeners.add(l);
    }
  
    public void onAccountRemoved(Consumer<AKonto> l) {
        accountRemovedListeners.add(l);
    }
  
    public Collection<T> <T extends AKonto> getAccountsOfType(Class<T> type) {
        return (Collection<T>) (accounts.stream().filter(k -> k instanceof T).collect(Collectors.toCollection(ArrayList::new)));
        // in einer enterprise anwendung würde hier ein HQL query stehen, etwa: FROM AKonto WHERE class = T.class
    }
}

Und dann kannst du in deiner View ganz bequem listener beim Repository registrieren:

Java:
accountRespository.onAccountAdded(konto -> {
    if (konto instanceof Girokonto) {
        giroLV.add(konto);
    }
    ... u.s.w.
});
Aber auch hier ist wieder das Problem mit der Abstraktion: wenn du im Model zu AKonto abstrahierst, musst du es im View wieder aufdröseln. Deswegen die Abstraktion komplett durchziehen (den Typ ggf. in der ListView erwähnen?) oder die Abstraktion entfernen.
 

Kababär

Top Contributor
@Tobse Mit Consumer hatte ich bisher noch nichts am Hut gehabt, aber werde mir mal angucken was diese Datenstruktur so drauf hat und wozu man die verwenden kann.
Dann werde ich mal deine Ratschläge in meinen Code einbauen und sehen, ob ich alles so geändert bekomme, dass noch alles läuft. Die Seite ooodesign scheint vernünftig zu sein, die kommt mal in meine Lesenzeichen-Liste :)

Eben. Warum dann nicht einfach subclassen ?

Ganz am Anfang hatte ich mir überlegt, ob es nicht einfach schon reicht, eine Klasse Konto zu erstellen und als Klassenattribut ein String zu definieren a la "Kontotyp". So hätte ich zwar keine 3 Klassen, aber das Design wäre auch nicht gerade gut. Du meinst also einfach das Abstract weglassen? Werde ich umsetzen, danke :)

Edit:
Code:
    public Collection<T> <T extends AKonto> getAccountsOfType(Class<T> type) {
        return (Collection<T>) (accounts.stream().filter(k -> k instanceof T).collect(Collectors.toCollection(ArrayList::new)));
        // in einer enterprise anwendung würde hier ein HQL query stehen, etwa: FROM AKonto WHERE class = T.class
    }
Da meint der Compiler: "unexcepted return value" :s
 
Zuletzt bearbeitet:

Tobse

Top Contributor
Code:
    public Collection<T> <T extends AKonto> getAccountsOfType(Class<T> type) {
        return (Collection<T>) (accounts.stream().filter(k -> k instanceof T).collect(Collectors.toCollection(ArrayList::new)));
        // in einer enterprise anwendung würde hier ein HQL query stehen, etwa: FROM AKonto WHERE class = T.class
    }
Da meint der Compiler: "unexcepted return value" :s
Versuch mal public <T extends AKonto> Collection<T> getAccountsOfType
 

InfectedBytes

Top Contributor
Wenn die drei Klassen wirklich gleich sind, ist es sehr unnötig das mit Vererbung zu lösen. Da wäre es besser den Typ einfach als attribut anzugeben.
Java:
public enum KontoTyp {
  GIRO, KREDIT, SPAR
}
public class Konto {
  private final KontoTyp typ;
  public KonoTyp getTyp() { return typ; }
  public Konto(KontoTyp typ) {
    this.typ = typ;
  }
}
 

Kababär

Top Contributor
Auch nicht schlecht! So meinte ich das. Dann arbeite ich auch mal mit enums :D Wollte es schon ein paar Mal erzwingen, aber das war dann letztendlich nonsense (bei anderen Projekten).
 

Tobse

Top Contributor
Nur meckert er noch " illegal generic type for instanceof". Wenn ich type reinschreibe, ist die Sichtbarkeit weg (denke ich mal). Muss ich hier die drei Fälle "Girokonto", "Kreditkonto" und "Sparbuch" unterscheiden?
Die Methode ist ja genau deshalb generisch, weil sie für alle Unterklassen, bekannte und unbekannte, funktionieren soll.

Ich habe jetzt mal selber den Compiler bemüht und es sieht so aus, als ob man Generics nicht mit dem Instanceof verbinden kann. Daher muss man auf die java.lang.Class zurückgreiffenm und das ist eklig.... genau deshalb will man sowas ja eigentlich vermeiden :/
Dashier wird funktionieren:

Java:
public <T extends Super> Collection<T> getAccountsOfType(Class<T> type) {
    return (Collection<T>) (accounts.stream().filter(k -> type.isAssignableFrom(k.getClass())).collect(Collectors.toCollection(ArrayList::new)))
}
 

Kababär

Top Contributor
Nachdem ich den Vorschlag von InfectedBytes implementiert habe, muss ich statt

Code:
k -> k instanceof T
nur noch
Code:
 k-> k.getType().equals(type)
schreiben mit dem entsprechenden Parameter
Code:
 Konto.KontoTyp typ


Ich danke euch und werde mich bemühen, dieses Konzept beizubehalten :)
 

Kababär

Top Contributor
Da ich meine Liste, je nachdem welcher Kontotyp es ist, filtern will, um das Konto in die dementsprechende ListView einzutragen, wird das so nicht funktionieren denke ich..

Aber es passt ja alles so wie es ist :)

Was mir aber noch schleierhaft ist: mit Consumer kann ich mir quasi eigene Listener basteln? Immer wenn sich etwas an meiner Datenstruktur geändert, kann ich dazu ein geeignetes Event triggern? Das eröffnet ja ungeahnte Möglichkeiten.
Habe mich schon oft gefragt, ob so was nicht geht.. aber da fand ich nur so was wie "Ahja.. dann rufst du halt jedes mal die Methode auf".
 
Zuletzt bearbeitet:

Tobse

Top Contributor
du kannst direkt: if(k.getTyp() == KontoTyp.GIRO) ... verwenden
Und was genau ist daran jetzt besser als ein instanceof? Das Enum erfüllt das Substitutionsprinzip, das Open/Close-Prinzip bleibt aber weiterhin verletzt...


Was mir aber noch schleierhaft ist: mit Consumer kann ich mir quasi eigene Listener basteln? Immer wenn sich etwas an meiner Datenstruktur geändert, kann ich dazu ein geeignetes Event triggern? Das eröffnet ja ungeahnte Möglichkeiten.
Habe mich schon oft gefragt, ob so was nicht geht.. aber da fand ich nur so was wie "Ahja.. dann rufst du halt jedes mal die Methode auf".
Consumer ist eigentlich für etwas anderes gedacht; Ich habe es nur der Einfachheit her verwendet. Richtig wäre folgendes:

Java:
class AccountRepository {
  /* ... der ganze andere Code ... */

  interface AccountAddedListener {
    public void onAccountAdded(AKonto konto);
  }

  interface AccountRemovedListener {
    public void onAccountRemoved(AKonto konto);
  }
}

Und dann entsprechend diese Klassen anstatt Consumer<AKonto> verwenden.
In Java 8 bleibt aber der Code im View gleich:

Java:
AccountRepository accountRepository = new AccountRepository();
accountRepository.onAccountAdded(k -> System.out.println("Account " + k + " hinzugefügt"));
 

Kababär

Top Contributor
Also am besten statt dem Enum ein Interface beziehungsweise eine eigene Klasse implementieren?

Habe mir mal eben Consumer, Supplier etc angeguckt und verstehe nicht so wirklich wofür das gut sein soll.. Aber vielleicht stoße ich irgendwann nochmal drüber wo die Funktionalität klarer wird.
 

Tobse

Top Contributor
Also am besten statt dem Enum ein Interface beziehungsweise eine eigene Klasse implementieren?
Ich glaube du vermischt gerade die Listener mit den Kontotyp. Ich wollte das nicht in Bezug zueinander setzen, weils nix miteinander zu tun hat. Wenn du das anders meinst stehe ich ggf. bissl aufm Schlauch...

[OFFTOPIC]

Habe mir mal eben Consumer, Supplier etc angeguckt und verstehe nicht so wirklich wofür das gut sein soll.. Aber vielleicht stoße ich irgendwann nochmal drüber wo die Funktionalität klarer wird.
Das ist jetzt schon sehr Offtopic hier. Consumer sind für sowas gedacht:

Java:
// ausgangssituation:
List<String> liste = Arrays.asList("foo", "bar", "hanz", "peter", "javaforum");


liste.forEach(System.out::println);

// das ist gleichbedeutend mit
liste.forEach(e -> System.out.println(e));

// und auch gleichbedeutend mit
liste.forEach(e -> { 
    System.out.println(e);
});

// und gleichbedeutend mit
liste.forEach(new Consumer<String>() {
    @Override
    public void accept(String e) {
        System.out.println(e);
    }
});
Consumer<E> wurde für die Lambdas in Java 8 eingeführt; ist besonders bei Streams hifreich.


[/OFFTOPIC]
 

Kababär

Top Contributor
das Substitutionsprinzip sollte man doch auch auf Klassen anwenden, nicht nur auf Interfaces oder? Also so, dass eine Klasse genau eine Aufgabe hat.
Bspw würde ich eine Klasse IO in zwei Klassen Writer und Reader splitten.

Ich habe mir Consumer nochmal angeguckt und die sind, so wie es im Buch stand, quasi durch Function ersetzbar. Der Vorteil ist doch, dass ich im Block eines Consumers ja eine Reihe Anweisungen schreiben kann ähnliche einer Methode, aber den Consumer selbst, der die Anweisungen enthält, als Objekt verwalten kann so wie wir das oben bei unsrer Liste gemacht haben?
 

Tobse

Top Contributor
das Substitutionsprinzip sollte man doch auch auf Klassen anwenden, nicht nur auf Interfaces oder? Also so, dass eine Klasse genau eine Aufgabe hat.
Bspw würde ich eine Klasse IO in zwei Klassen Writer und Reader splitten.
Jetzt verwechselst du das Substitutionsprinzip mit dem Single-Responsibility-Prinzip :S Interfaces erleichtern die Anwendung des Substitutionsprinzips (weil man leichter ein Interface implementieren als von einer Klasse erben kann).

Ich habe mir Consumer nochmal angeguckt und die sind, so wie es im Buch stand, quasi durch Function ersetzbar. Der Vorteil ist doch, dass ich im Block eines Consumers ja eine Reihe Anweisungen schreiben kann ähnliche einer Methode, aber den Consumer selbst, der die Anweisungen enthält, als Objekt verwalten kann so wie wir das oben bei unsrer Liste gemacht haben?
Consumer<E> ist ein Interface wie jedes andere. Die Besonderheit daran ist, dass es ein SAM (Single Abstract Method)-Interface ist und damit Lambdas erlaubt. Lambdas sind nur eine hübschere Schreibweise für innere Klassen, mehr nicht.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
E abstrakte Klasse implementiert ein Interface Java Basics - Anfänger-Themen 40
T Abstrakte Klasse und Interfaces Java Basics - Anfänger-Themen 12
D Abstrakte Klasse, Konstruktorkette, Attribute setzen Java Basics - Anfänger-Themen 12
J abstrakte Methode in Klasse mit Rückgabetyp der abgeleiteten Klasse Java Basics - Anfänger-Themen 5
I Abstrakte Klasse - static Attribute deklarieren Java Basics - Anfänger-Themen 14
T Übungsaufgabe abstrakte Klasse Java Basics - Anfänger-Themen 21
kilopack15 Beziehung Interface - (abstrakte) Klasse -Unterklasse Java Basics - Anfänger-Themen 3
N Vererbung Abstrakte Klasse stateful Java Basics - Anfänger-Themen 3
W Abstrakte Klasse mit Variable? Java Basics - Anfänger-Themen 2
A Vererbung Abstrakte Klasse mit Methode die Objekte der Subklassen benutzt? Java Basics - Anfänger-Themen 7
W Abstrakte und konkrete Klasse Java Basics - Anfänger-Themen 4
F Abstrakte Klasse doch zum "Teil" instanzieren? Java Basics - Anfänger-Themen 4
M Statische Methoden in Interface/Abstrakte Klasse Java Basics - Anfänger-Themen 6
N Datentypen abstrakte Klasse wird instanziert Java Basics - Anfänger-Themen 3
propra Interface - abstrakte Klasse Java Basics - Anfänger-Themen 18
N Abstrakte Klasse Java Basics - Anfänger-Themen 28
L Über abstrakte Klasse auf eine Klasse zugreifen? Java Basics - Anfänger-Themen 6
D Wann genau abstrakte Klasse und wann ein Interface verwenden? Java Basics - Anfänger-Themen 4
StupidAttack Abstrakte Methoden in nicht-abstrakter Methode in abstrakter Klasse Java Basics - Anfänger-Themen 6
T Abstrakte Klasse Java Basics - Anfänger-Themen 3
S Abstrakte Klasse Java Basics - Anfänger-Themen 5
K Abstrakte Klasse vs. Interface Java Basics - Anfänger-Themen 21
K Abstrakte Klasse bilden? Java Basics - Anfänger-Themen 11
S Abstrakte Klasse, festlegen, dass Methode verändert werden muss. Java Basics - Anfänger-Themen 4
H Warum Java? | Abstrakte Klasse = Modul? Java Basics - Anfänger-Themen 20
J abstrakte klasse und methode super Java Basics - Anfänger-Themen 2
H Eine Abstrakte Klasse muss. Java Basics - Anfänger-Themen 7
G Abstrakte Klasse "Point" Java Basics - Anfänger-Themen 2
G Abstrakte Methode in gleicher Klasse aufrufen Java Basics - Anfänger-Themen 5
M abstrakte Klasse Java Basics - Anfänger-Themen 3
F Abstrakte Klasse: Konstruktor vs init() Java Basics - Anfänger-Themen 13
G Abstrakte Klasse (was passiert hier) Java Basics - Anfänger-Themen 3
G Interface oder Abstrakte Klasse? Java Basics - Anfänger-Themen 3
Acha Unterschied Interface - abstrakte Klasse Java Basics - Anfänger-Themen 4
B OOP: abstrakte klasse implementiert interface Java Basics - Anfänger-Themen 3
D Abstrakte Klasse Graphics Java Basics - Anfänger-Themen 3
A Abstrakte Klasse Java Basics - Anfänger-Themen 3
G abstrakte klasse Java Basics - Anfänger-Themen 6
F Abstrakte Klasse Baum Java Basics - Anfänger-Themen 6
J Methodenaufrufe abstrakte Klassen, Interfaces Java Basics - Anfänger-Themen 17
M Abstrakte Klassen - Notation Java Basics - Anfänger-Themen 9
S Vererbung Abstrakte Methoden: Wozu das Ganze?! Java Basics - Anfänger-Themen 7
S abstrakte methoden in subclass? Java Basics - Anfänger-Themen 7
G Abstrakte Klassen Java Basics - Anfänger-Themen 11
G Java Abstrakte Methoden Java Basics - Anfänger-Themen 2
L Abstrakte Typen und Schnittstellen Java Basics - Anfänger-Themen 19
S Abstrakte Methode nutzen Java Basics - Anfänger-Themen 9
J Objekte und Abstrakte Klassen Java Basics - Anfänger-Themen 2
J Java Interface/abstrakte Klassen Java Basics - Anfänger-Themen 2
M Erste Schritte Prüfungsbeispiel: Interface / abstrakte Klassen Java Basics - Anfänger-Themen 8
A Interface Abstrakte Interface Methode kann nicht benutzt werden Java Basics - Anfänger-Themen 10
S Gehaltsberechnung (Vererbung, abstrakte Methoden) Java Basics - Anfänger-Themen 6
S Datentypen Abstrakte Datentypen Java Basics - Anfänger-Themen 0
A Abstrakte Datentypen - Methode delete Java Basics - Anfänger-Themen 6
D Abstrakte Klassen Verständniss Frage Java Basics - Anfänger-Themen 4
D Methoden Abstrakte Methoden Java Basics - Anfänger-Themen 3
D Interface Interfaces und abstrakte Klassen implementieren Java Basics - Anfänger-Themen 4
B Abstrakte Klassen Java Basics - Anfänger-Themen 7
C Abstrakte und virtuelle Methoden in Java Java Basics - Anfänger-Themen 4
E verdeckte abstrakte Methode sinnvoll? Java Basics - Anfänger-Themen 7
S Abstrakte Klassen Java Basics - Anfänger-Themen 2
C Dynamische Referenz & abstrakte Klassen Java Basics - Anfänger-Themen 3
V Interface Interfaces und abstrakte Klassen Java Basics - Anfänger-Themen 3
H Abstrakte Basisklasse Verständnisproblem! Java Basics - Anfänger-Themen 8
G Abstrakte Klassen - theoretische Frage Java Basics - Anfänger-Themen 2
OnDemand Abstrakte Klassen Java Basics - Anfänger-Themen 4
T OOP Abstrakte Klassen und ihre Kinder: wie läuft das? Java Basics - Anfänger-Themen 3
M Abstrakte Klassen Java Basics - Anfänger-Themen 2
J Interfaces Abstrakte Klassen Java Basics - Anfänger-Themen 15
M Interface und Abstrakte Klassen Java Basics - Anfänger-Themen 12
D Methoden abstrakte Methoden und Rückgabewerte Java Basics - Anfänger-Themen 2
B Abstrakte Methode vs. Interface Java Basics - Anfänger-Themen 2
R Namenskonvention abstrakte Klassen Java Basics - Anfänger-Themen 6
C OOP Objektstruktur: abstrakte Klassen Java Basics - Anfänger-Themen 3
V Vererbung Abstrakte Methode Java Basics - Anfänger-Themen 3
T OOP abstrakte klassen - methoden Java Basics - Anfänger-Themen 8
M Abstrakte Klassen Java Basics - Anfänger-Themen 21
J Welchen Sinn haben abstrakte Methoden? Java Basics - Anfänger-Themen 4
D Abstrakte Klassen und Interfaces als Paramter in Funktionen Java Basics - Anfänger-Themen 3
T Interfaces: Braucht man abstrakte Klassen eigentlich noch? Java Basics - Anfänger-Themen 3
T OO, Konstruktor, abstrakte Methoden Java Basics - Anfänger-Themen 13
T Abstrakte Klassen Java Basics - Anfänger-Themen 6
C abstrakte Klassen mögen mich nicht... Java Basics - Anfänger-Themen 2
I Abstrakte Klassen Java Basics - Anfänger-Themen 8
D Zusammenfassung von Klassen (Vererbung? Abstrakte Klass? ...?) Java Basics - Anfänger-Themen 8
G Abstrakte Klassen und Methoden Java Basics - Anfänger-Themen 3
C Schnittstellen und Abstrakte Klassen Java Basics - Anfänger-Themen 3
I Abstrakte Klassen Java Basics - Anfänger-Themen 22
G Abstrakte Klassen ? Java Basics - Anfänger-Themen 9
nadoria abstrakte Klassen Java Basics - Anfänger-Themen 6
M Unterscheid Abstrakte Klassen/Interface Klassen? Java Basics - Anfänger-Themen 7
T abstrakte Klassen? Java Basics - Anfänger-Themen 2
G konkretes beispiel: interface hier besser als abstrakte kl. Java Basics - Anfänger-Themen 4
M abstrakte klassen und interfaces Java Basics - Anfänger-Themen 2
L abstrakte Methode nicht implementiert! Java Basics - Anfänger-Themen 5
M abstrakte klassen / Schnittstellen Java Basics - Anfänger-Themen 4
H abstrakte Klassen, Interfaces Java Basics - Anfänger-Themen 13
R Interfaces durch abstrakte Klassen ersetzbar? Java Basics - Anfänger-Themen 8
A Eine abstrakte Methode static machen? Java Basics - Anfänger-Themen 4
A Abstrakte Klassen und Interfaces Java Basics - Anfänger-Themen 11

Ähnliche Java Themen

Neue Themen


Oben