简体   繁体   中英

Overriding method with Generics

I have a base class called GenericOrder that can be used to create an order with any type of products, then I have subclasses of that order that are more specific. My problem is with my ComputerOrder class and a method that I'm overriding. Here's the base class code.

import java.util.List;
import java.util.ArrayList;

public class GenericOrder<T> {

private long orderNumber;
private List<T> products;
private T theClass;

public GenericOrder() 
{
    products = new ArrayList<T>();
    orderNumber = System.currentTimeMillis();
}

public long getOrderNumber() {
    return orderNumber;
}

public void addProduct(T newProduct) {
    products.add(newProduct);

}

public int getNumberOfProducts() {
    return products.size();
}

public List<T> getProducts()
{
    return products;
}

public void setProducts(List<T> products)
{
    this.products = products;
}

public T get()
{
    return theClass;
}

public void set(T theClass)
{
    this.theClass = theClass;
}
}

And here is my subClass code. The getProducts is the method I'm having trouble with.

import java.util.ArrayList;
import java.util.List;

public class ComputerOrder<T> extends GenericOrder<T> {
    private List<ComputerPart> computerParts = new ArrayList<ComputerPart>();
    private String orderType = "Computer Parts";

public ComputerOrder() {
    super();

}

public void addProduct(ComputerPart newProduct) {

    computerParts.add(newProduct);

}

public String getOrderType() {
    return orderType;
}

public int getNumberOfProducts() {
    return computerParts.size();
}


public List<T> getProducts()
{

    return computerParts;
}


}

The Error I get says cannot convert from List(ComputerPart) to List<T>

The error is pretty clear: getProducts() is declared to return a List<T> yet you're returning a List<ComputerPart> . I think we agree that these two are not equivalent.

Looking at your code it looks like that you actually don't want a generic class since ComputerOrder only accepts ComputerPart s. What you want is something like the following:

public class ComputerOrder extends GenericOrder<ComputerPart> {
    @Override
    public List<ComputerPart> getProducts() {
        return computerParts;
    }
}

Design wise, I think you should reconsider whether products should be in the GenericOrder class. If GenericOrder is meant only to handle the orders, then it might not make sense to have any product related methods or fields defined there. As it is now you have a products List array in GenericOrder that is not being used because you have defined computerParts List array in ComputerOrder. This makes for bad code. In this case your classes would look like:

public class GenericOrder<T> {    
    private long orderNumber;
    private String orderType;
    private T theClass;

    public GenericOrder(String orderType) {
        this.orderType = orderType;
        orderNumber = System.currentTimeMillis();
    }
    public String getOrderType() {
        return orderType;
    }
    public long getOrderNumber() {
        return orderNumber;
    }
    public T get() {
        return theClass;
    }
    public void set(T theClass) {
        this.theClass = theClass;
    }
}

and

import java.util.ArrayList;
import java.util.List;

public class PartOrder<T> extends GenericOrder<T> {
    private List<T> parts = new ArrayList<T>();

    public PartOrder(String orderType) {
        super(orderType);
    }
    public void addProduct(T newProduct) {
        parts.add(newProduct);
    }
    public int getNumberOfProducts() {
        return parts.size();
    }
    public List<T> getProducts() {
        return parts;
    }
}

and you would have a ComputerPartOrder class like so:

public class ComputerPartOrder extends PartOrder<ComputerPart> {

    public ComputerPartOrder() {
        super("Computer Parts");
    }
}

Otherwise, you might also define the GenericOrder.getProducts method as abstract as per this stackoverflow post .

It actually looks like you don't want your ComputerOrder to be generic. While a GenericOrder<T> is generic and can be an order of anything, ComputerOrder seems specific to ComputerPart(s) and should extend GenericOrder<ComputerPart> . This way you will only have to implement List<ComputerPart> getProducts() and your code will be fine.

As your ComputerOrders class looks more specific, consider refactoring your code as below :

public class ComputerOrder extends GenericOrder<ComputerPart> { 

@Override 
public List<ComputerPart> getProducts() { return computerParts; }
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM