2

What I want to do is the following:

public class DBManager<T extends Type , Q extends Query>{
    T create(T t);
    Collection<T> read(Q query);
    T update(T t);
}

However, I only want instantiations of this class where T and Q are related. For instance, if T is AppleType, then I want Q to be AppleQuery and not PearQuery.

Is there a way to do this, or produce a similar behavior?

I tried Q extends T & Query, but that isn't allowed.

MrZarq
  • 258
  • 3
  • 12
  • Even if you could do that, I don't think you'd get very far on the implementation side of things. – Tom Hawtin - tackline Mar 11 '13 at 19:15
  • Why not? It's absolutely possible that you're correct, but I haven't worked with generics in Java before, and I'm not immediately seeing the reason. – MrZarq Mar 11 '13 at 19:16
  • How much control do you have over Type and Query? If they are from your library you could wrap valid pairs in a "endorsed type" object. – Andrew White Mar 11 '13 at 19:16
  • Are Type and Query your own classes? If so, can you share the details of each? – John Ericksen Mar 11 '13 at 19:16
  • What is the relationship (if any) between the `Type` and `Query` classes? – rgettman Mar 11 '13 at 19:19
  • @MrZarq To do anything useful in `DBManager` that requires a relationship with the types isn't going to be possible without specialising the code for the particular types. IYSWIM. – Tom Hawtin - tackline Mar 11 '13 at 19:22
  • Yes, they're both my own classes. I don't think their content is all that important. They're only there so I could work with generic types but still have a say in what instantiations they create. I don't want them to be able to create a DBManager for instance. – MrZarq Mar 11 '13 at 19:23
  • @AndrewWhite, could you elaborate? – MrZarq Mar 11 '13 at 19:28
  • @Dolda2000's answer is probably your best bet. – Andrew White Mar 11 '13 at 19:40

4 Answers4

4

You cannot do that unless the types themselves have some kind of relation in the type system.

Since I don't know exactly what you want to do, it's hard to recommend something with precision, but it sounds like you might want to do something like this:

public abstract class Type {
    ...
}

public class AppleType extends Type {
    ...
}

public abstract class Query<T extends Type> {
    public abstract T doQuery(); /* Or so? */
}

public class AppleQuery extends Query<AppleType> {
    public AppleType doQuery() {...}
}

With such a formal relation from Query to Type, you could then define your DBManager as such:

public class DBManager<T extends Type, Q extends Query<T>> {
    T read(Q id);
}
Dolda2000
  • 25,216
  • 4
  • 51
  • 92
1

Since Q is not used in return types, you don't need it. Simply

interface DbManager<T extends Type>

    T read(Query<? extends T> query)

where

interface Type

interface Query<T extends Type>
ZhongYu
  • 19,446
  • 5
  • 33
  • 61
0

You could make everything generic:

public class Type<Q extends Query<? extends Type<Q>>
public class Query<T extends Type<? extends Query<T>>

public class DBManager<T extends Type<Q> , Q extends Query<T>>
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
0

There isn't multiple inheritance in Java. Why not just to do this?

public class Generic{
 // Generic atributes and methods.
}

public class ClassA extends Generic{
 // ClassA atributes and methods overwriting, if need it, the extended methods from Generic class.
}

public class ClassB extends Generic{
 // ClassB atributes and methods overwriting, if need it, the extended methods from Generic class.
}

... // You can instantiate so many classes as you need. You can use the factory pattern.
Daniel García Baena
  • 1,191
  • 4
  • 19
  • 33