Casting and instance of or nearly empty interface? - java

I'm programming some kind of board game containing robots, items and such.
At one point, I need to get the energy value of a robot or an item that can have energy. The way this is programmed is that each robot and each item having energy have an EnergyContainer class as a field (to prevent code redundancy) and an energy Value class.
Now, basically, I call a method evaluate() that receives an Element. Element is an abstract class which robot and items extend. Not all elements have energycontainers. If possible, I need to call the getEnergyContainer on this element, but only if it is an element that has it of course.
I can think of a couple solutions: using a lot of instanceOf and then casting. So asking for example, if the element is instanceof robot, cast element to robot and call getEnergyContainer on the element. This has as clear disadvantage that I need to do this for every energy having subclass of element.
Second solution is defining an interface containing only a getEnergyContainer method and make all energy having classes implement this. The only purpose for this interface is then to facilitate the one method and it would be nearly empty.
Unless anybody has a better idea, what is the "best" solution? Nearly empty interfaces are used as Marker interfaces I think, but this it is one and only purpose so I'm a bit inclined against it.

If possible, I need to call the getEnergyContainer on this element, but only if it is an element that has it of course.
Why would you not want to call it on an element that doesn't have an energy container? If it doesn't have an energy container, either return a reference to some "null object" implementation of EnergyContainer, or return a null reference. It depends on what you want to do with it later - if you can easily implement some sort of "neutral" energy container, then the null object pattern is the simplest approach. Otherwise, just:
EnergyContainer container = element.getEnergyContainer();
if (container != null) {
// Use the container
}
There are no doubt those who would argue that this is in some senses "impure" - but it's almost certainly simpler than most alternatives.

The best solution would be to put the getEnergyContainer() method in one of the super classes of all energy containing elements the overriding this method in each elements class. You can make this method abstract to ensure its over-ridden. your super-class for this could be Element because you said: Element is an abstract class which robot and items extend.

Given your class hierarchy use composition with an Interface to provide default EnergyContainer behaviour
abstract class Element {
EnergyContainer ec = new EmptyEnergyContainer();
int getEnergyValue() {
getEnergyContainer().getValue();
}
EnergyContainer getEnergyContainer() {
return ec;
}
setEnergyContainer(EnergyContainer container) {
this.ec = container;
}
}
class Robot extends Element {
public Robot() {
this.ec = new ActiveEnergyContainer();
}
}
class Item extends Element{
public Item() {
this.ec = new ActiveEnergyContainer();
}
}
class Brick extends Element{
// will have a EmptyEnergyContainer by default
}
The Interface hierarchy for the EnergyContainer is like this
interface EnergyContainer {
int getValue();
setValue(int value);
}
class EmptyEnergyContainer implements EnergyContainer {
#Override
int getValue() {
return 0;
}
#Override
setValue(int val) {
throw Exception("Can not charge an empty container");
}
}
class ActiveEnergyContainer implements EnergyContainer {
int value;
#Override
int getValue() {
return 17 + 3; // calculate the value
}
#Override
setValue(int val) {
this.value = val // or do some funky calculation
}
}
At runtime you are able to set new EnergyContainer types for your objects. If you have multiple parent classes like Element then you will have to follow the same pattern of adding the default behaviour to the abstract parent and override as required.
Having the default behaviour return a sensible default value for getValue() will help you not have to use instanceof all over the place.
Potential improvements to this code would be to introduce
AbstractFactory pattern for creating the various EnergyContainer
variants
Including a hasEnergy() method to make your code more readable rather than checking for a value == 0
Make Element implement an Interface if other similar parent classes will include simlar methods

Related

Differential Functions with Interface in Java

I have to code a Java programm that takes a function like f(x)=2x-5 (but more complex) and evaluates f(x) and differenciate to f'(x). For this I must implement the interface Function:
public interface Function {
double evaluate(double x);
Function differentiate();
}
and implement the interface in several classes like (not correct yet):
public class Constant implements Function {
private final int FS = 0;
#Override
public double evaluate(double n) {
return n;
}
#Override
public Function differentiate() {
return this;
}
public Constant(double value){
evaluate(value);
differentiate();
}
}
that are parts like "product", "sinus", ... that are needed for the programm.
My problem is that I dont know how this should work, because the functions are kind of abstact (because of the unknown x) and the differenciate-method in the interface returns another interface i guess with doesn't make sence to me.
I am a new programmer and hope the get some help here.
Thanks very much!
If one takes this task literally, you will need to write an expression parser that takes a string like "2*sin(x)-5" and translates this into calls that composed amount to
F.Sum(F.Prod(F.Cons(2),F.Sin(F.VarX)),F.Cons(-5))
where F is an instance of a factory class (or a module) where each of the calls returns an implementation of the interface Function for the corresponding abstract function or operation. (Doing it via factory allows book-keeping operations such as checking for duplicated expressions.)
So for instance Product as returned object of F.Prod will need Function objects factor1, factor2 as member fields that are initialized from the constructor arguments. Then the numerical evaluation has to look like (add the usual decorations for a valid function declaration)
evaluate(x) { return factor1.evaluate(x)*factor2.evaluate(x); }
and the symbolic/algorithmic derivative would implement the Leibniz product rule symbolically
differentiate() { return Sum(Product(factor1, factor2.differentiate()), Product(factor1.differentiate(),factor2));
Like said in the comments, the Sine would need one argument Function object in the constructor and stored as member field argument. Then numerical evaluation and symbolic differentiation can look like
evaluate(x) {return Math.sin(argument.evaluate(x)); }
differentiate() { return Product(Cos(argument), argument.differentiate())); }
The last including the inner derivative per the chain rule d/dx(sin(u(x))=cos(u(x))*u'(x).
At the lowest level you need to make a U turn in the evaluation, this can be done sensibly using a VariableX sub-class of Function with
evaluate(x) { return x; }
differentiate { return Constant(1); ]

Access static field of generic type

Can I require classes implementing an interface to have a certain static field or method and access/invoke that field or method through a generic type argument?
I have an interface, Arithmetical<T>, which specifies several functions like T plus(T o) and T times(T o). I have as well a Vector<N extends Arithmetical<N>> class, which is intended for vectors (of variable dimension) with components of type N. I ran into an issue, however, when trying to implement the dot product.
I want to implement the method N dot(Vector<N> o). For this, I plan to start with whatever N's zero is and iterate through both Vector<N>s' List<N>s, adding the product of each pair of elements to my total. Is there a way to specify in Arithmetical<T> that all implementing classes must have a static (and preferably final) field ZERO and start dot(Vector<N> o)'s body with something along the lines of N sum = N.ZERO;?
If not, what other approaches might there be to this problem? I want to allow 0-dimensional vectors, so I can't just begin by multiplying the vectors' first components. Is there a way to instantiate an object of a generic type, so I can merely specify a T zero() method in Arithmetical<T>?
I have a reason for not using Java's numerical types—I want to have vectors with complex components.
Here's Arithmetical:
public interface Arithmetical<T> {
public T plus(T o);
public T minus(T o);
public T negate();
public T times(T o);
public T over(T o);
public T inverse();
// Can I put a line here that requires class Complex (below) to define ZERO?
}
Vector:
public class Vector<N extends Arithmetical<N>> {
private List<N> components;
public Vector<N>(List<N> cs) {
this.components = new ArrayList<N>(cs);
}
public N dot(Vector<N> o) {
// Here's where I need help.
}
}
And Complex:
public class Complex implements Arithmetical<Complex> {
public static final Complex ZERO = new Complex(0, 0); // Can I access this value through N if <N extends Arithmetical<N>>?
private double real;
private double imag;
public Complex(double r, double i) {
this.real = r;
this.imag = i;
}
/* Implementation of Arithmetical<Complex> (and some more stuff) not shown... */
}
I'm quite new to Java (and programming in general); I will likely not understand complex (ha) explanations and workarounds.
Thanks!
(Python is a suggested tag... Huh.)
You need a "zero" for every possible implementation type. A constant in the interface won't do, because a constant cannot be overridden and must remain the same.
The solution is to add a new method to your Arithmetical interface:
public T zero();
Each implementation is forced to implement this and return its own version of zero. In this case, you're using it as a starting point for adding; it's the additive identity.
The Complex class implementation would look like this.
#Override
public Complex zero() {
return ZERO;
}
If your instances are mutable, then don't use a constant; just return new Complex(0, 0).
Another idea is to borrow from what Streams do when reduce-ing items and combining them to one single item -- take an identity value that represents the initial state, i.e. no items collected yet -- zero.
public N dot(Vector<N> o, N identity) {
N dotProduct = identity;
// Perform operations on each item in your collection
// to accumulate and return a dot product.
}
The caller will have to supply the identity value.
Complex dotProduct = vectorOfComplex.dotProduct(otherVector, new Complex(0, 0));
Can I put a line here that requires class Complex (below) to define ZERO?
No. The best you can do is to define an interface, for example:
interface ZeroProvider<A extends Arithmetical<A>> {
A zero();
}
and then supply a compatible instance of that where you need to provide a zero, for example:
class ComplexZeroProvider implements ZeroProvider<Complex> {
public Complex zero() { return new Complex(0, 0); }
}
There's something you can do sometimes using reflection in situations like this. If you put the following method in the Vector class, it will invoke a static method N.zero() (with caveats, below):
protected N zero() {
try {
Type s = getClass().getGenericSuperclass();
#SuppressWarnings("unchecked")
Class<N> n = (Class<N>) ((ParameterizedType) s).getActualTypeArguments()[0];
Method zero = n.getMethod("zero");
return n.cast(zero.invoke(null));
} catch (RuntimeException | ReflectiveOperationException x) {
// probably better to make a custom exception type
throw new IllegalArgumentException("illegal type argument", x);
}
}
However, it's important to understand what this is actually doing. This is getting the type argument from the class file of the direct superclass of this. In other words, there must actually be a superclass of this with an actual type argument (which is a class).
The usual idiom then is that you'd create all of your vectors like this:
new Vector<Complex>() {}
instead of this:
new Vector<Complex>()
Or you'd declare subclasses like this:
public class Vector<N> {
// ...
public static class OfComplex extends Vector<Complex> {
}
}
Since you need an actual superclass with a type argument which is a class, instantiations like in the following examples will fail:
new Vector<Complex>()
new Vector() // never use this anyway
new Vector() {} // never use this anyway
// also, you can't do stuff like this:
public Vector<T> copy() {
return new Vector<T>(this) {};
}
In your case I think the suggestions in the other answers are better, but I wanted to post this answer along with the proper explanation and caveats which are sometimes not included. There are cases where this technique is actually good, mainly when you have pretty tight restrictions on how the class in question is extended. Guava TypeToken will also do some of the reflection for you.
Also, this is the best Java can do at doing exactly what you're asking for (at the moment), so it's worthwhile to point out just as a comparison.

Making Object immutable when passed as parameter

Can I make an Object immutable when passed as a parameter,
so that the called method can't change it but the callee can?
So I have somthing like this:
Class Car {
Wheel wheel_1;
Axis axis = new Axis(wheel_1);
}
Class Wheel {
int size;
setSize(int size) {}
int getSize() {}
}
Now I construct a car with a wheel. Then from class car I want to construct an axis.
For that I pass wheel_1 to the constructor of Axis.
Now my question: Can I asure somehow that the constructor of Axis doesnt change the size of wheel_1 but class car can change it.
Yes. Typically this is done by utilising a copy-constructor for the Wheel class.
For example:
wheel_1 = new Wheel(wheel);
Bear in mind, the Wheel class will need to be written in a way that supports this. That is, it should either offer a copy-constructor.
Note: this hasn't made the object immutable. It has merely produced a copy that can't be edited by anything outside your class.
If you return the Wheel instance from any of your other methods, be sure to defensively copy it on the way out too:
Wheel getWheel() {
return new Wheel(wheel_1);
}
Finally, it's worth mentioning that it's always a good idea to create immutable classes whenever you can. So perhaps you can avoid this issue by actually making Wheel immutable?
Make the Wheel class immutable. Then let the Car object create a new Wheel object when it needs a new size.
public final class Wheel {
private final int size;
public Wheel(int size) {
this.size = size;
}
public int getSize() {
return size;
}
}
Now you can pass the wheel object to the Axis without any problems.
public class Car {
private Wheel wheel;
private Axis axis;
public Car(int initialWheelSize) {
wheel = new Wheel(initialWheelSize);
axis = new Axis(wheel);
}
}
Pass the Axis constructor a copy of wheel_1.
class Car {
Wheel wheel_1;
Axis axis = new Axis(new Wheel(wheel_1));
}
Also, Wheel will need a constructor which takes another Wheel object and copies its properties.
Why don't you send the parameter as its superclass which doesn't have setSize() method
Class Car {
Superwheel wheel_1;
Axis axis = new Axis(wheel_1);
}
class Superwheel
{
int size;
int getSize() {}
}
Class Wheel extends Superwheel{
int size;
setSize(int size) {}
int getSize() {}
}
I would have Wheel implement an interface that has only accessor methods, i.e: -
Example
interface WheelInterface
{
int getSize();
}
class Wheel implements WheelInterface
{
// methods
}
class Axis
{
public Axis(WheelInterface wheel)
{
// Only getSize will be available
}
}
Now, simply pass WheelInterface instead of Wheel and only the accessor methods will be available to the constructor of your Axis class
Benefits
The benefits of doing this is that there is no copying required; you are simply providing a contract to the Axis class and that contract states that it can only get the size, not change it.
By passing the same object reference by value, you aren't having to call any copy constructor and don't have to worry about deep and shallow copying semantics. I would not want to use Clone on my wheel, I think that feels a little dirty for reasons mentioned in comments of other answers.
In an object-oriented pattern, using an interface to abstract away what you don't need is also a sign of good design. If your wheel has snow tyres on, your Axis class probably doesn't even need to care!
Drawbacks
As others have mentioned, it is possible to cast the interface back to a concrete type (as others have mentioned, assuming you know what you're casting to); this is called downcasting and I don't recommend it; if this were done in a similar scenario, it probably wouldn't get past a code review.
Yes, you can. If you make Car and Wheel in the same package and declare Wheel setter fields to be protected. So, Axis if declared in another package can't access setters of Wheel, thus making Wheel immutable from Axis point of view.
Well, this solution is basic to start with. Ofcourse, you can think of whether to make Wheel final or not, cloning, serializable, etc. based on what level you want to make immutable.

Java - array of different objects that have the same method(s)

I am practicing inheritance.
I have two similar classes that I'd like to assimilate into one array, so I thought to use the Object class as a superclass since everything is a sublcass of Object.
So, for example I put T class and CT class into an array called all like so:
Object all[] = new Object[6];
all[0] = T1;
all[1] = CT2;
all[2] =T3;
all[3] = CT1;
all[4] = T2;
all[5] = CT3;
I skipped the declarations as thats not my problem.
My real issue becomes when I wish to call a function within the array utilizing a loop:
for (int i = 0; i < 6; i++) {
all[i].beingShot(randomNum, randomNum, AK47.getAccuracy());
}
The classes involved with T and CT respectively both have the beingShot method, which is public.
Eclipse advises casting them as a quick fix. I'm wondering if there is any logical alternative other than creating my own Object class that holds the beingShot method, or adding this to the class of Object, although I feel either of these choices would cause more problems in the long run.
Thanks!
If both classes implement the same method(s), you should consider creating an interface.
Interfaces are very powerful and easy to use.
You could call your interface Shootable.
You can create an array of different objects that implement Shootable and treat them all the same.
// Define a VERY simple interface with one method.
interface Shootable {
public void beingShot();
}
// Any class that implements this interface can be treated interchangeably
class Revolver implements Shootable {
public void beingShot() {
System.out.println("Revolver: firing 1 round");
}
class MachineGun implements Shootable {
public void beingShot() {
System.out.println("Machine Gun: firing 50 rounds");
}
}
class HockeyPuck implements Shootable {
public void beingShot() {
System.out.println("Hockey Puck: 80 MPH slapshot");
}
}
class RayBourquePuck implements Shootable {
public void beingShot() {
System.out.println("Hockey Puck: 110 MPH slapshot");
}
}
class OunceOfWhiskey implements Shootable {
public void beingShot() {
System.out.println("Whiskey Shot: 1 oz down the hatch...");
}
}
// You can declare an array of objects that implement Shootable
Shootable[] shooters = new Shootable[4];
// You can store any Shootable object in your array:
shooters[0] = new MachineGun();
shooters[1] = new Revolver();
shooters[2] = new HockeyPuck();
shooters[3] = new OunceOfWhiskey();
// A Shootable object can reference any item from the array
Shootable anyShootableItem;
// The same object can to refer to a MachineGun OR a HockeyPuck
anyShootableItem = shooters[0];
anyShootableItem.beingShot();
anyShootableItem = shooters[2];
anyShootableItem.beingShot();
// You can call beingShot on any item from the array without casting
shooters[0].beingShot();
shooters[1].beingShot();
// Let's shoot each object for fun:
for (Shootable s : shooters) {
s.beingShot();
}
Here's a great related question and answer.
Object doesn't have the method beingShot. If all of the objects in array are of the same class, then your array should be of that same class. Otherwise they all should have same interface implemented or extend the same class. I can't imagine why would you want explicitly extend Object here, it doesn't add any functionality whatsoever.
You need to typecast your object references to appropriate class to call their method..
For each reference you fetch from your array, you need to check using instanceof operator, of which is the instance referred to by your object reference.. Accordingly you can typecast the reference to that class..
But Typecasting is an ugly thing.. You should avoid it as far as possible.. If you have to choose which method to invoke based on exact sub class, you should probably go with an Interface.. It is the best way you can achieve what you want here...
And I think you have got enough information about how to implement it..
You cant do it...since Java does not support extension method. (C# does)
READ THE LINK BELOW:
Java equivalent to C# extension methods

When to create a generic class

I haven't used generics before and I am wondering when I should use them and what the advantages are. I think it might be appropriate for a collection that I made since java always uses generics for collections as well but if I call the methods I created the type is already set in the function so it would give an error anyway. When should I use a generic class? Could you give an example because I am not sure how to use it. At the moment my code is as follows:
public class NodeList {
private static final int MAX_AMOUNT_OF_NODES = 12;
private HashMap<String, Node> nodeList;
public NodeList(){
nodeList = new HashMap<String, Node>(MAX_AMOUNT_OF_NODES);
}
public Node get(String id){
return nodeList.get(id);
}
public boolean add(Node node){
if(nodeList.size() <= MAX_AMOUNT_OF_NODES){
nodeList.put(node.id, node);
return true;
}
return false;
}
}
You can look at the existing API for guidance. For example, all the Collections are generic. That is because all collections contain elements of a type.
From that, it makes sense that generic classes should be used when you would have to create the exact same code again and again for different types. If you have to do that, generics might offer you some benefit.
As far as an example, the docs are a good place to start.
From that link, the first code sample is
public class Box<T> {
// T stands for "Type"
private T t;
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
}
Conceptually, there is a Box class that is going to contain something. What it contains does not matter, because the type is specific by the programmer. A Box instance can contain basically anything. When the programmer needs to create a box, he/she specifies the type.
Box<SomeClass> myBox = new Box<SomeClass>();
Think about it this way -- if you wanted to create a general Box that could hold anything without generics, you would have to
1) have the field f be an Object, or
2) create a Box class for every type a box could contain.
With generics, you only need one class, and you can specify the exact type. Maybe if you are doing something and your approach involved either 1 or 2 above, it's better to use generics.
If Node is a class that can hold a piece of data with certain type (like String, for example) then you should generify Node and subsequently NodeList to prevent type errors.
If you don't, then you leave it up to the user of your NodeList to ensure that she never adds an Integer when the list is only supposed to hold Strings. Generics is primarily about catching type problems at compile time rather than runtime.
It's pretty simple to do so, change something like this:
public class Node {
Object data;
//...
}
to something like this:
public class Node<T> {
T data;
//...
}
public class NodeList<T> {
public Node<T> get(String id) {
//...
}
public boolean add(Node<T> node) {
//...
}
}
Your NodeList looks like it could potentially have a second type parameter for the key type, which right now you're constraining to String.
You can generically type the methods arguments as well as the class itself. Here's an example from Java's java.util.List interface:
public interface List<E> {
//...
boolean add(E e);
//...
}
Generics are a way for Java to force a collection data structure (HashMap in your case) to accept only a specific types of objects. This means that at compile time, if you tried something like:
nodeList.add(1, new Node());
it would fail and not compile since 1 is not a String object. It is generally a way to write tidier code.
Check this link as well:http://en.wikipedia.org/wiki/Generics_in_Java

Categories

Resources