I'm trying to have an abstract superclass Race that is implemented by my ants as generic so that I can access attributes like "Movement Speed" for the ants. For the different races I will create classes extending Race and I want to give each Race different attributes, obviously. "Movement Speed" needs to be static in Race somehow so I can access them by the Class and not an instance of the object but it can't be static because then its the same for all races. I need a way to circumvent this problem because my whole program structure relies on it.
I can't make Race be the superclass of Ant because I have subclasses of Ant like Drone or Queen and they should be accessible for all races.
public abstract class Race {
public static double speed;
}
public class defaultAnt extends Race {
public static double speed = 2;
}
public abstract class Ant<R extends Race> {
public void move(){
speed = R.speed;
}
}
When I try it like this its all the same for all races, though it shouldn't be.
"Movement Speed" needs to be static in Race somehow so I can access them by the Class
Not at all. Consider static to be an abnormality in good OOP design, especially in Java. The OOP way would be to go like this:
public abstract class Race {
protected abstract double getIndividualSpeed();
...
and then subclasses (in the right place) #Override that to provide individual speed.
But as said: the key thing here is that you step back and re-think your design. Using a static field, especially in a "polymorphic" context is (almost) a no-go.
Beyond that, that idea about generics, it doesn't fit here too good. Generics are (more or less) about "containing" something. When you say class Foo<T extends Bar> then you communicate that Foo instances will somehow own/relate to the Bar class. Which, yes somehow fits your usecase, but (personally), I am not sure if generics are the right choice here.
And the thing is: generics are mostly a compile time thing. At runtime, that notion of R is gone. Your class Ant has no knowledge whether you had
Ant<Drone> ant = new Ant...
or
Ant<Queen> a2 = ...
In other words: R.speed is not possible conceptually. A more OOP approach could look like this:
public abstract class BaseAnt<R extends Race> {
protected final R rInstance;
protected BaseAnt(R rInstance) { this.R rInstance = R rInstance; }
public final double move(double distance) {
return distance / Instance.getSpeed();
}
public class Ant<R extends Race> {
ctor that calls super constructor
and then
public enum Race {
DRONE(5), QUEEN(1);
private final double speed;
private Race(double speed) { this.speed = speed; }
public double getSpeed() { return speed; }
In other words: you can use an enum that works as "constant provider". You can invoke getSpeed() on Race.DRONE; and you get back 5 then.
And then you can instantiate Ants using either Race.DRONE or Race.QUEEN.
The BaseAnt class on the other hand does all the "common" stuff for Ants, and your child classes then add specific behavior.
Related
Here's the problem, I have two drawing JAR libraries (A and B). Both provide separate but useful functionality. However, in their infinite wisdom they have two different concepts of the basic point class.
Neither has any interesting or particularly unique methods or fields and both basically boil down to:
public class PointA{
double x;
double y;
}
and
public class PointB{
double x;
double y;
}
The functions in these libraries have methods that look like:
public static List<PointA> doInterestingThing();
or
public static PointB calculateThatThing();
I feel like there should be some nice way to just understand that these two classes are for all intents, the same.
If I had source access I could just have them implement some IPoint interface, but both libraries are in JARS.
The way I see it, there are several options:
Convert one to the other. Either make functions to convert all PointA's to PointB's or vice versa. That would mean essentially making a abstraction layer atop one of the libraries by wrapping every function in it with some boilerplate conversion code.
public static List<PointA>doInterestingThingWrapper(){
return convertPoints(LibraryB.doInterestingThing());
}
Make some third class PointC, that both library's results are converted to which represented my code's understanding of a point. Same problems as above, but now I need to write two times as many boilerplate conversions!
Edit the JARS directly. Obviously this is not preferable. However, it would allow me make PointA and PointB implement the same interface.
Some magic dynamic interface interaction I don't know about.
Could it be that Java has some way of dynamically assigning interfaces to already loaded classes?
Something like:
public interface IPoint{
double getX();
double getY();
}
public static void main(){
//Magical made up linking syntax
PointA implements IPoint{
public getX(){
this.getX()//PointA's method
}
public getY(){
this.getY(){//pointA's method
}
}
//And same for pointB
//And now we can say things like:
List<? extends IPoint> listOPoints=A.doInterestingThing();
//and:
IPoint thePoint=B.calculateThatThing();
}
I apologize in advance if this is a duplicate. I didn't even know what to call the problem which makes searching hard. If there's some obvious design pattern (adapter pattern?) that I missed that solves this, let me know.
You have two solutions
Use reflection and unreflection to use same named functionatily.
Wrap both in your project code into a object that implements the interface.
Sample:
class A { public void d(){}}
class B { public void d(){}}
interface D { void d(); }
class AD extends A implements D {}
class BD extends B implements D {}
Or
class AD implements D {A obj = new A(); public void d(){obj.d();}}
I was reading some article about collision avoidance systems in cars when my programmer mind led me to think of that concept in the object-oriented way, and it made me wonder if those systems respect the object-oriented programming model.
Being mainly a Java developer, I transposed this problem in a Java environment and it raised a particular question: does calling a public method within the same class (in a non-static context) respect and follow the object-oriented way?
I mean, take this brief hypothetical Car class:
public class Car {
// Class attributes.
// Constructors.
public void accelerate(final double amplitude) {
// Accelerate according to the amplitude.
}
public void brake(final double amplitude) {
// Brake according to the amplitude.
}
// Other useful methods.
private void collisionPreventionActions() {
// Some actions.
brake(100.0);
// Some other actions.
}
}
Suppose some Thread is responsible of detecting a collision and take actions when it does detect a collision, and one of those actions would be braking. Obviously the brake(...) method becomes an interesting choice, but doesn't that break the object-oriented way of doing things? It's not just the brakes though. What if the collision avoidance system in this class used the steering wheel instead to avoid the accident? I find it weird that the car would be using its own input from an internal point of view...
On a more general scope, suppose you have a generic object, which I like to see as a black box. The public methods would be the equivalent of levers on that black box that would control its behaviour. Calling a public method within this object would mean that the black box would activate its own levers from its internal mechanism.
I ask because I know it's legal in Java to do so, and that I've seen public methods being called within the same class numerous times in my life, but it being legal doesn't necessarily mean that it's the proper OO way of doing it.
Does using public methods within the same class in a non-static context follow the rules of object-oriented programming and encapsulation? If not, what would be the proper way of doing it or what could be the workaround?
There is nothing wrong with this choice from the OOP perspective: it is perfectly fine for a method to perform things that require combinations of other methods.
In practice, though, a common approach would be to separate the functionality into a public and a private portions, like this:
public void brake(final double amplitude) {
// check preconditions
if (speed == 0) throw new IllegalStateException("cannot brake when standing");
if (amplitude <= 0) throw new IllegalArgumentException("amplitude must be positive");
// ... do other important checks
doBrake(amplitude);
}
private void doBrake(final double amplitude) {
// The real code goes here
}
Now your collisionPreventionActions could call doBrake instead of brake, assuming that you have checked all the necessary preconditions before making the call.
Note: doBrake should check its preconditions as well. However, rather than throwing exceptions when preconditions are not met, it can use assertions. The difference is that exceptions indicate a misuse of your public methods by others, while assertions indicate misuse of your encapsulated methods by you or someone else maintaining your code.
No rules are violated when an object uses its own API. On the contrary, problems are likely to occur if a class has an API that can be overridden, but it fails to use that API internally.
As a trivial example, consider a non-final property accessor. An object could skip the accessor and read (or worse, write) fields directly. Suppose the accessor is overridden in a subclass to compute the property value using the field together with some other information from the subclass. Now the class is broken because it failed to honor its own contract.
Consider the (somewhat contrived) Point and OffsetPoint classes below. The derived class, OffsetPoint is written correctly, but it's inherited toString() method will not work as expected because the parent class, Point, wrongly fails to use its own accessors.
public class Point {
private final int x, y;
public Point(int x, int y) { this.x = x; this.y = y; }
public int getX() { return x; }
public int getY() { return y; }
#Override
public final String toString() {
/* Here's the bug; should be getX() and getY() instead of x and y */
return String.format("(%d,%d)", x, y);
}
}
class OffsetPoint extends Point {
private int dx, dy;
OffsetPoint(Point point, int dx, int dy) {
super(point.getX(), point.getY());
this.dx = dx;
this.dy = dy;
}
#Override
public int getX() { return super.getX() + dx; }
#Override
public int getY() { return super.getY() + dy; }
}
Does using public methods within the same class in a non-static context follow the rules of object-oriented programming and encapsulation?
No, there is no problem with encapsulation becuase the method is public so anyone (even this) can call it.
However, for something like a collision avoidance system, relying on public methods could be bad security wise.
Let's use your example of this intenal Collision detector calling the public method brake(). What if someone subclassed car and overrode the method?
public class BrokenCar extends Car{
#Override
public void brake(final double amplitude) {
//BREAKS CUT!!!
}
}
So there are some security rules of not relying on overridable methods. Making brake and accelerate final methods resolves this problem.
Yes, I think it is proper in an OO context to call your own public method. It's quite common when there are overloads for a method that all but one call the most specific one, either filling in defaults for missing parameters or transforming the type of the argument(s). I also see the pattern where all the overloads call into a private or protected method of the same name with _internal or _impl added to the end. For example, several overloads of ComputeSpeed might all call ComputerSpeed_internal. This pattern would be appropriate if there is parameter validation in the public methods that you don't want to do twice, or would be inappropriate for internal calls.
You can certainly introduce problems by not having a clear separation of concerns. For example, if the caller of collisionPreventionActions also decided it was a good idea to set the brake, you could have a conflict in how much brake is applied.
KC
In general, it is fine to call the public methods. The thing to consider is what the interface of the Car should be. In this case, does preventCollision() belong in the Car class or in some other CollisionPrevention class.
Breaking your code multiple classes each with a single responsibility, and then using them a bigger class like Car, is generally a good idea.
I totally agree with you that it's common that a class itself addresses its private members and methods. But I don't understand why it shouldn't be legal in terms of the Object Oriented Paradigm. Consider the following example:
public class Human {
public Human() {
liveYourLife();
}
private void liveYourLife() {
while(alive){
createYourDay();
}
}
private void createYourDay() {
drink();
eat();
sleep();
awake();
drink();
}
private void eat() {}
private void drink() {}
private void sleep() {}
private void awake() {}
}
Probably someone will criticise the simple rule of life, shown in the example above. But what I want to demonstrate with the few lines above is, that "normally" a human is allowed to decide on his daily routine.
The basic principle of the OO-Paradigm is to describe the actions and properties of real world entities. Hence, as long you are allowed to yourself decide on when you want to eat, drink, sleep, etc. your above described model is absolutely correct. But if you discover some exceptional cases in your problem domain which you want to address in your software (e.g. you got arrested, etc. ) you should update your OO-design.
In case that there is an something, which heavily influences the state of another instance, you should treat that "instance of disturbance" as a different object which has a reference to the actual instance.
public class Prisoner extends Human {
#Override
private void liveYourLife() {
while(jailed){
createYourDay();
}
}
#Override
private void createYourDay() {
// A bit different :)
}
}
public class Prison {
private List<Prisoner> prisoners;
}
I have learned that Java doesn't allow instance fields in an Interface, but I really want this feature.
I am learning to create my first game. My game has different kind of actors such as Hero (to be control by the player), Boss, Canon, etc...
No matter which kind they are, I want that every actors inherit from the base class Model which imparts some fields to its subclasses such as position, width and height so that every subclasses of Model can associate with Controller and Renderer as in MVC pattern.
public class Model {
//position
public float x;
public float y;
public float width;
public float height;
}
Incidentally, I intended that Hero and Boss are entities that can die, so I want that they are instances of Life which is enforced to have, for example, public float hitPoint; as a field, in contrast, a Cannon is not a Life because it will be an immortal entity. Thus I tried:
public interface Life {
public float hitPoint;
}
and expected that an instance of
public class Hero extends Model implements Life {...}
will intrinsically have the hitPoint. But then I learned that instance fields in an Interface are not allow in Java, and it don't support multiple inheritance as well.
Is it possible to achieve the above mentioned design in Java.
only constants can be declared in an interface.
anything you define in an interface is always public static final (except for the methods ofcourse as they are public abstract) if the hitpoints value will never change then this design works for you.
A better solution would be this
public interface Life {
//methods that implementation of this interface should implement
}
public abstract LifeForm extends Model implements Life {
int hitPoints;
//other LifeForm specific methods and instance variables
}
public Hero extends LifeForm {
//Hero specific methods like save the damsel
}
The short answer is 'no'. As you mention, Java doesn't support multiple inheritance -- there are some things you just can't do. However, one can almost always work around this limitation with clever application design. For example, why can't 'Life' extend 'Model'? Or perhaps you could just define accessors (e.g. getHitPoints()) in interfaces? If you really feel the need for an approximation of multiple inheritance, check out Aspect Oriented Programming extensions like AspectJ.
Does it make sense to you to declare Life and Model as field members and change their initial values and state depending on each of the desired Actor implementation?
For example, set the life's value to Infinity for the Cannon objects and to a finite value for other Actors. When you modify the life's value, just be sure to check for Infinity and let it unmodified if it's the case.
public class Hero implements Actor{
//initialize these fields differently in each Actor implementation
private Life life;
private Model model;
public void init() {
// different initialization values here
}
}
public class Cannon implements Actor{
//initialize these fields differently in each Actor implementation
private Life life;
private Model model;
public void init() {
// different initialization values here
}
}
My question is a bit long.
I am learning abstract factory pattern.
I have a abstract class for the abstract factory.
I want to share the "resources" needed by the concrete factories.
So I simply make the variable inside AbstractFactory as static
public class AbstractFactory{
private static Vector vector = new Vector();
protected Vector void getVector() {
return vector;
}
protected void setVector(Vector v){
this.vector = v;
}
public abstract Circle createCircle();
}
And its Subclass will look like:
public class ConcreteFactory extends AbstractFactory{
public ConcreteFactory(){
super();
}
public Circle createCircle(){
Circle circle = new Circle();
getVector().add(circle);
return circle;
}
}
However, my teacher said that I should not use the static object instance
because static variables are often used for some constants.
Therefore, I use instance variable instance instead of static variable for the Vector
, and I pass the vector from outside when I instantiate the concrete factory.
So the new design of my classes will look like:
public class AbstractFactory{
private Vector vector;
protected Vector void getVector() {
return vector;
}
protected void setVector(Vector v){
this.vector = v;
}
public abstract Circle createCircle();
}
public class ConcreteFactory extends AbstractFactory{
public ConcreteFactory(Vector v){
super();
setVector(v);
}
public Circle createCircle(){
Circle circle = new Circle();
getVector().add(circle);
return circle;
}
}
**
My question is : why I should not use the static variable to share object?
**
It will be easier to share resources among the concrete factories without passing in the Vector
when I create an instance of concrete factories.
Sometimes what makes your life easier today will make it much, much more difficult down the road.
Some examples: You don't always know the environment where your class will be used. Maybe different instances of your factories will wind up being loaded by different class loaders (this happens often in web applications). You could wind up with completely unpredictable behavior using a static instance variable that way. Static variables are almost always a bad idea.
That said, I think that what you really want to do in your class is this:
public class AbstractFactory{
private final Vector vector;
protected AbstractFactory(Vector vector){
this.vector = vector;
}
protected Vector void getVector() {
return vector;
}
public abstract Circle createCircle();
}
and
public class ConcreteFactory extends AbstractFactory{
// USE THIS IF YOU NEED TO SHARE THE VECTOR AMONGST MULTIPLE FACTORY INSTANCES
public ConcreteFactory(Vector vector){
super(vector);
}
// OR USE THIS IF THE VECTOR IS SPECIFIC TO THE FACTORY
public ConcreteFactory(){
super(new Vector());
}
public Circle createCircle(){
Circle circle = new Circle();
getVector().add(circle);
return circle;
}
}
the use of final on the instance variable is a good idea for this sort of thing - it keeps you from accidentally changing the variable elsewhere in your code. But that is optional. The key change that I made is adding vector to the constructor of the abstract base class, then passing it in from the super class.
static attributes are just not meant to be used that way.
statics are something, that is available only once during runtime.
In your case that means that all factories deriving from your AbstractFactory will share this single vector.
See this example:
ConcreteFactory a = new ConcreteFactory();
ConcreteFactory b = new ConcreteFactory();
a.createCircle();
b.createCircle();
Both objects a and b will now have two entries in the vector, since they share the same, static vector.
Also do I think, that
protected void setVector(Vector v){
this.vector = v;
}
is illegal, because vector is not an attribute of the instance of the Factory, but an attribute of the Factory itself!
Adding to that it is just a bad, error prone (try debugging that on a larger scale) and plain ugly style of coding.
Just trust your teacher there - he's right ;)
The fact that static final variables are sometimes used as constants should not prevent you from using the same mechanism wherever it servers the best (logger is the only other example I can give).
It is always good though, when there is no implicit component coupling to the outer world. If you define vector as a static variable you leave user no possibility to make your factories be context based and independent from one other. If you make the vector an argument of the factory then it is up to the factory creator (typically Spring context loader nowdays) to define which factories share the vector and which do not.
Another reason to pass vector as an argument in your case is related to the unit testing aspect. If your class is designed to take vector from the outside you can mock it and test your class more thoroughly.
My problem concerns an API design.
Let's say I'm designing a vector (math/physics meaning). I would like to have both an immutable implemenation and a mutable one.
I have then my vector that looks like this:
public interface Vector {
public float getX(); public float getY();
public X add(Vector v);
public X subtract(Vector v);
public X multiply(Vector v);
public float length();
}
I wonder how I can ensure to have both a mutable and an immutable implementation. I don't really like java.util.List's approach (allowing mutability by default) and the UnsupportedOperationException() that Guava's immutable implementation has.
How can I design a "perfect" interface or abstract class Vector with both these implementations?
I've thought about something like this:
public interface Vector {
...
public Vector add(Vector v);
...
}
public final class ImmutableVector implements Vector {
...
public ImmutableVector add(Vector v) {
return new ImmutableVector(this.x+v.getX(), this.y+v.getY());
}
...
}
public class MutableVector implements Vector {
...
public MutableVector add(Vector v) {
this.x += v.getX();
this.y += v.getY();
return this;
}
...
}
So all in all, I would like to check if this approach has flagrant design flaws, which are they and what should I do tho fix these?
Notes: the "vector" stuff is an example of a more general use case. For the sake of my question I could have chosen to rewrite the List interface or anything else. Please focus on the more general use case.
Final choice, after answers below, based on Joda-time as someone explained but now edited:
/** Basic class, allowing read-only access. */
public abstract class ReadableVector {
public abstract float getX(); public abstract float getY();
public final float length() {
return Vectors.length(this);
}
// equals(Object), toString(), hashCode(), toImmutableVectors(), mutableCopy()
}
/** ImmutableVector, not modifiable implementation */
public final class ImmutableVector extends ReadableVector implements Serializable {
// getters
// guava-like builder methods (copyOf, of, etc.)
}
/** Mutable implementation */
public class Vector extends ReadableVector implements Serializable {
// fields, getters and setters
public void add (ReadableVector v) {/* delegate to Vectors */}
public void subtract(ReadableVector v) {/* delegate to Vectors */}
public void multiply(ReadableVector v) {/* delegate to Vectors */}
}
/** Tool class containing all the logic */
public final class Vectors {
public static ImmutableVector add(ReadableVector v1, ReadableVector v2) {...}
public static void addTo(Vector v1, ReadableVector v2) {...}
...
}
I changed Vector from an interface to a abstract class because basically a vector shouldn't be anything else.
Thank you to everyone.
As a user of your Vector library, I would not like to have one add implementation which modifies the current Object and another add implementation (of the same interface) which returns a new one.
Better have a clear set of methods which do not modify the current object, and then have additional methods in the mutable vector which do modify the current object.
I do not think there is anything evidently wrong with your design. I find it perfectly valid. There are few things that I would take into account if I were you:
Reckless users may write code for the
interface Vector thinking their
implementations are always mutable.
Immutability typically means more objects and a performance penalty due to the need to put more and more objects in the heap and forces the garbage collection to do more work. If your application will need to do many "add" operations you may need to pay the price. But hey, that's the whole purpose of having a mutable version, right?
Also, if you are writing for a multithreading environment, you will still need to synchronize access to share variables of type Vector when you are not sure of implementation above all if you want to ensure that the implementation can be switched without consequences. This, again, proves that it can be hard to write code oblivious of implementation details.
Although I argued a bit with #Paulo Eberman in other post, I do believe he is totally right. I think it is best to have two separate interfaces, one for immutable objects, and one for mutable (which could extend this latter).
Of course most of this points are arguable, these are just my opinions.
Your idea is fine, but it's hardly perfect.
You've left out generics.
You assume that arithmetic operations such as addition and subtraction are defined for the types your Vector is holding, which may not be true. (Generics might help with that.)
I don't know how useful an immutable vector is in the context of mathematics and physics.
A perfect API would have an analogous Matrix class, since you'll need to do linear algebra for math and physics.
I'd have a look at Apache's common math library for inspiration. It's the heir to JAMA. I find that looking at successful designs and implementations by my betters is a good way to learn.
I think this design is not very good. Having mutable arithmetical objects is not good if even you have them explicitly marked as mutable. Additionally, I wouldn't put vector operations in the class vector. Because now you have only addition and multiplication and tomorrow you will want something else and your class will grow and grow as you will add this or what vector operation. If I were you, I would create an immutable vector like this
public class Vector {
private Double X;
private Double Y;
public Vector(Double x, Double y) {
X = x;
Y = y;
}
public Double getX() {
return X;
}
public Double getY() {
return Y;
}
}
and then I would create a class for doing basic vector operations:
public class BaseVectorAlgebra {
public static Vector add(Vector arg1, Vector arg2) {
return new Vector(arg1.getX() + arg2.getX(), arg1.getY() + arg2.getY());
}
}
This way you will have an easy way to extend the system without touching existing classes and without introducing mutability, which just complicate things.
UPDATE:
If you still want to go with mutable vectors, then I would add SetX and SetY setters into Vector class, but put mutability decision into BaseVectorAlgebra like this:
public static Vector addInto(Vector arg1, Vector arg2) {
arg1.setX(arg1.getX() + arg2.getX());
arg1.setY(arg1.getY() + arg2.getY());
return arg1;
}
But really I don't like mutability here as it introduces unnecessary complications