How should I override the equals method of an API class? - java

I am using the Vector2 class of the libGDX API, and if I want to check the equality of two vectors I have to do the following:
Vector2 vectA = new Vector2(0, 1);
Vector2 vectB = new Vector2(1, 1);
if (vectA.x == vectB.x && vectA.y == vectB.y) {
return true;
}
This is very uncomfortable and I am thinking about creating an equals() method for this scenario. Which should be the better to do:
Creating a wrapper for the Vector2 class with an equals(Vector2) method
Creating an EqualUtil class with an equals(Vector2, Vector2) method
The first would look better (in my opinion), but it may not be a 'nice' solution while the other is much cleaner but also a bit simplistic. Different ideas also welcome.

Yes you should.
In my opinion, it is better to create a Wrapper (and you should also override hashCode() to match the new behavior).
Not only doing so will result in more readable code, it will also allow you to use collections such as a HashSet or other methods that rely on the equals() behavior.
It also makes sense logically, because you are trying to create a method that gives data on the specific object - what better way to show it then to do it as an instance method?

I'll go with, overriding both equals() as well as hashCode() method inside a Vector2 class.
From Joshua Bloch Item -9
Always override hashCode when you override equals
Edited:
Scroll down to page 45
Page 45: Item-9

public interface CheckObject(){
public abstract boolean and(CheckObject checkobject);
}
public abstract class AbstractObject()
implements CheckObject
{
public AbstractObject()
{
}
public abstract boolean and(CheckObject checkobject);
protected void beforeObjectChecked(Object obj)
throws IllegalArgumentException
{
}
public class EqualUtil extends AbstractObject {
private int point1;
private int point2;
}
protected EqualUtil(int point1,int point2){
this.point1=point1;
this.point1=point2;
}
public boolean and(CheckObject checkobject){
beforeObjectChecked(checkobject);
return(this.getPoint1()==checkobject.getpoint1() && this.getPoint2()==checkobject.getpoint2()));
}
public int getPoint1() {
return point1;
}
public void setPoint1(int point1) {
this.point1 = point1;
}
public int getPoint2() {
return point2;
}
public void setPoint2(int point2) {
this.point2 = point2;
}
Now you can use it from Main Class

Wrapper's are a good and understandable way to add in new behaviour when the original designers did not include it for some reason. Given that the original API class just uses the java.lang.object equals method, creating a wrapper seems a sensible option to me.

Related

How can I use a third party Class Object as Hashmap Key?

OK I understand the working of equals and hashcode and How they are used in hashmap.
But This question crossed my mind What if I am having a third party object which does'nt have overridden hashcode and equals and I am not even allowed to modify it.
Consider following Class:
//Unmodifiable class
public final class WannaBeKey{
private String id;
private String keyName;
//Can be many more fields
public String getId()
{
return id;
}
public String getKeyName()
{
return id;
}
//no hashcode or equals :(
}
Now I want to make this class as my Hashmap key obviously it won't work without equals and hashcode. I want to know is there any way to handle such cases? I am unable to think of any or I am way over my head..
Thanks.
I've encountered this previously, and worked around it by creating a wrapper for the WannaBeKey as such:
public class WannaBeKeyWrapper {
private final WannaBeKey key;
public WannaBeKeyWrapper(WannaBeKey key) {
this.key = key;
}
public boolean equals(Object obj) {
// Insert equality based on WannaBeKey
}
public int hashCode() {
// Insert custom hashcode in accordance with http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()
}
}
Obviously this changes your Set from Set<WannaBeKey> to Set<WannaBeKeyWrapper>, but you should be able to account for that.
You can create a wrapper for that object which will have the overridden methods. Then you can use the wrapper class as the key of your hash map.
You can wrap the actual object in another instance with the required semantics:
class KeyWrapper {
WannaBeKey key; // constructor omitted
#Override
public int hashCode() {
return key.getId().hashCode();
}
#Override
public boolean equals(Object o) {
// equals method implementation
}
}
Alternatively, you could simply extend the class (if the class was not final as you stated in your edit).
This question has already been answered thoroughly but I thought it was worth mentioning that the solutions above are part of a specific design pattern known as a Decorator.
The Adapter or Wrapper pattern uses essentially the same solution but is meant more for transforming code to a different interface whereas Decorator is used for extension.

Edit return value in a class without modifying the class itself?

Okay, so let's say I have a class called Pancake.
Pancake.java would look something like this:
public class Pancake {
public boolean shouldEat() {
return false;
}
}
Now, I don't want to edit Pancake.java at all. All I want to do is to change what shouldEat() returns to from a different class, such as "NotPancake.java".
I know if I had something like
public boolean eat = false;
I could easily just change that by doing something like Pancake.eat = true, but is there any way of changing what shouldEat() returns to without editing the class in a similar way?
Thanks.
The way to do that is based on Object Oriented programming
public class NotPancake extends Pancake {
#Override
public boolean shouldEat() {
return true;
}
}
The magic that happens here is called "inheritance," and is one of four elements assigned to OO.
What happens here is that you define new structure that is delivered from Pancake.
This means that NotPancake inherits form Pancake. So a NotPancake is a Pancake.
Pancake p = new Pancake();
Pancake q = new NoPancake();
print(p.shouldEat()); //Will be false
print(q.shouldEat()); //Will be true
This relation gives us the possibility to change the behavior, we are allowed to redefine all public, protected and defaults methods from super class.
The when in our child class we define a method with the same signature we say that this method override the previous one. In Java you should add the annotation #Override to inform compiler additionally about it.
This is one way to do it. The inheritance is simple but create a lot of issue in coding complex programs an alternative solution is called composition. and you should always prefer composition over inheritance.
The composition is based on the abstractness. To use it a interface is required. The interface is an description of an contract that classes that implements it follow.
public interface Dish {
boolean isEatable();
}
The name of interface should represent some abstract general concept.
public class Pancake implements Dish {
#Override
public boolean shouldEat() {
return false;
}
}
public class Carrot implements Dish {
#Override
public boolean shouldEat() {
return true;
}
}
Usage is more less the same.
Dish dish1 = new Pancake();
Dish dish2 = new NoPancake();
print(dish1.shouldEat()); //Will be false
print(dish2.shouldEat()); //Will be true
On this small example is hard to show the benefits for composition. But is demonstrate the coding to interface approach.
Pancake p = new Pancake() {
public boolean shouldEat() {
return true;
}
};

Java Inheritance/OOP - call child type specific method with only a handle on parent

I'm writing a game engine in Java for Android games and my engine handles collision detection for different shapes. Each shape is its own class (Square, Circle, etc.), and derives from a common abstract parent Collidable. I have a physics manager class which basically checks if any of the existing objects in the game are colliding with another, and then does the appropriate action when collision is detected. The check for collision is implemented inside each physics shape child class as in the code below.
public abstract class Collidable
{
}
public class Square extends Collidable
{
public boolean Collides(Square) {...}
public boolean Collides(Circle) {...}
public boolean Collides(Triangle) {...}
}
public class Circle extends Collidable
{
public boolean Collides(Square) {...}
public boolean Collides(Circle) {...}
public boolean Collides(Triangle) {...}
}
public class Triangle extends Collidable
{
public boolean Collides(Square) {...}
public boolean Collides(Circle) {...}
public boolean Collides(Triangle) {...}
}
public class PhysicsMgr
{
public boolean Collides(Collidable p1, Collidable p2)
{
return p1.Collides(p2);
// This obviously won't work because there is no Collides
// method in Collidable. I want it to somehow call the child's
// method and pass in p2 as its child type rather than as
// a parent. Or somehow do this:
return (p1.child()).Collides(p2.child());
// I know that obviously nothing like this exists.
}
}
I am aware of "instanceof" and really don't want to check the child type of p1 and p2 versus every single collision shape I have. There must be a better way. I'm looking for either a workaround for my current problem, or preferably a redesign of my current collision detection system to avoid this problem altogether.
Thanks!
you should read about the visitor pattern
For starters, I wouldn't make Collidable an abstract class. Even though there are probably good arguments for it; it just seems to me like this is an "is a" situation where a lot of objects could be collidable.
So, that being said, here is what I would recommend:
// Assuming you're working in 2 dimensions
public class Coordinates {
public Coordinates(float x, float y) {
// etc etc etc
}
}
public interface ICollidable {
// Using unusually long name to illustrate point,
// but feel free to rename.
public int getMaxDistanceFromCenterOfMass(Coordinates unitVector);
public Coordinates getCenterOfMass();
}
And then, for Square, Triangle, and Circle, I would implement the interface.
public class Square implements ICollidable {
#Override
public int getMaxDistanceFromCenterOfMass(Coordinates unitVector) {
// Must declare and initialize
return this.lengthOfSide;
}
#Override
public Coordinates getCenterOfMass() {
return this.centerOfMass;
}
}
public class Circle implements ICollidable {
#Override
public int getMaxDistanceFromCenterOfMass(Coordinates unitVector) {
// Must declare and initialize
return this.radius;
}
#Override
public Coordinates getCenterOfMass() {
return this.centerOfMass;
}
}
public class Triangle implements ICollidable {
#Override
public int getMaxDistanceFromCenterOfMass(Coordinates unitVector) {
// Must declare and initialize
return this.lengthOfSide;
}
#Override
public Coordinates getCenterOfMass() {
return this.centerOfMass;
}
}
Then, in your PhysicsMgr...
public class PhysicsMgr {
public boolean Collides(ICollidable p1, ICollidable p2) {
Coordinates cm1 = p1.getCenterOfMass();
Coordinates cm2 = p2.getCenterOfMass();
int length = Math.sqrt(Math.pow(cm1.x - cm2.x, 2) + Math.pow(cm1.y - cm2.y, 2))
// It is a misnomer to use coordinates as a unit vector, but if I defined a
// UnitVector class, it would be exactly the same with the exception of
// the class name for this situation.
Coordinates unitVector = new Coordinates((cm1.x - cm2.x)/length, (cm1.y - cm2.y)/length);
int collisionDistance1 = p1.getMaxDistanceFromCenterOfMass(unitVector);
int collisionDistance2 = p2.getMaxDistanceFromCenterOfMass(unitVector);
return (length - collisionDistance1 - collisionDistance2) <= 0;
}
}
The one major caveat here is that using the maxDistance from center of mass literally will only give you an approximation for the Square and Triangle. To be exact, you will have to declare some orientation, theta, and calculate the distance from the center of mass of the object to the edge along the unit vector (which will be tricky, but exact).
Another thing that is nice about this is that it allows you to easily add other collidable objects as your engine becomes more sophisticated. This also makes it so that none of the objects have to know about each other.
I was a physics TA for 3 years and it was actually how I got my first exposure to programming. If you're interested in the extra work, here is a reference to the book we used: http://matterandinteractions.org/ It is great for programmers because it teaches physics by using coding examples in python (specifically, vpython http://vpython.org/ ). So this would be a very good reference to have for physics programming.
public boolean Collides(Square) {...}
public boolean Collides(Circle) {...}
public boolean Collides(Triangle) {...}
You are going to need separate implementations for the various combinations of shapes (because there is no common algorithm, I think). So at one point, there will be the need to call instanceof. I am afraid having an abstract method or interface method public boolean Collides(Collidable) is not going to help here, and what you have now cannot be significantly improved upon. This is a textbook case of the limitations of OOP, because these collision detection methods cannot be neatly attached to any of the shape classes, they live somewhere in between, in something like your physics manager.

Why should I use interface in this situation in Java?

I'm trying to understand the basics of Java OOP concepts so I've a question about the interfaces as it confuses me a little. Below I was playing around with two classes. One which implements the SizeComparable interface and the other which doesn't but works too.
public interface SizeComparable {
int isHigher(SizeComparable obj);
}
public class Interesting implements SizeComparable {
private int height;
public Interesting(int height) {
this.height = height;
}
public int getHeight() {
return height;
}
public int isHigher(SizeComparable obj) {
Interesting otherInteresting = (Interesting)obj;
if(this.getHeight() > otherInteresting.getHeight()) {
return 1;
} else {
return 0;
}
}
public static void main(String[] args) {
Interesting i1 = new Interesting(182);
Interesting i2 = new Interesting(69);
int result = i1.isHigher(i2);
System.out.println("Is i1 higher than i2? Result: " + result);
}
}
How is the code above better than the code bellow? Personally I don't understand because the code bellow those it's job great too. Am I missing some concepts behind the interface idea?
public class Interesting {
private int height;
public Interesting(int height) {
this.height = height;
}
public int getHeight() {
return height;
}
public int isHigher(Interesting obj) {
if(this.getHeight() > obj.getHeight()) {
return 1;
} else {
return 0;
}
}
public static void main(String[] args) {
Interesting i1 = new Interesting(182);
Interesting i2 = new Interesting(69);
int result = i1.isHigher(i2);
System.out.println("Is i1 higher than i2? Result: " + result);
}
}
I was trying to understand it (here), but I'm still unsure about this. Sorry if the question is a little silly, i just want to understand it completely.
If you have Interesting, Boring, Indifferent and Crazy classes which all represent some objects comparable by height, then all of them can implement the SizeComparable interface and thus be comparable to each other.
Without the interface you would need n methods in each class to compare it with itself and all the others.
At the beginning it probably won't make much sense, however when you will start injecting dependencies, start testing or will write more than one implementation of interface, than it will really give you boost.
Also it allows for multiple inheritance. Sometimes you want thing like comparable - very generic interface that may be used by a lot of classes in your system. That will come with bigger systems and larger class hierarchies.
Right now just trust rest of java world, and use them interfaces :)
and good luck
An interface is a contract that any class wishing to implement the interface agrees to follow. The reason for using an interface is to allow some other class or method to access the interface functions without requiring that the your class inherit from a common class... I'll modify your example to make it clearer:
public interface HeightCapable {
int getHeight();
}
public class Interesting implements HeightCapable {
private int height;
public Interesting(int height) {
this.height = height;
}
public int getHeight() {
return height;
}
}
public class SomeOtherClass {
public boolean isHigher(HeightCapable obj1, HeightCapable obj2) {
// ... do something interesting
if (obj1.getHeight() > obj2.getHeight()) {
return true;
}
}
In the example above, any class implementing the HeightCapable interface can call SomeOtherClass.isHigher(). Without the interface, any class wishing to call SomeOtherClass.isHigher() would need to inherit from a common class. Java lacks multiple inheritance.
If you want to have your SizeComparable objects comparable not to all other SizeComparable objects, but only to those of some type, you could use generic types.
interface SizeComparable<X> {
/**
* returns true if this object is higher than that object.
*/
boolean isHigher(X that);
}
Then you could create your implementations like this:
public class Interesting implements SizeComparable<Interesting> {
...
public boolean isHigher(Interesting obj) {
return this.getHeight() > obj.getHeight();
}
}
Or, you could even have another interface
public interface HeigthHaving extends SizeComparable<HeightHaving> {
/**
* returns the height of this object.
*/
public int getHeigth();
/**
* compares this object's height with another objects height.
* #return true if this.getHeight() > that.getHeight, else false.
*/
public boolean isHigher(HeightHaving that);
}
Now every implementation of HeightHaving must implement the isHigher(HeightHaving) method (this would be the case even if we did not repeat it here), and should do that according to the specification here. Other SizeComparable implementations are not affected of this, though.
The good thing here is that now for example sort algorithms can sort lists/arrays of any type X implementing SizeComparable, so you don't have to write it again for every new type of object you may want to sort by height.
(In fact, there is already a similar interface Comparable<X> in the standard API. Maybe you want to use this instead of your SizeComparable.)
By the way, for a isXXX method usually a boolean return type is quite more sensible than an integer.

Java - Method name collision in interface implementation

If I have two interfaces , both quite different in their purposes , but with same method signature , how do I make a class implement both without being forced to write a single method that serves for the both the interfaces and writing some convoluted logic in the method implementation that checks for which type of object the call is being made and invoke proper code ?
In C# , this is overcome by what is called as explicit interface implementation. Is there any equivalent way in Java ?
No, there is no way to implement the same method in two different ways in one class in Java.
That can lead to many confusing situations, which is why Java has disallowed it.
interface ISomething {
void doSomething();
}
interface ISomething2 {
void doSomething();
}
class Impl implements ISomething, ISomething2 {
void doSomething() {} // There can only be one implementation of this method.
}
What you can do is compose a class out of two classes that each implement a different interface. Then that one class will have the behavior of both interfaces.
class CompositeClass {
ISomething class1;
ISomething2 class2;
void doSomething1(){class1.doSomething();}
void doSomething2(){class2.doSomething();}
}
There's no real way to solve this in Java. You could use inner classes as a workaround:
interface Alfa { void m(); }
interface Beta { void m(); }
class AlfaBeta implements Alfa {
private int value;
public void m() { ++value; } // Alfa.m()
public Beta asBeta() {
return new Beta(){
public void m() { --value; } // Beta.m()
};
}
}
Although it doesn't allow for casts from AlfaBeta to Beta, downcasts are generally evil, and if it can be expected that an Alfa instance often has a Beta aspect, too, and for some reason (usually optimization is the only valid reason) you want to be able to convert it to Beta, you could make a sub-interface of Alfa with Beta asBeta() in it.
If you are encountering this problem, it is most likely because you are using inheritance where you should be using delegation. If you need to provide two different, albeit similar, interfaces for the same underlying model of data, then you should use a view to cheaply provide access to the data using some other interface.
To give a concrete example for the latter case, suppose you want to implement both Collection and MyCollection (which does not inherit from Collection and has an incompatible interface). You could provide a Collection getCollectionView() and MyCollection getMyCollectionView() functions which provide a light-weight implementation of Collection and MyCollection, using the same underlying data.
For the former case... suppose you really want an array of integers and an array of strings. Instead of inheriting from both List<Integer> and List<String>, you should have one member of type List<Integer> and another member of type List<String>, and refer to those members, rather than try to inherit from both. Even if you only needed a list of integers, it is better to use composition/delegation over inheritance in this case.
The "classical" Java problem also affects my Android development...
The reason seems to be simple:
More frameworks/libraries you have to use, more easily things can be out of control...
In my case, I have a BootStrapperApp class inherited from android.app.Application,
whereas the same class should also implement a Platform interface of a MVVM framework in order to get integrated.
Method collision occurred on a getString() method, which is announced by both interfaces and should have differenet implementation in different contexts.
The workaround (ugly..IMO) is using an inner class to implement all Platform methods, just because of one minor method signature conflict...in some case, such borrowed method is even not used at all (but affected major design semantics).
I tend to agree C#-style explicit context/namespace indication is helpful.
The only solution that came in my mind is using referece objects to the one you want to implent muliple interfaceces.
eg: supposing you have 2 interfaces to implement
public interface Framework1Interface {
void method(Object o);
}
and
public interface Framework2Interface {
void method(Object o);
}
you can enclose them in to two Facador objects:
public class Facador1 implements Framework1Interface {
private final ObjectToUse reference;
public static Framework1Interface Create(ObjectToUse ref) {
return new Facador1(ref);
}
private Facador1(ObjectToUse refObject) {
this.reference = refObject;
}
#Override
public boolean equals(Object obj) {
if (obj instanceof Framework1Interface) {
return this == obj;
} else if (obj instanceof ObjectToUse) {
return reference == obj;
}
return super.equals(obj);
}
#Override
public void method(Object o) {
reference.methodForFrameWork1(o);
}
}
and
public class Facador2 implements Framework2Interface {
private final ObjectToUse reference;
public static Framework2Interface Create(ObjectToUse ref) {
return new Facador2(ref);
}
private Facador2(ObjectToUse refObject) {
this.reference = refObject;
}
#Override
public boolean equals(Object obj) {
if (obj instanceof Framework2Interface) {
return this == obj;
} else if (obj instanceof ObjectToUse) {
return reference == obj;
}
return super.equals(obj);
}
#Override
public void method(Object o) {
reference.methodForFrameWork2(o);
}
}
In the end the class you wanted should something like
public class ObjectToUse {
private Framework1Interface facFramework1Interface;
private Framework2Interface facFramework2Interface;
public ObjectToUse() {
}
public Framework1Interface getAsFramework1Interface() {
if (facFramework1Interface == null) {
facFramework1Interface = Facador1.Create(this);
}
return facFramework1Interface;
}
public Framework2Interface getAsFramework2Interface() {
if (facFramework2Interface == null) {
facFramework2Interface = Facador2.Create(this);
}
return facFramework2Interface;
}
public void methodForFrameWork1(Object o) {
}
public void methodForFrameWork2(Object o) {
}
}
you can now use the getAs* methods to "expose" your class
You can use an Adapter pattern in order to make these work. Create two adapter for each interface and use that. It should solve the problem.
All well and good when you have total control over all of the code in question and can implement this upfront.
Now imagine you have an existing public class used in many places with a method
public class MyClass{
private String name;
MyClass(String name){
this.name = name;
}
public String getName(){
return name;
}
}
Now you need to pass it into the off the shelf WizzBangProcessor which requires classes to implement the WBPInterface... which also has a getName() method, but instead of your concrete implementation, this interface expects the method to return the name of a type of Wizz Bang Processing.
In C# it would be a trvial
public class MyClass : WBPInterface{
private String name;
String WBPInterface.getName(){
return "MyWizzBangProcessor";
}
MyClass(String name){
this.name = name;
}
public String getName(){
return name;
}
}
In Java Tough you are going to have to identify every point in the existing deployed code base where you need to convert from one interface to the other. Sure the WizzBangProcessor company should have used getWizzBangProcessName(), but they are developers too. In their context getName was fine. Actually, outside of Java, most other OO based languages support this. Java is rare in forcing all interfaces to be implemented with the same method NAME.
Most other languages have a compiler that is more than happy to take an instruction to say "this method in this class which matches the signature of this method in this implemented interface is it's implementation". After all the whole point of defining interfaces is to allow the definition to be abstracted from the implementation. (Don't even get me started on having default methods in Interfaces in Java, let alone default overriding.... because sure, every component designed for a road car should be able to get slammed into a flying car and just work - hey they are both cars... I'm sure the the default functionality of say your sat nav will not be affected with default pitch and roll inputs, because cars only yaw!

Categories

Resources