[Java] Abstrakte Methode mit allgemeinem Parameter

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von Calyx, 8. August 2012 .

  1. 8. August 2012
    Abstrakte Methode mit allgemeinem Parameter

    Hi,

    habe ein paar Klassen, die AbstractDatabaseBean erweitern:
    Code:
    public class PortDAO extends AbstractDatabaseBean { ...
    
    public class SwitchDAO extends AbstractDatabaseBean { ...
    und in mehreren verschiedenen Controllern Methoden in der Art:
    Code:
    protected List<String> checkChanges(PortDAO port, PortDAO oldPort) { ...
    
    protected List<String> checkChanges(SwitchDAO swiatch, SwitchDAO oldSwitch) { ...
    Jetzt möchte ich das in einer abstrakten Klasse zusammenfassen, nur weiß ich nicht wie ich da als Parameter den Obertyp angeben muss. Habs unter anderem so probiert:

    Code:
     protected abstract List<String> checkChanges(
     Class<? super AbstractDatabaseBean> currentValue,
     Class<? super AbstractDatabaseBean> oldValue);
    oder

    Code:
     protected abstract List<String> checkChanges(
     Object currentValue,
     Object oldValue);
    oder

    Code:
     protected abstract List<String> checkChanges(
     AbstractDatabaseBean currentValue, 
     AbstractDatabaseBean oldValue);
    funktioniert alles nicht, der Compiler meckert immer dass die abstrakte Methode nicht implementiert ist.

    Was muss ich da angeben?
     
  2. 8. August 2012
    Zuletzt bearbeitet: 8. August 2012
    AW: Abstrakte Methode mit allgemeinem Parameter

    So, also mein Ziel ist duplizierten Code zu beseitigen und unsere GUI zu vereinheitlichen, da wir da ein bisschen geschludert und das nicht wirklich abstrahiert haben

    Im DB-Package siehts vereinfacht so aus. Die DAOs basteln mehrere Tabellen zusammen und geben Werte zurück, wobei sie aus verschiedenen Gründen AbstractDatabaseBean erweitern müssen.

    AbstractDatabaseBean.java
    Code:
    public abstract class AbstractDatabaseBean {
    
     public abstract int hashCode();
    
     public abstract boolean equals();
    }
    PortDAO.java
    Code:
    public class PortDAO extends AbstractDatabaseBean {
    
     @Override
     public int hashCode() {
     // TODO Auto-generated method stub
     return 0;
     }
    
     @Override
     public boolean equals() {
     // TODO Auto-generated method stub
     return false;
     }
    }
    
    SwitchDAO.java
    Code:
    public class SwitchDAO extends AbstractDatabaseBean {
    
     @Override
     public int hashCode() {
     // TODO Auto-generated method stub
     return 0;
     }
    
     @Override
     public boolean equals() {
     // TODO Auto-generated method stub
     return false;
     }
    }
    In der GUI implementieren wir MVC und es ist unnötig dass in vielen Klassen der selbe Code steht.

    PortViewController.java
    Code:
    public class PortViewController extends AbstractViewController {
    
     @Override
     protected List<String> checkChanges(PortDAO currentValue, PortDAO oldValue) {
     // TODO Auto-generated method stub
     return null;
     }
    }
    SwitchViewController.java
    Code:
    public class SwitchViewController extends AbstractViewController {
    
     @Override
     protected List<String> checkChanges(SwitchDAO currentValue, SwitchDAO oldValue) {
     // TODO Auto-generated method stub
     return null;
     }
    }
    AbstractViewController.java
    Code:
    public abstract class AbstractViewController {
    
     protected abstract List<String> checkChanges(
     Class<? super AbstractDatabaseBean> currentValue,
     Class<? super AbstractDatabaseBean> oldValue);
    }
    Der Plan ist alle gemeinsamen Methoden in die abstrakte Klasse zu packen und den Views vorzuschreiben, dass sie diese checkChanges-Methode haben müssen. Ich dachte, ich kann dann in AbstractView einfach angeben, dass die Methode als Parameter eine Klasse haben muss, die von AbstractDatabaseBean erbt (was ja auf PortDAO und SwitchDAO zutrifft) und dann in den konkreten Views auch die konkreten DAOs verwenden. Das führt aber dazu, dass eclipse meckert da die Typen der Parameter in den Views nicht auf die in der abstrakten Klasse passen. Bin mir fast sicher dass ich das irgendwann schon mal so in der Art gemacht habe...weiß aber nicht mehr wie^^ eclipse gibt da leider auch keine Hilfe.

    Hoffe das ist einigermaßen verständlich

    Soll genau andersrum sein, also in der abstrakten Klassen den allgemeinen Typ um in den speziellen Views die speziellen DAOs zu verwenden.
     
  3. 8. August 2012
    AW: Abstrakte Methode mit allgemeinem Parameter

    das is dem anschein nach ein eclipse bug.
    der code lässt sich wunderbar kompilieren und lauft ohne probleme.

    Code:
    abstract class ACFoo
    {
     abstract public void bar(ACBar vbar);
    }
    
    abstract class ACBar
    {
     abstract public void baz();
    }
    
    class CBar extends ACBar
    {
     public void baz() { System.out.println("okay"); }
    }
    
    // eclipse meldet: 
    // The type Main must implement the inherited abstract method ACFoo.bar(ACBar)
    public class Main extends ACFoo
    {
     public static void main(String[] args)
     {
     Main foo = new Main();
     foo.bar(new CBar());
     }
     
     public void bar(CBar vbar)
     {
     vbar.baz(); // okay
     }
    }
    
     
  4. 8. August 2012
    AW: Abstrakte Methode mit allgemeinem Parameter

    Hallo!
    @Murdoc: Mich wundert es eher das er das so kompiliert und ausführt. Ich bin nicht der Meinung das es sich um ein Eclipse Bug handelt. Weil du implementierst ja in Main die Methode bar(ACBar vbar); nicht aus, sondern die bar(CBar vbar). Soweit ich weis müssen abstrakte Methoden in nicht abstrakten Klassen implementiert werden.

    Grüße Mever :]
     
    1 Person gefällt das.
  5. 8. August 2012
    Zuletzt bearbeitet: 8. August 2012
    AW: Abstrakte Methode mit allgemeinem Parameter

    ich denke der compiler merkt, dass ich die abstrakte methode mit der signatur gar nicht nutze und optimiert das einfach weg.

    denkfehler... sorry ^^
    dennoch schade irgendwie

    da kommt man wohl ums hin-und-her casten nicht rum, oder man macht es mit
    dem generischen zeug (hässlich mmn.)
     
    2 Person(en) gefällt das.
  6. 8. August 2012
    Zuletzt bearbeitet: 8. August 2012
    AW: Abstrakte Methode mit allgemeinem Parameter

    Mein Vorschlag wäre:

    AbstractViewController.java
    Code:
    import java.util.List;
    
    public abstract class AbstractViewController[B]<DAO extends AbstractDatabaseBean>[/B] {
    
     protected abstract List<String> checkChanges(
     [B]DAO[/B] currentValue,
     [B]DAO[/B] oldValue);
    }
    Wobei "DAO" ein Name ist den du frei wählen kannst (sofern es die Sprachdefinition zulässt).

    PortViewController.java
    Code:
    import java.util.List;
    
    public class PortViewController extends AbstractViewController[B]<PortDAO>[/B] {
    
     @Override
     protected List<String> checkChanges(PortDAO currentValue, PortDAO oldValue) {
     // TODO Auto-generated method stub
     return null;
     }
    
    }
    SwitchViewController.java
    Code:
    import java.util.List;
    
    public class SwitchViewController extends AbstractViewController[B]<SwitchDAO>[/B] {
    
     @Override
     protected List<String> checkChanges(SwitchDAO currentValue,
     SwitchDAO oldValue) {
     // TODO Auto-generated method stub
     return null;
     }
    
    }
     
    1 Person gefällt das.
  7. 9. August 2012
    AW: Abstrakte Methode mit allgemeinem Parameter

    Super Sache, so funktionierts! Erspart einem das rumgecaste und sieht viel hübscher aus, das werd ich jetzt öfter so verwenden! vielen vielen Dank

    // kann dich grad net bewerten alex
     
  8. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.