3

I have a base class Product that has five subclasses (ComputerPart, Peripheral, Service, Cheese, Fruit). Each of these further have 2/3 subclasses.

Then I have a GenericOrder class that acts as a collection of an arbitrary number of objects in the Product class. GenericOrder has a subclass called ComputerOrder that will only allow ComputerPart, Peripheral and Service to be added to the order. I've spent quite some time trying to figure this out but couldn't get a reasonable answer. Please help. Here's what I have for GenericOrder:

public class GenericOrder<T>{

    private static long counter=1;
    private final long orderID = counter++;
    private List<T> orderItems;
    public GenericOrder(){
           orderItems = new ArrayList<T>();
    }
    // and so on with another constructor and add, get and set methods.
}

class ComputerOrder<T> extends GenericOrder{
//need help here
}

Any any will be greatly appreciated.....

Cheers

Abdur Rahman
  • 353
  • 5
  • 16
Shayaan
  • 35
  • 1
  • 5
  • 1
    use a custom interface as tag for the types/classes you want to add to the generic and use the interface name in the generic declaration (make sure the classes chosen are related hierarchicaly) – Nikos M. Mar 12 '15 at 13:54
  • possibly related http://stackoverflow.com/questions/1623480/generic-interface, http://stackoverflow.com/questions/4045389/using-java-generics-in-an-interface-to-enforce-implementation-of-a-method-with-t – Nikos M. Mar 12 '15 at 13:55
  • see also http://www.java2novice.com/java-generics/implements-interface/ – Nikos M. Mar 12 '15 at 13:57
  • you need to have those three classes inherit an interface, and then `class GenericOrder`. if you have a chance to have `T` to be primitives, then you need to define explicit classes without laziness, i.e. `class IntOrder`, `class FloatOrder`, and so on. – Jason Hu Mar 12 '15 at 14:12

1 Answers1

3

I think you want something like this:

GenericOrder:

public class GenericOrder<T> {

    private List<T> orderItems;

    public GenericOrder() {
        orderItems = new ArrayList<T>();
    }

    public void add(T item) {
        orderItems.add(item);
    }
}

Let's define an interface that will be the only type that ComputerOrder allows:

public interface AllowableType {

}

ComputerOrder:

public class ComputerOrder extends GenericOrder<AllowableType> {

}  

Product class and family:

public class Product {

}

public class ComputerPart extends Product implements AllowableType {

}

public class Peripheral extends Product implements AllowableType {

}

public class Service extends Product implements AllowableType {

}

public class Cheese extends Product {

}

public class Fruit extends Product {

}

Now test it:

public void test() {
    ComputerOrder co = new ComputerOrder();
    co.add(new ComputerPart()); //ok
    co.add(new Peripheral());   //ok
    co.add(new Service());      //ok

    co.add(new Cheese());  //compilation error
    co.add(new Fruit());  //compilation error
}

If we want a particular type to be addable to ComputerOrder, we just need to make that type implement the AllowableType interface.

dbank
  • 1,173
  • 1
  • 17
  • 29
  • Thank you so much for replying to my question......what will the AllowableType interface have? – Shayaan Mar 12 '15 at 17:11
  • @Shayaan Do you mean what methods will the `AllowableType` interface have? It doesn't have to have any methods. It's just a way to restrict what type is allowed to be used with ComputerOrder. I suppose it's like a [marker interface](http://geekexplains.blogspot.com/2009/10/marker-interface-in-java-what-why-uses.html). – dbank Mar 12 '15 at 17:22
  • @Shayaan Great! I'm glad I could help. If you feel like this is the solution to your question please upvote and/or accept the answer. :-) – dbank Mar 12 '15 at 18:35
  • Yes it was very helpful........I do have more questions if you don't mind regarding the same assignment......I've spent quite some time on it......and the wording of the questions are very confusing.......I have to create another class OrderProcessor that will accept(), process() and dispatch() various types of orders into and from an internal collection of OrderPrcoessor – Shayaan Mar 12 '15 at 19:27
  • @Shayaan Depending on what your question is, it may be better to create a new question and provide a link to this post if it is somehow related. – dbank Mar 12 '15 at 19:30
  • I created a class and an accept (GenericOrder) method in my TestClass I created OrderProcessor op and tried to accept a GenericOrders and a ComputerOrders using the same object "op" and it gives me the first one only eventhough I did something like this: op.accept(go.getOrder()); and then I had op.accept(co.getOrder()); and it gives me the GenericOrder (go) both times, not the ComputerOrder(co), why? – Shayaan Mar 12 '15 at 19:40
  • @Shayaan It's difficult to understand what you are asking in a small unformatted comment. Please [ask a new question](http://stackoverflow.com/questions/ask) with relevant code samples so that you can take advantage of the code formatting that the stackoverflow question editor provides. If you feel [this question](http://stackoverflow.com/questions/29011187/how-to-restrict-a-class-from-taking-certain-types-in-java) is relevant to your new question, you can post a link in that new question to this question. Then either me or someone else can try to answer your new question. – dbank Mar 12 '15 at 19:55