2016-11-25 4 views
3

ich eine Art von Klasse, die die GeneralProduct ist und es sieht aus wie folgt:Zugang zu einem gemeinsamen Verfahren ohne Gussobjekt

public class GeneralProduct() 
{ 
    String label; 
    Object obj; 
    public GeneralProduct(String label, Object obj) 
    { 
    this.label = label; 
    this.obj = obj; 
    } 
} 

Dann habe ich zwei verschiedene Klassen, ProductA und ProductB. Diese beiden Klassen haben eine gemeinsame Methode namens getPrice(). Auf der anderen Seite habe ich genannt ein Array auxList:

ArrayList<GeneralProduct> auxList = new ArrayList<GeneralProduct>(); 
auxList.add(new GeneralProduct(new ProductA(), "ProductA")); 
auxList.add(new GeneralProduct(new ProductB(), "ProductB")); 

Das Problem ist jetzt, dass ich nicht getPrice() in Klassen ProductA und ProductB vom auxList zugreifen können. Wie könnte ich das schaffen? Soll ich so etwas benutzen? Und wenn ja, wie kann ich die Methode getPrice() von den Kindern erben?

public class ProductA extends GeneralProduct 
+0

getPrice() sollte als abstrakte Methode in der Basis-Klasse GeneralProduct deklariert werden. http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html –

+0

Ich habe die Frage möglicherweise falsch gelesen. Warum haben 'GeneralProduct'' ProductA'/'ProductB' als' obj' Parameter? –

+0

Diese Klassendeklaration sieht nicht syntaktisch korrekt aus –

Antwort

5

In Ihrer Frage, wie es scheint, ProductA und ProductB gemeint sind Subklassen von GeneralProduct zu sein; das heißt, dass "ist ein" GeneralProduct, nur mehr spezialisiert.

Wenn ja: Definieren Sie GeneralProduct mit einer abstrakten getPrice Methode (aber lesen Sie weiter¹), die die Unterklassen implementieren. Sie würden wahrscheinlich tun, weg auch mit obj, brauchen Sie es nicht:

public abstract class GeneralProduct { 
    String label; 
    public GeneralProduct(String label) 
    { 
     this.label = label; 
    } 

    public abstract double getPrice(); 
} 

class ProductA extends GeneralProduct { 
    @Override 
    public double getPrice() { 
     // implementation 
    } 
} 

// and the same for ProductB 

Dann:

auxList.add(new ProcuctA("ProductA")); 
auxList.add(new ProcuctB("ProductB")); 

(. Aber man kann obj setzen zurück, wenn Sie es für etwas brauchen)

Beachten Sie, dass getPrice nicht zu abstrahieren, wenn es eine sinnvolle Implementierung gibt, die GeneralProduct bieten könnte, so dass es in einer Unterklasse optional überschreiben.

Sie können sogar nehmen weiter und trennen Sie die Schnittstelle von Produkten aus der Umsetzung aus:

public interface Product { 
    double getPrice(); 
} 

Dann würde die Liste

List<Product> list = new ArrayList<Product>(); 

sein Wenn Sie noch GeneralProduct müssen (wenn ein Bedarf da ist für eine Basisklasse), kann diese Schnittstelle implementiert werden.

public abstract class GeneralProduct implements Product { 
    // ... 
} 

Aber wenn Sie nicht überhaupt eine Basisklasse benötigen, ProductA und ProductB können nur die Schnittstelle selbst implementieren.


jedoch, Vererbung ist nur eine Möglichkeit, Funktionalität bereitzustellen, und manchmal ist es der richtige Weg, und ein anderes Mal ein anderer Ansatz ist sinnvoll: Zusammensetzung. In diesem Fall hätte GeneralProduct " oder ProductB", aber (und ProductB) hätte keine "ist a" -Beziehung mit GeneralProduct.

Das wahrscheinlich immer noch eine Schnittstelle und/oder eine abstrakte Klasse beinhaltet, nur an einem anderen Ort:

public interface Product { 
    double getPrice(); 
} 

class ProductA implements Product { 
    public double getPrice() { 
     // implementation 
    } 
} 

// ...same for ProductB 

public class GeneralProduct { 
    String label; 
    Product product; 
    public GeneralProduct(String label, Product product) 
    { 
     this.label = label; 
     this.product = product; 
    } 

    // You might have something like this, or not 
    public double getProductPrice() { 
     return this.product.getPrice(); 
    } 
} 

// Then using it: 
auxList.add("ProductA", new ProcuctA("ProductA")); 
auxList.add("ProductB", new ProcuctB("ProductB")); 

Sowohl Vererbung und Komposition sind leistungsfähige Werkzeuge.

+0

Das Feld "Objekt" ist unnötig, wenn wir statt der Komposition die Vererbung gewählt haben – Andrew

+0

@AndrewTobilko: Ich bin mir nicht ganz sicher, was das Ziel von "obj" war. Dies scheint eine Erbschaftssituation zu sein, aber vielleicht sollte ich die Komposition als eine Option markieren. –

+0

genau, wenn wir Vererbung wählen, denke ich, dass Objekt gelöscht werden kann. Vielen Dank! – pistacho

Verwandte Themen