• Post Reply Bookmark Topic Watch Topic
  • New Topic

Interfaces and how would I do this  RSS feed

 
Harish Shivaraj
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I know what i want, but not sure how to.
How do you enforce any class which implements an interface should also implement comparable too?

Say for instance you may have an interface



I want all of the classes which implements the interface Task to implement comparable too. Of course I can just say implements Task, Comparable. But is there something which we could do from interface level, i mean interface Task level?

 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
An interface can extend another interface. Not sure if that makes sense to me semantically for Task and Comparable though.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Harish Shivaraj wrote:I know what i want...

But we don't. So why don't you explain it to us?

Like Junliu, what you suggest sounds "odd", and I doubt whether the solution (if there is one) will actually be what you think it is.

Sounds like a "design crisis" to me; and that's what we're here for. But in order to help, we need to know WHAT you want to do; not HOW you want to do it.

HIH

Winston
 
Harish Shivaraj
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have an interface called events which some basic method. And the class which implement that event say printevent, printstatus etc should implement comparable interface. whats the elegant way of doing this?

Clearly i cant enforce this from the interface level. Therefore I was wondering how would go on about doing this?
 
Campbell Ritchie
Marshal
Posts: 56599
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you want them always to be Comparable (capital C note) why not make your Event<T> interface extend Comparable<T>?
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Harish Shivaraj wrote:I have an interface called events which some basic method. And the class which implement that event say printevent, printstatus etc should implement comparable interface. whats the elegant way of doing this?
Clearly i cant enforce this from the interface level. Therefore I was wondering how would go on about doing this?

Again, you've told us HOW you want to do this (or what you've been given); and that's no basis for a fundamental design.

The simplest (as Junilu hinted at) is to have your interface extend Comparable<YourInterface>. That way, no class can implement it without implementing Comparable as well.

It might be the solution; another one might be to type it generically. But until we know WHAT you want you do, rather than HOW you want to do it; it's very difficult to advise.

So (once again): WHAT are you trying to do? Is there some sort of secret to it?

Winston
 
Harish Shivaraj
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Its quite simple, im trying to simulate printQ job. A queue has many events(mainly print job event) which needs to be interested into the queue. The Queue is s priority and event which gets inserted needs to have implemention of comparable interface to find it position in the Queue.

So therefore, I came up with the interface class Event which some basic methods and class which implements the interface will have to implement the comparable without it the any event cannot be interested into the Queue.

If that makes sense?
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Harish Shivaraj wrote:If that makes sense?

YES (finally ).

Solution (as Julinu suggested a while back, and unless your Event itself is typed):
  public interface Event extends Comparable<? extends Event>.

HIH

Winston
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Another approach which makes more sense to me is to specify a getPriority() method in the Event interface, then create a Comparator<Event> that uses getPriority() - this is what you'll use for your queue prioritization logic. Forcing all Events to implement Comparable is too onerous for this one purpose, IMO.
 
Harish Shivaraj
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks guys for all our suggestions. I'm having a problem compiling it. This is what i have





I get two errors which the above modification. At the interface level i get

The type Event cannot extends on implement Comparable<? extends Event>. A supertype may not specify any wildcard.

This basically say that i cant have wild card at the interface level?
 
Harish Shivaraj
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I got one other problem guys. I'm a bit confused how these subtyping works now. This is what ive got now.











And the compiler donst list me creating Queue of length 20 of type Jobs. So that I cant put in of type PrintJob. why?
 
Harish Shivaraj
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Anyone find anything stupid ive done here?
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Harish Shivaraj wrote:Anyone find anything stupid ive done here?

We will never say "stupid" around here but since you asked, your code exemplifies what I said about extending Comparable: it doesn't make much sense in this case. If a PriorityQueue will deal with Comparable then it must be able to take ALL objects that implement it, not just your particular implementations. Just look at the JavaDocs for Comparable and see all the kinds of objects that it covers. Many of those make no sense in a PriorityQueue but your code will take them.

A better approach, IMO, is to have a specific Comparator just for Events or Tasks and use that in your prioritization logic instead.
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Also, you should consider making Event an abstract base class instead of an interface. I don't see why you would have Event implementations that are not in the same object hierarchy, which is one motivation for using an interface. Interfaces are more general and crosscutting, whereas an abstract base class implies a stronger commonality. I think an Event and its ilk would be better under the latter.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Harish Shivaraj wrote:The type Event cannot extends on implement Comparable<? extends Event>. A supertype may not specify any wildcard.

You're quite right. My apologies.

There are two possible ways around this:
1. Event extends Comparable<Event>.
2. Event<T extends Event<T>> extends Comparable<T>.

I have a slight preference for the latter, because I think it's closer to what you want - ie, you want Events to be comparable to others of the same type - and it will enforce it at compile time. But you then have to type your Events, ie:

  public class PrintJob implements Event<PrintJob> { ...

However, I think Junilu's advice may be better. Generics is NOT a 100% solution, and there are some things that it has problems with (Comparable being just one), so you have to think carefully about what you want to enforce at compile time - which is the main reason for using it.

Sorry if I led you down a garden path.

Winston
 
Harish Shivaraj
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Guys I really appreciate your help so far. Im sort of stuck, I understand your approach but however this is what ive got and i need this working. But im not able to get it working.

So basically I have class called PriorityQueue which I implemented where the signature looks like this.



As you can see its parametrized and any type should implement Comparable (I know this not the preferred way). And I have another thing which goes inside the Queue. A queue of jobs, job could a print job and print status etc. For instance take a queue of print jobs in a prioirty order. Priority Queue class is implementing using heap method.

This is what I have from Job preceptive. I have an abstract class called Jobs which implements nothing. What I effectively want to do in main is this



The Jobs class looks like follow





All this is good. But when I come to do the following compiler dosent like this



Warning is this
The type Jobs is not a valid substitute for the bounded parameter <T extends Comparable<T>> of the type PriorityQueue<T>

I need queue of Jobs, so that I can insert any subtype of Jobs class. Like PrintJob or Print status etc.

Ive been banging my head on this. Can you please shred some light.
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why do you insist on going down this route? It's convoluted and the relationships you're trying to define by extending Comparable are tenuous and tortuous. The only advice I can give if you want to keep banging your head on this is to get a helmet. Seriously. Maybe I'm missing something but I just don't see how you're going to extricate yourself out of this roundabout. Even if does compile, I can't even begin to wrap my head around your declaration for Jobs: Jobs<T extends Jobs<T>>
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Harish Shivaraj wrote:Guys I really appreciate your help so far. Im sort of stuck, I understand your approach but however this is what ive got and i need this working. But im not able to get it working.

And, like Junilu, I think the reason is that you're overthinking this. There's nothing wrong with your PriorityQueue declaration, because all you're saying is that it must contain Comparable elements; however, just as a tip:

  public class PriorityQueue<T extends Comparable<? super T>> implements Queue<T> { ...

is slightly more flexible (in fact, it might solve your problem; but I doubt it).

Where I think you're going wrong is that you're ALSO making Jobs a class that takes a Comparable type, when in fact all you need to do is make it Comparable. You can't implement the same interface for both a class AND its type.

I'm also a bit worried about the name. Jobs suggests to me that each object contains more than one "Job", when in fact, I suspect that's what your PriorityQueue is for (but I could be wrong).

I need queue of Jobs, so that I can insert any subtype of Jobs class. Like PrintJob or Print status etc.
Ive been banging my head on this. Can you please shred some light.

Well, shredding light is beyond even my capabilities , but the reason you're having the problem is that Jobs doesn't implement
  Comparable<Jobs>
it implements
  Comparable<"something extended from Jobs">
and the compiler is quite finicky about these distinctions.

And if you think about it, it's absolutely right to complain. If you want a collection that can contain a mixture of Jobs subclasses, then they MUST be mutually comparable; otherwise you'll run into problems whenever you try to compare a PrintJob with a PrintStatus.

Therefore, Jobs should implement Comparable<Jobs> - and it probably doesn't need to be typed - and ALL its subclasses need to be comparable to any other subclass of Jobs. You have no choice.

However, even then I suspect that Junilu is quite right: this structure feels way too involved.
I think you'd be far better off backing up and describing in English what it is you want, rather than trying to force generics to do something you haven't really properly thought out yet.

HIH

Winston
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And I apologize if I seemed a bit curt in my previous response. The holiday season tends to stress me out a little and I think I may be running a little low on the spirit... listen to Winston, he's got a much more level head than I do right now
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Junilu Lacar wrote:The holiday season tends to stress me out a little and I think I may be running a little low on the spirit...

Bah, humbug.

Winston
 
Tushar Goel
Ranch Hand
Posts: 934
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Junilu, do you mean something like this:

 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, I meant something more along the lines of

This is a simpler, more straightforward design that simply says "A PriorityQueue is a Queue implementation for Jobs." The PriorityQueue has a specific way of prioritizing Jobs that it manages and that's determined by the prioritizer, which is an implementation of Comparator<Job>. You can have just the one prioritizer as shown or you can make that more flexible by defining a set of enums, say something like enum Prioritization = {BY_DATE, BY_SIZE, BY_URGENCY} and each enum can provide its own specific Comparator implementation. At any rate, the logic for the queue prioritization stays encapsulated in the PriorityQueue, which I would strive to do until otherwise proven that it needs to be externalized further. If that were so, I might add a setPriotizationStrategy method so that an object that provides a Comparator<Job> implementation can be injected into the PriorityQueue instance.
 
Harish Shivaraj
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And I apologize if I seemed a bit curt in my previous response. The holiday season tends to stress me out a little and I think I may be running a little low on the spirit... listen to Winston, he's got a much more level head than I do right now

Dont worry about it; I understand. The reason why I was reluctant to implement you approach was just down to, I wasn’t able to understand your approach. I’m very new to Java, its just been 4 week since I started writing Java. I would really appreciate some sort of code sample(not exactly the solution) to help me understand your approach. That would go long way

The comparator you were talking about, so ive looked up on the internet and what i really see that its been used for Collection.sort function. But no where I could see how to use comparator class in my own class. That is compare function within the PriorityQueue class. What I have in PriorityQueue class is this



Just a sample code where I use the compareTo.

Well, shredding light is beyond even my capabilities , but the reason you're having the problem is that Jobs doesn't implement
Comparable<Jobs>
it implements
Comparable<"something extended from Jobs">
and the compiler is quite finicky about these distinctions.

And if you think about it, it's absolutely right to complain. If you want a collection that can contain a mixture of Jobs subclasses, then they MUST be mutually comparable; otherwise you'll run into problems whenever you try to compare a PrintJob with a PrintStatus.


@Winston quite precisely explained it well. And I did the following





And this worked marvellously.

This is an assignment which im working on toward my degree which is due for submission next Tuesday, I really don’t have much time at all do i? The assignment is basically to simulate printQueue. Where the user keep adding to the Jobs Queue. Basically the simulator has two queues one general queue where all the jobs/event which is prioritized according to time and there's another queue which gets prioritized by the actual priority. The entire system is a event based. It Just goes around the loop picking jobs of the queue. This is what im trying to achieve.

So far what i have is the data structures and the algorithm implemented. Now implementing the actual stuff which goes into the data structure.

Think ive just hit with the problem. Do you when I said that I have two queues. One prioritized by time and other one prioritized by actual job. The Jobs queue which you guys been helping me out works well with one attribute within those jobs that is the time. What if I wanted to prioritise the same object with the different attribute in that object? Does that make sense? Say for instance



The compareTo implementation works just on one attribute oops!



 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Harish Shivaraj wrote:This is an assignment which im working on toward my degree which is due for submission next Tuesday, I really don’t have much time at all do i?

No, but I hate to say: that's your problem, not ours.

Basically the simulator has two queues one general queue where all the jobs/event which is prioritized according to time and there's another queue which gets prioritized by the actual priority. The entire system is a event based. It Just goes around the loop picking jobs of the queue. This is what im trying to achieve.

And this is what I (and, I suspect, Junilu) have been trying to understand all along. And it's also what I've been trying to tell you - you are trying to force generics to fit your solution, rather than describing the problem first, and then fitting a solution (generic or otherwise) to it.

And I think we're back to Junilu's original suggestion: there are TWO Queues involved, and they each need to be able to "prioriitize" (or order) their elements differently; and since they're (presumably) the same elements, you cannot rely on Comparable to produce both orders.

So, maybe you're back to a PriorityQueue that takes a Comparator; not one that relies on its elements being Comparable.

HIH

Winston
 
Tushar Goel
Ranch Hand
Posts: 934
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Junilu and Winston, i got it now and learns better way to use Comparator.

Now we pass this comparator to the Collections.sort(Collections, comparator) to sort it as per the priority.
 
Harish Shivaraj
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks very much to Winston Gutkowski and Junilu Lacar.

Please do excuse my lack of intelligence i understanding java jargon. Junilu Lacar I finally got what you were trying to say. I did implemented your approach. Priority queue take an another parameter of type Comparator which implements compare function. In my case I had to attribute to be prioritized.

I’m satisfied with the solution, and as always it could be better. But I ran out of time.

Do appreciate for your patience. I will get there
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Not a problem, we understand where you're coming from because we've all been there. Thanks for sticking with it and making an effort to understand. Good luck and don't hesitate to come back with more questions.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!