Java generic Comparable where subclasses can't compare to eachother - java

public abstract class MyAbs implements Comparable<MyAbs>
This would work but then I would be able to compare class A and B with each other if they both extend MyAbs. What I want to accomplish however is the exact opposite.
So does anyone know a way to get the generic type to be the own class? Seemed like such a simple thing at first...
Edit:
To explain it a little further with an example. Say you have an abstract class animals, then you extend it with Dogs and ants.
I wouldn't want to compare ants with Dogs but I however would want to compare one dog with another. The dog might have a variable saying what color it is and that is what I want to use in the compareTo method. However when it comes to ants I would rather want to compare ant's size than their color.
Hope that clears it up. Could possibly be a design flaw however.

Most straightforward would be:
public abstract class MyAbs<T> implements Comparable<T>
Perhaps more usefully, you go Enum style:
public abstract class MyAbs<THIS extends MyAbs<THIS>> implements Comparable<THIS>
You may possibly be able to ignore the issue:
public abstract class MyAbs
An external Comparator feels more natural to me (that is to say, don't have a natural order).

Simply implement Comparable<MyAbs> on class B, which if I interpret your question correctly, extends MyAbs. That way, objects of class B can be compared with any objects whose classes extend MyAbs, but not vice versa. However, if what you want is to have the type parameter reflect the concrete class' type, then you should probably pass Comparable a new type parameter.
I.E.:
public abstract class MyAbs<T> implements Comparable<T extends MyAbs>
But this of course has the disadvantage that now your concrete classes need to change their definition to
public class ConcreteClass extends MyAbs<ConcreteClass>
Looks kindof nasty, but it should work. It's probably better to implement Comparable separately on each concrete class.

Related

If I want a subtype to only be deriveable from a single Supertype, should I be using abstract classes intead of an interface to ensure that?

Basically the question in the title but here a little more detail:
I have a set of classes you can create similar objects of (e.g. animals and I have the classes Tiger, Crocodile, Wolf etc. whatever you like). And the types of those objects are specified by the Supertype they are derived from. Now some objects might derive from multiple Supertypes, which obviously need to be implemented as Interfaces. But lets say I have a specific Supertype which I want each animal to only derive EXACTLY ONCE from (e.g. the animal family they belong to). Does this automatically mean that this Supertype should be an abstract class to ensure it can only be extended once in a Subtype?
Edit since Michael pointed out that my question is unclear.
This question is not about a specific piece of code it is more a theoretical question about types, maybe I should ask like this: Can and should an abstract class be used as a tool to ensure a Subtype of this Supertype can only derive it once. Lets say for my example with animals I have the Supertypes "Omnivore", "Herbivore" and "Carnivore" and I know an animal can only be exactly one of those, is this a valid reason to make those abstract classes and not interfaces?
If you have different exclusive categories then different base classes (abstract or not) is a sensible solution.
class HerbivoreBase implements Animal, EatsVegetables { ... }
class CarnivoreBase implements Animal, EatsAnimals { ... }
class OmnivoreBase implements Animal, EatsVegetables, EatsAnimals { ... }
It only makes sense when the classes have (differing) methods.
To look at other languages. Scala has case classes (the name says it all) with pattern matching.
Java also has (will have?) pattern matching based on classes, and instanceof as follows:
Animal animal = ...
if (animal instanceof Herbivore herbi) { ... herbi.eatVegy(...); ... }
else if (animal instanceof Carnivore carni) { ... carni.hunts(...); ... }
Java has also introduced a restricting mechanism to list which classes may be child of a given class, say abstract class Animal.
I would still like to mention, that modeling with inheritance can easily over-architect things, especially if later a change is needed, or the code becomes bloated.
Your question is more about "should I use an interface, or a class (and extend it)?"
Remember that a subclass has a relationship of is-a with its base class. A class has a relationship of has-a with an interface.
An interface define a behaviour that one class has (a car has 4 wheels) (remember also that an interface should define only one behaviour, related to the interface segregation principle, which says that it's better to have more smaller and specific interfaces than one general and bigger, so that classes can implements only needed behaviours), a superclass define a "more general" type (dog is an animal).
See for example:
If you have a MountainBike class, it will implement an interface Bike, or extend a class Bike? It will extend the Bike class, since mountain bike is a "sub-type" of bike.
If you have an Elephant class, it will implement an interface Trunk or extend a class Trunk? It will implement the Trunk interface, since trunk is a part (behaviour) of the elephant, not a "container".
An interface is a way to define signature of a method, but normally it does not define the implementation of a given method. If you want to implement a method in an interface, use the default keyword
interface inter{
public default void myMethod(){/*your code here*/
}
A class can implement multiple interfaces but cannot extend more than one class.
If you are using an abstract class you are can use the following two benefits
The abstract class cannot be initialized
The abstract class can implement abstract methods.
A subclass can still only extend one class, abstract or not.
Your question was: "If I want a superclass to only be derivable from a single subclass, which should I use? Interface or abstract class?"
By derivable, do you mean inheritance? Because if that's the case, then I think you got the question backwards. Subclasses inherit from the superclasses.
The child (subclass) inherits from its parent (superclass)

Class which extends abstract class

I have a problem, i have abstract class which implements interface, and one more class which extends this first abstract class, but i got an error it says that i my second class must inherit methods from interface, and i dont want that, i also can change it to abstract class too, but then i can't call constructor from that class in some third class, how can i fix this?
I searched for answer on internet but couldnt find it, and i dont understand abstract classes rly good so i can't solve it.Please help
(p.s. sorry for my english, it is really bad)
Edit:
I have an assignment where it is requiered that my second class needs to extend abstract class, and i am implementing interface because they also gave me main class in which they are making object from constructor in my second class and then they are using it with type of interface, i dont know if this makes any sense, code is pretty long, but i will give some lines: Here is my main class
(NationalTeam bulgaria = new NationalTeam("Bulgaria", Formation.F352, "Bulgaria");
nationalManager.setManagingTeam(bulgaria);) (bulgaria must be type of interface),
also here is my constructor from second class which extends abstract class:(public NationalTeam(String name,Formation formation,String country){
super(name,formation);
this.country=country;
})
Abstract class:Abstract classes may have abstract methods which means methods are methods without implementations.
when you are extending a abstract class A, methods of class A must be implemented by your subclass lets say B unless you make your child class B an anstract class.
You need to think how want to design the system not how compiler forces you.
If design says second class should be abstract then do it and then ultimately implement your abstract methods in your implementation.
On the other way, if second class is your implementation not abstract, the you have to provide implementation to make object of it
my second class must inherit methods from interface, and i dont want that
Really? Then why did you declare the interface in the first place? Why the abstract class needs to implement the interface?
Interfaces are supposed to be a higher level of abstraction. It is a contract between the client code and the library. It creates a interface between the client code and the library. It's like saying "I have the abilities to do the things the interface requires me to do". And you say you don't want to?
So there are two good ways and one bad way to fix this:
Good
Don't extend the abstract class. Because if you do, it probably does not make sense.
The abstract class don't extend the interface.
Bad (This is really really bad)
Add the methods in the interface and leave the body blank or return a random value. Again, don't do this if you don't have to.

Java - passing ArrayList of interface type

I have an interface Damageable as follows
public interface Damageable {
public void handleCollision(float impulse);
}
a class which implements this interface, BaseObject
public class BaseObject implements Damageable
Now in a third class, I have an ArrayList of the type BaseObject
public class ObjectManager {
public ArrayList<BaseObject> bodies;
What I am trying to do is to pass the ArrayList bodies to a method of another class which accepts ArrayList
public CollisionManager( ArrayList<Damageable> _bodies) {
bodies = _bodies;
}
Java does not let me do new CollisionManager(bodies) where bodies is of type ArrayList and BaseObject implements Damageable
I have tried casting. Says cannot cast from
ArrayList<BaseObject> to ArrayList
Also tried using Class<? extends Damageable> but then I'm unable to call methods declared in the interface Damageable. How can I pass the ArrayList?
You have to be explicit with your generics. Therefore, you have to inform the compiler that your generic type doesn't have to be a Damagable per se, rather it can extend Damagable:
public CollisionManager(ArrayList<? extends Damagable> bodies) {
By the way, notice that I changed your variable to bodies rather than _bodies. Underscores are not part of the standard Java coding conventions.
Edit in response to the OP's comments
Let's say that, instead of an interface, you had a concrete class called Damagable. Telling the compiler <? extends Damagable> says that it doesn't have to be an instance of Damagable. It's okay that the type extend Damagable. Otherwise, the compiler assumes that you have a Damagable exactly.
It doesn't make as much sense when you think of Damagable as an interface, since there is not case where you would have an instance of Damagable. But they work in essentially the same way.
You have to remember that you're working with Java types, not classes. Java's type syntax and structure is less robust than it's class structure. There is no concept of implements when it comes to types.
Last round of edits
Finally, I should note that it's generally better to use an interface for method/constructor parameters and method return types. This allows you and those that use your methods to use whatever implementation you please, and allows you to change your implementation as you please.
So with those revisions, you would have:
public CollisionManager(List<? extends Damagable> bodies) {
Try ArrayList<? extends Damageable > _bodies.
This says that you want an ArrayList consisting of a Class that extends (well implements) Damageable
Others will no doubt point out the technical solutions from the Java syntax perspective.
I'm just going to mention a few design issues that you should perhaps consider:
Your BaseObject implements Damageable. That means all BaseObjects are Damageable. Why not then just make a CollisionManager(ArrayList<BaseObject>)? Unless you are going to use Damageable elsewhere (i.e. there are things which are Damageable but are not BaseObjects) then it seems like an unnecessary abstraction.
Usually for collision detection in a game / simulation you would want to use a spatial data structure for collision detection (e.g. Octree, Quadtree or AABB tree) rather than an ArrayList. Searching for collisions in an ArrayList is an O(n^2) algorithm. This will become a big issue if you have a lot of live objects.
Damageable seems like a bad name, since the functionality relates to collision detection rather than damage - wouldn't Collidable be better?

Achieving multiple inheritance via interface

I am a beginner in interface concept.
when I surfing for the information about "Achieving multiple inheritance via interface", I came across this link.. Multiple inheritance
I have a same doubt as the programstudent had.
hi, Good Explanation very much helpful In the uml diagram for java
there is no connection to Animal from Bird and horse why? Is it
necessary to use the implement the same method in the derived class
and why
void birdNoise();
void horseNoise();
why in the Peagus class
public void horseNoise()
{
System.out.println("Horse Noise!");
}
public void birdNoise()
{
System.out.println("Bird Noise!");
}
why this must be there? Why "Remember, we must write each class's own implementation for each method in the interface. reason? Thank for this good explanation Thank you
In that post, they have used multiple inheritance in c++ and converted to interfaces in java.
1.what I thought about inheritance is having some methods in parent class, and whenever the same methods are needed in other class(es) too, then those class(es) will inherit the parent class and use it.
But in interface concept if each derived class(es) has to define its own implementation then what is the use of inheriting it?
2.If we have to provide own implementation then why not we define that method in the derived class(es) itself. What is the use of inheriting it?
Someone please explain.
Thanks in advance.
When I switched from c++ to java I had this same feeling but now that I been working with java for a while it all kinda makes sense.
1.what I thought about inheritance is having some methods in parent
class, and whenever the same methods are needed in other class(es)
too, then those class(es) will inherit the parent class and use it.
Like the original author did, you can still do multiple inheritance in java you just must use interfaces. Interfaces are like pure virtual classes in c++.
But in interface concept if each derived class(es) has to define its
own implementation then what is the use of inheriting it?
The reason you implement an interface in java is so that you guarantee that class has those methods. That way you can have a specific class implement a generic interface and then treat every specific class that implements that generic interface the same.
Java Design is a bit different then c++ design but after doing several java program's you will become just as good at using multiple interfaces as you are at using multiple inheritance.
Each subclass has to define it's own implementation because each subclass may perform the operation slightly differently. Consider the following example:
public interface animal {
//All implementers must define this method
void speak();
}
This interface states that any Animal MUST have a way to speak. Basically, any type of animal is going to be able to make a noise. We then have 2 subclass, or 2 different types of animals that we create.
public class Dog implements animal {
//Define how a Dog speaks
public void speak() {
System.out.println( "woof" );
}
}
We then define another animal, cat
public class Cat implements animal {
//Define how a Cat speaks
public void speak() {
System.out.println( "meow" );
}
}
In this example, both Cat and Dog are animals, and therefore must be able to speak due to our interface. However, everybody knows that cats and dogs make different sounds. By allowing each subclass to define how it 'speaks', we can give Dog and Cat their own respective sound when the speak() method is called, while ensuring they are both Animals.
In answer to your question more specifically, inheritance forces it's subclasses to have a specific method. In other words, an interface states that "all my subclasses will define each of these methods". What this allows us to do is to write code that deals with the methods in an interface without knowing the specific subclass. We can safely do that because we know that each subclass MUST have defined the method in the interface class. If only the subclasses that use the method defined it, then we would have no way of knowing for sure whether it is safe to call the method on all subclasses.
Just a note: If you do not want a subclass to define the method, you can simply define an empty method like this:
public class MuteAnimal implements animal {
//A MuteAnimal can't speak!
public void speak() { }
}
Inheritance is often useless without polymorphism. It is really not easy to explain it all just in few sentences. My advices would be to look at interfaces for defining behavior (something like can-do relationship), and concrete inheritence for is-a relationships.
In the center of everything as you may learn is something called Single Responsibility Principle. This means that one class has one responsibility, if you are having more of them, you separate the class.
If you take your example, even the Pegasus isn't both horse and bird at the same time 100% percent. It would inherit the horse, but implement specific characteristics of the birds, which would be defined in interfaces, like Flyable for instance. You can say that birds have one way of flying common to them all, so inherit them from Bird. Pegasus is a little different, so that custom logic can be defined after you implement the Flyable interface with method Fly.
Also, the example with horseNoise and birdNoise is little unrealistic, you want one method speak() which will due to internal class alhorithm perform certain action. What if that pegasus could talk? Would you have a method for each word?
Back to Flyable example, say you now have a video-game. Now you can have polimorphism for this: Lets say that in game earthquake happens. You want for each animal that can fly to go and fly. You have a collection of animals currently in game, so you write this:
foreach(Flyable flyableAnimal in animals)
flyableAnimal.Fly();
You just rely on polimorphism ...
These were just some random thoughts, you can find far better examples online, hope this helps ...
If class A inherits from class B, that effectively means two things:
Class A can implicitly use all methods and properties of class B, and need only define that functionality which is in fact unique to class A.
Code which expects an object of type B will accept an object of type A.
Those two features of inheritance are in some sense orthogonal; one can imagine places where either could be useful without the other. Although derived classes can only have one parent class from which they gain implicit access to methods and properties, they may define an arbitrary number of interfaces for which they are substitutable.
Note that while some people insist that interfaces form a "has-a" rather than "is-a" relationship, I think it's better to think of them as saying something "is __able" or "is a __er", the point being that interfaces don't just define abilities, but define substitutability (i.e. "is a") in terms of ability.

Java extend generically specified type

Is there anyway I could do something like this:
Class extends <T extends ClassB>
Can you have a class extend a class as long as that class extends the class that the generically specified class must extend?
What would be the syntax/structure for it?
No, that is not possible. I don't think it would make much sense either—when you use generics and specify a class this way, you only have the information from the class you specified.
For normal use (containers, for example), this makes sense because it lets you rely on a particular class or interface's methods while being able to ensure additional type safety. However, for extending a class, this would not really make much sense—since you can only rely on the methods of ClassB, it would be functionally identical to just doing Class extend ClassB.
For your idea to make much sense, you would need to be able to take the class you've defined and pass in a type to "extend". However, this would have many of the same pitfalls as multiple inheritance—what would you do if a method first defined in Class was also defined in the class you pass in to the generics, but not in ClassB? Not having multiple inheritance in Java was a design decision and having generics that work like that would go against that.
In short, something like this would either be like multiple inheritance or would be identical to normal inheritance.
I think that because of type erasure, you won't be able to do this. For instance, you can't even do this:
class A<T> {
class B extends T {
}
}

Categories