2016-04-11 7 views
0

ich mit dem Besucher-Muster bin zu entwickeln, wie folgt aus:Polymorphismus zwischen einem Elternteil und einem Kind Klasse

public abstract class AbstractVisitor { 
    public void visit(AbstractConfig config) { 
     throw new NotImplementedException(); 
    } 
} 

, die von

@Component 
public class ConcreteVisitor extends AbstractVisitor { 
    public void visit(ConfigA config) { 
     // Do something 
    } 
    public void visit(ConfigB config) { 
     // Do something 
    } 
} 

vererbt Wo, natürlich ConfigA und ConfigBAbstractConfig verlängern .

ich die Bean-Instanz von ConcreteVisitor verwenden, indem Sie es wie folgt autowiring:

@Autowired 
private AbstractVisitor visitor; 

Das Problem ist, wenn ich visitor.visit(config) nennen, wo config eine Instanz von ConfigA ist, wirft es ein NotImplementedException.

Jetzt habe ich alle möglichen abstrakten Methoden in AbstractVisitor erklärt, aber gibt es noch eine andere bevorzugte Lösung? Ich meine, ein konkreter Besucher kann beliebige polymorphe Methoden zum Argument der abstrakten Methode der Eltern definieren.

Vielen Dank im Voraus.

+0

ersetzen diese: public void Besuch (AbstractConfig config) { throw new NotImplementedException(); } mit: public void visit (AbstractConfig config); und stellen Sie sicher, dass Ihr Autowiring Drähte eine Implementierung der richtigen Klasse – Stultuske

+0

@Stultuske, danke für Ihren Kommentar, aber das hat nicht funktioniert, immer noch den Fehler ausgelöst. – tsuda7

+1

Das ist auch einer der Gründe, warum '@ Override' wichtig ist: Es rettet dich vor einem Problem wie dem, dass du dachtest, du hättest eine Methode außer Kraft gesetzt, aber nicht –

Antwort

2

public void visit(AbstractConfig) ist nicht dasselbe wie public void visit(ConfigA). Wenn Sie eine AbstractConfig haben und visit aufrufen, wird die Methode des übergeordneten Elements aufgerufen.

AbstractConfig con = new ConfigA(); 
visitor.visit(con); //NoImplementedException (parent's method) 

ConfigA = conA = new ConfigA(); 
visitor.visit(conA); //OK, ConcreteVisitor's method 

Sie haben jede Methode für jede konkrete Umsetzung von AbstractConfig zu erklären. Verwenden Sie eine Schnittstelle für die Besucher statt:

public interface Visitor { 
    public void visit(ConfigA config); 
    public void visit(ConfigB config); 
} 

@Component 
public class ConcreteVisitor implements Visitor { 

    @Override 
    public void visit(ConfigA config) { 
     // Do something 
    } 

    @Override 
    public void visit(ConfigB config) { 
     // Do something 
    } 
} 

@Autowired 
private Visitor visitor; 
+0

danke für deine Antwort, aber das erlaubt uns nicht, eine andere zu definieren Methode, sagen 'besuchen (ConfigC Config)', 'besuchen (ConfigD Config)' etc ... – tsuda7

+1

Sie haben Recht, das ist, weil die Verwendung von Besucher Muster sehr gerechtfertigt sein muss. Jedes Mal, wenn Sie eine neue 'AbstractConfig'-Implementierung hinzufügen möchten, müssen Sie eine Methode zur' Visitor'-Schnittstelle hinzufügen und sie in 'ConcreteVisitor' implementieren. –

+0

Ich bekomme das Bild. Was ich gerne machen würde, ist ein bisschen anders (Es wäre besser, wenn ich eine andere Implementierungs-Bean flexibel ersetzen könnte), aber das bedeutet, dass das Besucher-Muster nicht vorzuziehen ist, oder? Ich werde meinen Code beibehalten, wie du es vorgeschlagen hast. Danke @ Bigdestroyer – tsuda7

Verwandte Themen