• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Use generics or abstract class?

 
Igor Spence
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi! I'm new to generics and is a bit confused by such situation: Suppose we have some abstract class and we want to write compare method that will work for all it's children. We can pass objects for compare (child classes) as abstract classes and even then if we run child overrided methods on these objects they work right. Or we can use generics for this. I think second way is better, is it true? Is passing child objects as abstract classes correct?
Methods for example:

public static AbstractWorker compare(AbstractWorker aw1, AbstractWorker aw2) {
...
return aw1;
}

public static <T extends AbstractWorker> T compare(T w1, T w2) {
...
return w1;
}
 
Stephan van Hulst
Bartender
Pie
Posts: 5912
66
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What does your compare method do? What does it return?
 
Igor Spence
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:What does your compare method do? What does it return?


It returns the element with bigger value (i.e. monthly salary) in pair.
 
Winston Gutkowski
Bartender
Pie
Posts: 10430
63
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Igor Mylastname wrote:It returns the element with bigger value (i.e. monthly salary) in pair.

No it doesn't; it returns 'w1' (the first value passed to it).

If you want to make a class meaningfully comparable, it has to implement java.lang.Comparable (which is already generic), viz:and personally, I'd make its compareTo() method final.
If you don't want to do that, you should probably add a type to your class:
Winston
 
Igor Spence
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for your reply.

No it doesn't; it returns 'w1' (the first value passed to it).


I just skipped the part about choosing wheteher return w1 or w2.

I'm also not sure why you have static on your class definition - that's only valid for nested classes. From your question, I suspect you meant abstract.


It's supposed to be a static method inside abstract class.

If you want to make a class meaningfully comparable, it has to implement java.lang.Comparable (which is already generic)


Yes, i've already done that. But the question is, is it right to operate child classes objects as abstract classes objects (that as i understand contain information about it's children because if i run overrided method on such abstract class object it runs correctly as it was child class) as in case 1?
i.e. (workers have different methods for getting it's monthly salary):
 
Winston Gutkowski
Bartender
Pie
Posts: 10430
63
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Igor Spence wrote:It's supposed to be a static method inside abstract class.

Yeah, I figured that out; hence my edit.

Yes, i've already done that.

But you haven't (or at least there's no evidence of it). Comparable defines a compareTo() method that compares this object with another. Your compare() method is more like the one for java.util.Comparator.

But the question is, is it right to operate child classes objects as abstract classes objects (that as i understand contain information about it's children because if i run overrided method on such abstract class object it runs correctly as it was child class) as in case 1?
i.e. (workers have different methods for getting it's monthly salary):...

Well, the main thing about compareTo() is that it must be consistent across the hierarchy, which is why I suggested making it final. So if, in order to do that, you need to compare monthly salaries, that's what you have to do.

I suggest you look at the API definition for the method, because it lists all the rules that it has to follow; but briefly they are that it must be reflexive, symmetric, transitive and consistent, and that means for ANY two objects that you can call it for.

Winston

PS: Please DontWriteLongLines (←click). I've broken yours up, but it makes your thread very hard to read.
 
Igor Spence
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But you haven't (or at least there's no evidence of it)


Thanks for explaining on compareTo implementation, but:
I did that, but now i just wanted to know, is manipulating objects of abstract class
instead of using generics and manipulating child objects correct.
My comparable implementation: (I'm talking now not about right
comparable implementation, but about using abstract classes instead of generics)



PS: Please DontWriteLongLines (←click). I've broken yours up, but it makes your thread very hard to read.

Sorry. Edited post.
 
Winston Gutkowski
Bartender
Pie
Posts: 10430
63
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Igor Spence wrote:I did that, but now i just wanted to know, is manipulating objects of abstract class
instead of using generics and manipulating child objects correct.
My comparable implementation: (I'm talking now not about right
comparable implementation, but about using abstract classes instead of generics)

I don't quite understand the question.

If your compareTo() method needs to work for any child of AbstractWorker compared with any other child of AbstractWorker, then the definition looks fine; however, the implementation seems rather odd.
Comparable implies a notion of one object being "greater" or "less" than another, so why involve the name (and in your case only the first character)?

My advice: just compare salaries (assuming that's your "natural" order). If you need any other comparisons, write Comparators for them.

Winston

PS: else if(this.getMediumSalary() == o.getMediumSalary()) is redundant, since you already know they must be equal. Also, you'd be better of storing the results of this.getMediumSalary() and o.getMediumSalary() first; then you don't have to recalculate them.
 
Igor Spence
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you. Just wanted to know if this method is acceptable. Your corrections on comparable implementation are useful too.
 
Winston Gutkowski
Bartender
Pie
Posts: 10430
63
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Igor Spence wrote:Thank you. Just wanted to know if this method is acceptable.

Well, it depends on your notion of "acceptable". It may well work but, like I say, it's an odd way to implement an ordering, and I suspect you'll run into gotchas down the road simply because it's doing exactly what you told it to - ie, ordering by salary + first character of name, which are entirely unrelated.

Winston
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic