Make several classes have the same attributes without inheritance - java

I'm facing a problem in Java.
I need to have several classes with the same attributes ( for example a Position and a boolean isWalkable ).
But I don't want these classes to inherit from a class Element because that would prevent me from using inheritance later.
I thought of an interface (so that the interface has the attributes), but apparently you can't have an interface inherit from a class.
There must be a way because otherwise I would have to copy/paste my attributes and there methods.
Thanks in advance for anyone who has an idea on how to overcome this problem.

For this, I would consider composition over inheritance.
public class Main {
public static void main(String[] args) {
AgentWrapper agentWrapper = new AgentWrapper(new Agent1(), false, 1);
System.out.println("isWalkable: " + agentWrapper.isWalkable());
System.out.println("position: " + agentWrapper.getPosition());
agentWrapper.getAgent().doSomething();
}
}
interface Agent {
void doSomething();
}
class Agent1 implements Agent {
public void doSomething() {
System.out.println("Agent1");
}
}
class Agent2 implements Agent {
public void doSomething() {
System.out.println("Agent1");
}
}
class AgentWrapper {
private final Agent agent; //Wrapped instance.
private final boolean isWalkable;
private final int position;
public AgentWrapper(Agent agent, boolean isWalkable, int position) {
this.agent = agent;
this.isWalkable = isWalkable;
this.position = position;
}
public Agent getAgent() {
return agent;
}
public boolean isWalkable() {
return isWalkable;
}

I suspect you might need an interface anyway, if you want to treat your objects generically - e.g. loop over all of them and draw each one. E.g. assuming your elements include "cats" and "houses":
interface Element{
public point getPosition();
public boolean isWalkable();
}
class Cat implements Element{
private Point position;
private String catBreed; // example of cat-specific data
public point getPosition() {return position;}
public boolean isWalkable() {return true;} // cats can walk
...
}
class House implements Element{
private Point position;
private String streetAddress; // example of house-specific data
public point getPosition() {return position;}
public boolean isWalkable() {return false;} // houses cannot walk
..
}
// Finally, using that common interface:
Element[] allGameObjects= {new Cat(...), new Cat(...), new House(...) };
for(Element e:allGameObjects)
draw(e, e.getPosition());
That was good enough for several system I wrote... but as other replies correctly mentioned, you might refactor to use composition - however it might not be a 100% clear-cut. I mean, I can understand if you feel Cat or House should be managed independently from their position... but what about isWalkable?
// Position is easy to separate:
class Cat { String catBreed; ... }
class House{ String streetAddress; ... }
class ElementWrapper implements Element{
Point position;
Object theObject; // could hold Cat or House
public Point getPosition() {return position;}
// however, isWalkable is a bit tricky... see remark below
}
But 'isWalkable' is tricky because in classic polymorphism you'd expect House/Cat to tell you whether they can walk (meaning they should implement an interface anyway). If you absolutely don't want (or cant) have it, you may compromise on polymorphism and do something in the lines of instanceof (if theObject is instanceof Cat then it can walk, if it's instanceof House it cannot walk, etc).

You can extend an abstract base class(containing nothing) or You can use the Decorator pattern as somebody suggested in the comments, for more information related to Decorator pattern you can read this link.

Related

OO: new class implementing requires additional parameter

let's say i have an interface as below
public interface ConditionChecker {
boolean isInCondition(Person p);
}
I want to create a new class implementing the above interface but i need to implement a function with another parameter
public class MacroConditionChecker implements ConditionChecker {
public boolean isInCondition(Person p, MacroView mv);
}
Two problems:
One: if i change the interface signature to boolean isInCondition(Person p, MacroView mv); then i need to update all the classes implementing ConditionChecker
Two: I want the consumers of ConditionChecker to just call isInCondition as-is
I think that means:
public class MacroConditionChecker implements ConditionChecker {
private static final MacroView mv;
public MacroConditionChecker(MacroView mv) {
this.mv = mv;
}
public boolean isInCondition(Person p){
// now i have access to MacroView
}
}
so, the only change i need is make at the time I decide to use MacroConditionChecker and the call to isInCondition is not changed
Am i on the right track? or Is there some way else to accomplish this?
or should i separate out MacroView as its own interface
public class MacroConditionChecker implements ConditionChecker implements MacroView
ConditionChecker reminds Command design pattern. Comment from the linked page:
Command decouples the object that invokes the operation from the one
that knows how to perform it. To achieve this separation, the designer
creates an abstract base class that maps a receiver (an object) with
an action (a pointer to a member function). The base class contains an
execute() method that simply calls the action on the receiver.
This is exactly, what you need. In case you need to check only internal state of Person object it is enough. When you want to check Person object with external API that's OK to create implementation which binds external API in constructor with Person object in method. Simple example:
import java.util.ArrayList;
import java.util.List;
public class DesignPatterns {
public static void main(String[] args) {
List<ConditionChecker> checkers = new ArrayList<>();
checkers.add(person -> person != null);
checkers.add(person -> person.getName() != null);
checkers.add(person -> person.getName().length() > 0);
checkers.add(new MacroViewConditionChecker(new MacroView()));
checkers.add(new RestApiConditionChecker(new RestApi()));
Person person = new Person();
person.setName("Name");
for (ConditionChecker checker : checkers) {
System.out.println(checker.isInCondition(person));
}
}
}
interface ConditionChecker {
boolean isInCondition(Person person);
}
class MacroViewConditionChecker implements ConditionChecker {
private final MacroView macroView;
public MacroViewConditionChecker(MacroView macroView) {
this.macroView = macroView;
}
#Override
public boolean isInCondition(Person person) {
return macroView != null;
}
}
class MacroView {
}
class RestApiConditionChecker implements ConditionChecker {
private final RestApi restApi;
public RestApiConditionChecker(RestApi restApi) {
this.restApi = restApi;
}
#Override
public boolean isInCondition(Person person) {
return restApi.checkName(person.getName());
}
}
class RestApi {
public boolean checkName(String name) {
System.out.println("Validate name ...");
System.out.println(name + " is valid");
return true;
}
}
class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
You can use this pattern together with Chain of Responsibility. This approach does not bind Person object with any implementation. This bind is done in specific ConditionChecker implementation which can be easily exchanged.
Given that MacroConditionChecker cannot respect the ConditionChecker signature, then what's the point of implementing it?
Maybe a better approach is to transform the MacroConditionChecker class to an interface which extends ConditionChecker
interface MacroConditionChecker extends ConditionChecker {
boolean isInCondition(final Person person, final MacroView macroView);
}
And then provide a default/simple implementation (or whatever you need)
class SimpleMacroConditionChecker implements MacroConditionChecker {
public boolean isInCondition(final Person person, final MacroView macroView) {
...
}
}
The ones that needs to check a condition using a MacroView will simply accept a MacroConditionChecker
public boolean check(final MacroConditionChecker checker) {
return checker.isInCondition(this.person, this.macroView);
}
Personally, I see them as two totally separated interfaces, but the extension approach is still good.
Choose cautiously, especially if they'll be used in many places.
Since the interface is only asking that you implement the given method, you could overload the method with the parameters that you desire, and the appropriate implementation will run when an extra parameter is passed.
public class MacroConditionChecker implements ConditionChecker {
boolean isInCondition(Person p) {};
public boolean isInCondition(Person p, MacroView mv) {};
}

Java hashCode for similar classes

I have two similar classes, each with a single field of the same type.
class Fruit {
private final String name;
}
class Vegetable {
private final String name;
}
I'd like to implement hashCode() for each. My problem is that in my case, collisions between names are somewhat more possible than with "apple" and "carrot," and they both might be in the same Map/Set. I'm wondering what's the most clear way of implementing hashCode to handle this.
So far, I've considered Objects.hash(this.getClass(), name), Objects.hash(<some int unique to this class>, name). I like the first just because it's a bit more self-documenting and robust than the second, but it's not a pattern I've seen in the wild. I also considered <some prime int unique to this class> * Objects.hashCode(name), but that felt fragile, especially if a new field gets added.
Assuming the 2 classes extend a common parent class, I solved this by adding a second field that would tell the instances of two different classes apart. This may be regarded as just another way of using the class name suggested by David Ehrmann in his question. But in my case using an additional field looks more appropriate than using a class name. So here's my abstract parent class:
public abstract class NationalDish {
public String dishName;
public String country;
#Override
public int hashCode() {
return Objects.hash(country, dishName);
}
#Override
public boolean equals(Object obj) {
if (!(obj instanceof NationalDish)) {
return false;
}
NationalDish other = (NationalDish) obj;
return Objects.equals(dishName, other.dishName)
&& Objects.equals(country, other.country);
}
}
Note how having the fields in the parent class allows to define equals() and hash code() in that same class and keep child classes to the minimum:
public class EnglishDish extends NationalDish {
public EnglishDish(String dishName) {
this.dishName = dishName;
this.country = "England";
}
}
public class AmericanDish extends NationalDish {
public AmericanDish(String dishName) {
this.dishName = dishName;
this.country = "USA";
}
}
Now, with country names (or plant types like in the question) in place we can have same name instances which will look different to Java:
public static void main(String[] args) {
NationalDish englishChips = new EnglishDish("Chips");
NationalDish americanChips = new AmericanDish("Chips");
System.out.println(englishChips.equals(americanChips)); // false
}

Is there someway to restrict the access to a member of an object only to the object that owns it by composition?

I really feel like there must be a way around this.
Imagine I have a large number of objects as components of an owner class. I want to offer easy access to the clients of this owner class to its members, so I make all those objects public. Each of those objects also have all their members public. But one member of the components should not be accessible to the clients of their owner, only by their owner itself:
public class ComponentObject
{
public int int_field;
public float float_field;
public Object object_field;
public Object public_method1()
{
//something;
}
public Object public_method2()
{
//something;
}
public Object restricted_to_owner_only()
{
//something;
}
}
//all clients of Owner should be able to access all the members of its components, except
//restricted_to_owner_only, which only Owner should be able to access
public class Owner
{
public ComponentObject component1;
public ComponentObject component2;
public ComponentObject component3;
//... lots of others
public ComponentObject component300;
}
Is there a way to achieve this? Note that any class from any package can own a ComponentObject, so using package level visibility at restricted_to_owner_only doesn't seem to be an option. ComponentObject is like a utility class, reusable in other applications.
Maybe there's an annotation that enforces that at compile time in some nice lib out there?
EDIT: I forgot to mention that ComponentObject is a parameterized type in real life, and each field in Owner is parameterized differently. I tried to abstract off the details so we could focus on the design problem itself, but I abstracted too much. I will post bellow something more similar to the real problem:
public class ComponentObject<T>
{
public int int_field;
public float float_field;
public T object_field;
//any method could return T or take T as an argument.
public T public_method1()
{
//something;
}
public Object public_method2()
{
//something;
}
public Object restricted_to_owner_only()
{
//something;
}
}
//all clients of Owner should be able to access all the members of its components, except
//restricted_to_owner_only, which only Owner should be able to access
public class Owner
{
public ComponentObject<String> component1;
public ComponentObject<File> component2;
public ComponentObject<Consumer<Boolean>> component3;
//... lots of others
public ComponentObject<Integer> component300;
}
EDIT 2 (Possibly a solution): Guys, inspired by Romeo and Juliet's love, I wrote this solution, can you spot any faults with it? Or would it work as I intended?
//add this class
public class OwnershipToken
{
private static int id_gen = 0;
public final int id = id_gen++;
#Override
public boolean equals(Object obj)
{
return (obj instanceof OwnershipToken) && ((OwnershipToken)obj).id == id;
}
#Override
public int hashCode()
{
return id;
}
}
//Then change this in ComponentObject<T>:
public class ComponentObject<T>
{
//add this field:
private final OwnershipToken ownershipToken;
//add this constructor
public ComponentObject(OwnershipToken onwershipToken)
{
this.ownershipToken = ownershipToken;
}
//change restricted_to_owner_only signature:
public Object restricted_to_owner_only(OwnershipToken ownershipToken)
{
//add this condition
if(this.ownershipToken.equals(ownershipToken)
//something;
}
}
//finally, Owner gains a field:
public class Owner
{
private final OwnershipToken ownershipToken = new OwnershipToken();
//... etc, remainder of the class
}
would this work as intended?
I understand what you want and that is impossible i think.
But, there is still one way to do it!
Make an id in the owner class:
private int id = new Random().nextInt(10000);
In ComponentObject:
private id;
public ComponentObject(int id){
this.id = id;
}
public Object restricted(int id){
if(this.id != id)
return null;
else
return object;
}
In owner:
private ComponentObject<String> string;
public Owner() {
string = new ComponentObject<>(id);
string.restricted(id);
//if the id is right it will return the restricted object, if not i will
//return null
}

What kind of relationship does an interface have with it implementing class?

A subclass has a relationship that is described as IS-A with it base class, but a base class does not share this kind of relationship with it subclass. I was wandering what kind of relationship an interface have with it implementing class since an object of that class can be passed to interface object and the interface object can only access methods defined it concrete Interface.
public class main {
public static void main(String[]args){
Nigeria ng = new Nigeria(){};
//Interface object can accept Nigerias object which is not posible in Inheritance
Continent continent = ng;
//prints Country is in Africa
continent.Africa();
//continent.language(); will not compile language is not in the interface
//Print Democratic thought this should print Undefined since it is inialied with default.
continent.Goverment();
}
}
interface Continent{
public void Africa();
default void Goverment(){
System.out.println("Undefined");
}
}
class Nigeria implements Continent{
#Override
public void Africa(){
System.out.println("Country is in Africa");
}
public void language(){
System.out.println("Official Language is English");
}
public void Goverment(){
System.out.println("Democratic");
}
}
If you are looking for English-language analogues, an Interface is not an "Is a..." nor "Has a..." relationship, but more an "Is...".
An Interface is not about the class that uses it.
It's about the consumer that asks for it.
If you wanted to see it as anything, you could see it as an adjective.
"He is Responsible".
Well, what does he do?
He finishes tasks; he takes ownership of his mistakes; he makes them right.
Is he a pilot, is he a surgeon, is he a doctor?
Is he a child, a father, a greatGrandfather?
Do you care?
I need a responsible person, to help me do this job.
Does ResponsiblePerson inherit from PoliceOfficer? Does Lawyer inherit from ResponsiblePerson, because I'm sure there can be irresponsible lawyers.
class Lawyer extends Person { }
class ResponsibleLawyer extends Lawyer implements ResponsibleEntity { }
class NeedyPerson extends Person {
public void acceptHelp (ResponsibleEntity somebody) {
try {
somebody.attemptTask( someTask );
} catch (TaskCompletionError err) {
somebody.takeOwnership(err);
somebody.fixMistake(err);
}
}
}
Can corporations be Responsible too?
Perhaps we don't see it too often, but it's theoretically possible:
class LawFirm extends CorporateEntity { }
class BetterLawFirm extends LawFirm implements ResponsibleEntity { }
Can somebody be a responsible corporate body? Well, so long as that corporate body does all of the same things that the responsible person would otherwise do, sure.
In another example, you might have a Switchable interface.
Looking at that name, you could surmise that the thing you're being given has a switch which can be poked.
So what methods might it have?
on( )
off( )
toggle( )
isOn( )
sounds like a useful set to have.
What benefit is there to having an interface like this?
Well, now I know that I can deal with a switch, and its lineage doesn't matter.
If all I want is a class which takes a switch and does something with it, why do I need to create dozens of classes, just to accept my dozens of things with switches?
Or override methods into the dirt to do the same.
class SwitchThrower {
public void throwSwitch (CoffeeMaker coffeeMaker) { coffeeMaker.on(); }
public void throwSwitch (LightSwitch lightSwitch) { lightSwitch.on(); }
public void throwSwitch (GhostTrap ghostTrap) { ghostTrap.on(); }
public void throwSwitch (TheHeat theHeat) { theHeat.on(); }
public void throwSwitch (CarIgnition ignition) { ignition.on(); }
}
...
why not just:
class SwitchThrower {
public void throwSwitch (Switchable switch) { switch.on(); }
}
class LightSwitch implements Switchable {
private boolean currentlyOn;
public LightSwitch (boolean initiallyOn) {
currentlyOn = initiallyOn;
}
public LightSwitch () {
currentlyOn = false;
}
public boolean on () {
currentlyOn = true;
return currentlyOn;
}
public boolean off () {
currentlyOn = false;
return currentlyOn;
}
public boolean toggle (boolean forceOn) {
boolean state;
if (forceOn == true) {
state = on();
} else {
state = off();
}
return state;
}
public boolean toggle () {
boolean state;
if (isOn() == true) {
state = off();
} else {
state = on();
}
return state;
}
public boolean isOn () {
return currentlyOn;
}
}
...et cetera
As you can see, aside from describing a basic feature-set of the implementer, interfaces are not about the class at all, but rather the consumer.
An even more awesome implementation of this, in different languages, is _Traits_.
Traits are typically like Interfaces, but they have default behaviour associated with them.
Looking at my Switchable and my LightSwitch, you could imagine that practically all classes with this switch would have the same methods, with the same method behaviour...
...so why would I rewrite all of those methods over again, if I'm already going through the trouble of defining the signature in the interface?
Why couldn't I just add default behaviour in there, and have it apply to the implementer, unless a method is overridden?
Well, that's what Traits / Mix-Ins allow.
The relationship is only the "contract" that the class is getting to implement the methods the interface is offering.
That is how java can separate WHAT objects can do (Interface) and HOW the inherited class will do it.

Having a method accept different objects as an argument

First I will just put my sample code.
public class Shape {
public String colour;
public Shape(String colour) {
this.colour = colour;
}
}
public class Car {
public String colour;
public Car (String colour) {
this.colour = colour;
}
}
public class Colour {
public static String getColour(Object item) {
return item.**colour**;
}
}
I've read other questions related to this, but I just can't seem to understand. I found their original code was just too complex for me to get around. So I tried to make as simple a code as possible. Anyway, I want getColour to accept both the Shape and Car object. If I use Object like I did in my example, the "colour" in bold is considered an error. The error I get is "colour cannot be resolved or is not a field". What's wrong?
Also, I've heard a lot of "static methods are bad" etc., is this a case of it being bad? Because I find if I don't make it static, then I need to duplicate getColour methods in both the Shape and Car classes. If I should avoid static methods, then please suggest another way to do this.
What you're looking for is the concept of interfaces:
public interface Colourable {
String getColour();
void setColour(String colour);
}
You should modify the Shape and Car classes:
public class Shape implements Colourable {
public Shape(String colour) {
this.colour = colour;
}
private String colour;
public String getColour() {
return colour;
}
public void setColour(String colour) {
this.colour = colour;
}
}
(note that I've made the colour field private; this is common practice and called encapsulation)
You can then define your static method as
public static String getColour(Colourable item) {
return item.getColour();
}
And static methods are definitely not bad, though in this case the method itself is a bit superfluous, because if you already have an Colourable, you know you can call .getColour() to get its color. A bit more useful would be the method
public static boolean isRed(Colourable item) {
return "red".equals(item.getColour());
}
You can "unify" Shape and Car. There are two general approaches:
Inheritance and
Interfaces
Let's look at both.
Inheritance: When a class Porsche inherits (or, in Java syntax, extends) a class Car, you establish an "is-a" relationship. In this case: Porsche is-a Car. Now, the magic comes to work, when you use object references. You can now write something like this:
Car c = new Porsche();
Since a Porsche has everything, a Car has (plus some things on top), you can see a Porsche as a Car (each Porsche is a Car, but not each Car is a Porsche). Reading my last sentence carefully, it is obvious, that the following does not work and, in fact, produces a compile error:
Porsche p = new Car();
What you can now do is write a method, that expects a Car and pass in a Porsche (since every Porsche is a Car).
Coming back to your example. To get this working, you could define a common parent class for Shape and Car, let's call it Colourable and give it a method public Colour getColour(). Then, you could simply change your getColour(Object item) method to getColour(Colourable c).
Remeber the thing I said about the "is-a" relation? Ask yourself: is each Shape a Colourable? Is each Car a Colourable? Why should Car and Shape both be in the same bucket (Colourable)? And what to do, if Car already has a parent class, e.g. Vehicle? This solution is sub-optimal.
Interfaces: This is, where interfaces come into play. Interfaces guarantee, that certain methods are present. Instead of defining a common parent class Colourable, you could simply write Colourable as an interface, containing the method public Colour getColour(). Now Shape and Car can implements this interface. This forces you to implement this method in both classes. The beauty: you can use interfaces just like classes. Meaning your implementation of getColour(Colourable c) does not need to change.
For more details, please read the provided tutorials on Inheritance and Interfaces.
Seems like your trying to use duck typing, which isn't how Java works.
The easiest thing to do, IMHO, would be to define an interface to handle the color. E.g.:
public interface Colourful {
public String getColour();
}
public class Shape implements Colorful {
private String colour;
public Shape(String colour) {
this.colour = colour;
}
#Override
public String getColour() {
return colour;
}
}
public class Car {
private String colour;
public Car (String colour) {
this.colour = colour;
}
#Override
public String getColour() {
return colour;
}
}
Alternatively, if you don't want to change Shape and Car, you could use reflection to extract the colour field, but this is usually considered a bad idea, and you'd probably be better off not using it:
public static String getColour(Object o) {
Field colourField;
try {
colourField = o.getClass().getField("colour");
} catch (NoSuchFieldException e) {
// No such field
return null;
}
Object colourValue;
try {
colourValue = colourField.get(o);
} catch (IllegalAccessException e) {
// The field isn't public
return null;
}
if (!(colourValue instanceof String)) {
// The field isn't a String
return null;
}
return (String) colourValue;
}
The reason an error is thrown is that Object doesn't have a colour field. I wouldn't recommend it, but if you want to move forward with this design, you could make a class called ShapeCarParent (used in this case because I see no clear relationship between the two) and have both the classes inherit from that, and then change getColour, like so:
public class ShapeCarParent{
public String colour;
}
public class Car extends ShapeCarParent
public class Shape extends ShapeCarParent
public class Colour {
public static String getColour(ShapeCarParent item) {
return item.colour;
}
}
This is still pretty poor style, so you can also use an interface which you then implement in each class.
public interface ColorProperties{
public String getColour();
}
public class Car implements ColorProperites{
public String getColour() {
return colour;
}
}
public class Shape implements ColorProperites{
public String getColour() {
return colour;
}
}
Hope this helps.

Categories