Use Object class to achieve polymorphism in math operations - java

I want to make good use of polymorphism in java when implementing math operations between objects of math classes.
I got from the answers in How to add two java.lang.Numbers?
that the general solution when using java.lang.Number is to know or check the real objects class and make the appropriate hardcoded conversion to float, int, etc.
But this approach actually is not very object oriented. The java language designers chose to give the java.lang.Number class and its derivatives a set of methods floatValue(), intValue() and so on.
In light of this, Is my proposed approach, below, not going to work?.
To implement mathematical operations in a seamless way I want to to rewrite the Number class Hierarchy to allow to do something like this:
MyNumber a = b.getValue() + c.getValue();
where the real type of b and c don't matter
The base class would be:
public abstract class MyNumber {
protected Object mValue;
public abstract <N> N getValue();
}
And, for example, my integer class would look like:
public class MyInteger extends MyNumber {
public MyInteger(int value) {
mValue = value;
}
#Override
public Integer getValue() {
return (Integer) mValue;
}
}
and similarly for MyFloat, MyDouble, etc.

It will not work with different types.
public class MyInteger extends MyNumber {
public MyInteger(int value) {
mValue = value;
}
#Override
public Integer getValue() {
return (Integer) mValue;
}
}
public class MyFloat extends MyNumber {
public MyFloat(float value) {
mValue = value;
}
#Override
public Float getValue() { // first issue: types don't match. can't override
return (float) mValue; // second issue: type won't match with other getValue methods, arithmetic will fail
}
}
Your problem is even before the arithmetic. You'll need to use generics, or some kind of type-resolving and/or type-converting mechanis to get past this issue.
Firstly, overriding methods need to have matching signatures, and Types are part of that signature.
Secondly, after having a single type, Java does not have operator overloading. Therefore you will need to implement a method that MyNumber has that can take your two Generic or high level Object's and do that type casting or conversion itself.

Related

Comparator (int) in inner class

I have some problem with comparator. I make very simple class with 2 fields and i need make inner classes with comparators for this two fields.
public class KlassA {
private int i;
private String tekst;
public int getI(){
return i;
This comparator works ok.
public static class KomparatorText implements Comparator<KlassA>{
public int compare(KlassA a1, KlassA a2) {
return a1.getTekst().compareTo(a2.getTekst());
}
}
In this comparator i have some issue: "Cannot invoke compareTo(int) on the primitive type int"
public static class KomparatorI implements Comparator<KlassA>{
public int compare(KlassA a1, KlassA a2) {
return a1.getI().compareTo(a2.getI());
}
}
I also try CompareTo but then i need to implements field or method and it's not work
public static class KomparatorI implements Comparable<KlassA>{
private int i = this.i;
public int compareTo(KlassA o) {
if (this.i < o.i)
return -1;
else if (this.getI() == o.getI())
return 0;
else
return 1;
}
}
}
I really don't know how to fix it. I'm already serach the other inquiries but all sollutions don't work for my example. Pls help.
You could force everything to Integers as in the other answers, but, IMO, better to keep your current class structure with ints and to use a built in method, Integer.compare()
public static class KomparatorI implements Comparator<KlassA>{
public int compare(KlassA a1, KlassA a2) {
return Integer.compare(a1.getI(), a2.getI());
}
}
Likewise, if you wish to use Comparable instead, use it to save typing (and avoid mistakes in the logic):
public static class KomparatorI implements Comparable<KlassA>{
public int compareTo(KlassA o) {
return Integer.compare(this.i, o.i);
}
}
In Java, primitive types like int, float, or boolean are not objects like the correspondent Integer, Float, or Boolean.This means you cannot call methods on them.
Try using,
Integer.valueOf(this.i).compareTo(o.i);
Your confusion probably comes from the fact that the compiler tries to covert primitive types to their corresponding object classes automatically. In the sample above this happens for the argument o.i, which is converted automatically to an Integer.
Try searching for "java autoboxing".
Note: You can actually use Integer.compare(this.i, o.i) which is better, for that case.
Lets see what you gout here
a1.getI().compareTo(a2.getI());
it looks like getI() returns int insteed of Integer.
Change mehod definition to return Integer insteed and all wil be fine. So inside your KlaasA
public Integer getI(){ return i};

Declare enum without specify values, something like abstract

I have an abstract class (or an interface). In this class I want to define an enum, in order to force classes that extend this abstract class (or implement this interface) to declare an enum with the same name.
abstract class Operator {
public abstract enum Symbol;
public Symbol value;
}
class Binary extends Operator {
public enum Symbol {
pls,
min,
mul,
div,
//...
}
}
class Unary extends Operator {
public enum Symbol {
sin,
cos,
tan,
cot,
//...
}
}
Assume I can't know the values of sub classes enums. I want that every extending class had an enum with that name and its values. I want to use enums (especially because it's easy to switch enums)
There's no way to do this thing and moreover, even if it were, how would you call the subclass' implementation? I mean, only method calls can be virtual, ie dispatched at runtime. Types can not, so without cheating with reflection (which throws away any type safety anyhow, so that you don't even need to subclass), you would not be able to call the overridden type (in fact, types can't be overridden).
Maybe you can still achive your objectives by using composition:
public abstract class Operator<T extends Enum<T>> {
public final Class<T> symbol;
public Operator(Class<T> symbol) { this.symbol = symbol; }
}
public enum BinarySymbol { PLS, MIN, MUL, DIV }
public class Binary extends Operator<BinarySymbol> {
public Binary(Object operand1, Object operand2, BinarySymbol symbol) {
super(symbol);
}
}
Your base class Operator can dynamically read the enumerated values through reflection, via Class.getEnumConstants()
You can't enforce it at compile time. One way would be to use reflection at runtime to see if the class has been implemented correctly. I don't suggest this, but it's possible.
What you can do is have enums that implement a common interface, and then utilize those interfaces:
public interface YourEnumInterface<E extends Enum<E> & YourEnumInterface<E>> {
//methods that your enum should be implementing
}
The extension for the interface generic declaration is there to guarantee it is only called by enums that implement your interface
And then any enum you have to specify can implement it like so:
public enum MyEnum implements YourEnumInterface<MyEnum> {
// enum constants
TEST_VALUE;
// implementation of interface methods
}
From there, you would simply work with the YourEnumInterface as an object, and you can pass enum values for them:
public void doSomething(YourEnumInterface enm) {
//work with enm
}
//Elsewheres...
doSomething(MyEnum.TEST_VALUE);
It should be noted, that once you lower your enum down to the interface itself, you won't be able to change the constant you are working with (without casting, which can potentially be unsafe). This should really be used more or less for passing things to a destination that just works with the values (like a config enum, or internalization of strings, etc)
So in relevance to forcing a subclass to implement it:
public class YourSuperClass {
public abstract YourEnumInterface symbol;
}
A runnable example
public class EnumMagic {
public static void main(String[] args) {
YourSubClass clazz = new YourSubClass();
//prints the default value
System.out.println(clazz.getEnum().getValue());
//gets the value of a specified enum constant
System.out.println(clazz.getEnum().SECOND_TEST.getValue());
}
}
abstract class YourSuperClass {
protected YourEnumInterface symbol;
public abstract YourEnumInterface getEnum();
}
interface YourEnumInterface<E extends Enum<E> & YourEnumInterface<E>> {
public int getValue();
}
class YourSubClass extends YourSuperClass {
public enum MyEnum implements YourEnumInterface<MyEnum> {
TEST_VALUE(1),
SECOND_TEST(2);
private final int val;
private MyEnum(int example) {
this.val = example;
}
public int getValue() {
return this.val;
}
}
public YourSubClass() {
this.symbol = MyEnum.TEST_VALUE;
}
public MyEnum getEnum() {
return MyEnum.TEST_VALUE;
}
}
The output of this progam is:
1
2
And you can simply get the class' specified enum constant via getEnum, which they will return their own internal enum.
However, once downcasted to the super type, e.g. YourSuperClass intc = clazz;, then you will lose this ability to specify the enum itself. Depending on how you store your instances will determine whether or not this requires changes.

NullObjectPattern and the Comparable interface

The problem I'm having has already been asked before: How to implement an interface with an enum, where the interface extends Comparable?
However, none of the solutions solve my exact problem, which is this:
I have a value object, similar to BigDecimal. Sometimes this value will not be set with a real object, because that value is not yet known. So I want to use the Null Object Pattern to represent the times this object is not defined. This is all not a problem, until I try to make my Null Object implement the Comparable interface. Here's an SSCCE to illustrate:
public class ComparableEnumHarness {
public static interface Foo extends Comparable<Foo> {
int getValue();
}
public static class VerySimpleFoo implements Foo {
private final int value;
public VerySimpleFoo(int value) {
this.value = value;
}
#Override
public int compareTo(Foo f) {
return Integer.valueOf(value).compareTo(f.getValue());
}
#Override
public int getValue() {
return value;
}
}
// Error is in the following line:
// The interface Comparable cannot be implemented more than once with different arguments:
// Comparable<ComparableEnumHarness.NullFoo> and Comparable<ComparableEnumHarness.Foo>
public static enum NullFoo implements Foo {
INSTANCE;
#Override
public int compareTo(Foo f) {
return f == this ? 0 : -1; // NullFoo is less than everything except itself
}
#Override
public int getValue() {
return Integer.MIN_VALUE;
}
}
}
Other concerns:
In the real example, there are multiple subclasses of what I'm calling Foo here.
I could probably work around this by having NullFoo not be an enum, but then I can't guarantee there is ever only exactly one instance of it, i.e. Effective Java Item 3, pg. 17-18
I don't recommend the NullObject pattern because I always find myself in one of these 2 situations:
it does not make sense to use NullObject like an object, and it should stay null
NullObject has too much meaning to be just a NullObject, and should be a true object itself (for instance, when it acts like a fully functional default value)
According to our discussion in the comments, it seems to me that your NullObject behaves very much like the 0 value of your normal objects.
What I would do is actually use 0 (or whatever default value makes more sense), and put a flag if you really need to know whether it has been initialized. This way, you will have 2 things to consider:
all uninitialized values won't share the same instance with my solution
for the very same reason, you are now able to initialize your object later without having to create a new instance
Here is the kind of code I think of:
public static class VerySimpleFoo implements Foo {
private int value;
private boolean initialized;
public VerySimpleFoo() {
this.value = 0; // whatever default value makes more sense
this.initialized = false;
}
public VerySimpleFoo(int value) {
this.value = value;
this.initialized = true;
}
#Override
public int compareTo(Foo f) {
// possibly need some distinction here, depending on your default value
// and the behavior you expect
return Integer.valueOf(value).compareTo(f.getValue());
}
#Override
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
this.initialized = true;
}
public boolean isInitialized() {
return initialized;
}
}
As you suggested, I believe one solution would be to use a class instead of an enum:
public class NullFoo implements Foo {
private NullFoo() {
}
public static final Foo INSTANCE = new NullFoo();
#Override
public int compareTo(Foo f) {
return f == this ? 0 : -1;
}
#Override
public int getValue() {
return 0;
}
}
This mimics an enum behavior, but it allows you to implement your Foo interface. The class is not instantiable because of the private constructor, so the only instance available is the one accessible via NullFoo.INSTANCE, which is thread-safe (thanks to the final modifier).
The thing is that Enum already implements Comparable natively, and since the generics are just a sugar code, and lost after compilation, effectively you want to implement the same method twice for the same interface.
I would drop enum, for NullFoo, converting it to class (like you suggested), and make final public static INSTANCE reference with private constructor, (This is not as good as using an enum, but acceptable, in most cases).

How can I define a template class by constraining the set of allowed types, and reference a Collection of these in Java?

I am defining the following class:
public class Foo<T> {
T _value;
public T getValue() {
return T;
public void setValue(T value) {
_value = value;
}
}
T should only be of type int, char, or double.
I want to be able to reference a collection of these, such as:
interface IBar {
Collection<Foo> getAllFoo();
}
Obviously, this doesn't work since I'd need to specify the type T with this reference. So, I need to define some abstract base class that I can use instead.
The question is, how can I enforce that all derived types implement the getValue() and setValue() functions? I know I can define them in the abstract base as abstract methods returning / accepting an Object, but that doesn't provide type safety on the 3 accepted primitives.
Is there a better way to define a collection of these, and is there a way to enforce T being either int, char, or double?
You're better off creating concrete implementations for each type you care about.
interface Foo<T>{
public T getValue();
public void setValue(T value);
}
class IntFoo implements Foo<Integer>{...}
class CharFoo implements Foo<Character>{...}
class DoubleFoo implements Foo<Double>{...}
interface Bar{
Collection<Foo<?>> getAllFoo();
}
The ? allows the collection to contain any type of Foo object. You still lose the generic type when you reference a Foo<?>, but there's no good way around that.
Other than having the common base class, there really is no advantage of doing this. If you had some common ground each Foo could resolve to, then I would do this:
abstract class Foo<T>{
T value;
T getValue(){
return value;
}
void setValue(T value){
this.value=value;
}
// return whatever is appropriate for all implementations
abstract Object baz();
}
class IntFoo implements Foo<Integer>{
Object baz(){
return null // something useful;
}
}
Collection<Foo<?>> foos = bar.getAllFoo();
for(Foo<?> foo:foos){
foo.baz();
}
public class Foo<T>
private Foo(){} // only nested classes can access
static public class Int extends Foo<Integer>{}
static public class Char extends Foo<Character>{}
static public class Double extends Foo<Double>{}
public class MyIntFoo extends Foo.Int // MyIntFoo is a Foo<Integer>
There is no way to create a subclass of Foo whose T is not one of Integer/Character/Double. If the 3 nested classes are final, then they are the only subclasses of Foo.
We still can't prevent a Foo<Float> type declaration. But at least you know such an object cannot be instantiated.

Java Type Erasure Problem

I've made an example to demonstrate my problem:
Metrical.java
public interface Metrical<T>
{
double distance(T other);
}
Widget.java
public class Widget implements Metrical<Widget>
{
private final double value;
public Widget(double value) { this.value = value; }
public double getValue() { return value; }
public double distance(Widget other) { return Math.abs(getValue() - other.getValue()); }
}
Pair.java
public class Pair<T>
{
private final double value;
private final T object1, object2;
public Pair(T object1, T object2, double value)
{
this.object1 = object1;
this.object2 = object2;
this.value = value;
}
public T getObject1() { return object1; }
public T getObject2() { return object2; }
public double getValue() { return value; }
}
Algorithm.java
import java.util.Set;
public class Algorithm<T extends Metrical<T>>
{
public void compute(Set<T> objects)
{
}
public void compute(Set<Pair<T>> pairs)
{
}
}
So, in Algorithm.java, Set< Pair< T >> is being seen as a Set< T > and thus I am having type erasure problems. However, is there any way I can get away with something like this without naming the methods differently? Both variants of the algorithm are meant to operate on T's, but I need to allow for different arguments. They compute the same thing, so in an effort to avoid confusion, I would rather not name them differently. Is there any way to accommodate this?
No there isn't.
You have to remember that someone could call your method with just a vanilla Set, in which case which one would be called?
That's why you can't do it. Just like you can't do:
interface A {
void blah(Set set);
void blah(Set<T> set);
}
Same problem.
The type information isn't available at runtime (ie type erasure).
Sorry, the bad news is that you cannot do this:
public class Algorithm<T extends Metrical<T>> {
public void compute(Set<T> objects) {
}
public void compute(Set<Pair<T>> pairs) {
}
}
Due to erasure, both will erase to the same signature. There is no way around this short of renaming one of the methods.
Sadly, this is the major area where Java Generics falls down... there is just no good solution.
I've generally resorted to making a new class, with the interface as Set<Pair<T>>, but that wraps Set<Pair<T>> (without extending it, which would cause the same problem).
I've written an article about type erasure which can be of your interest.
It gives the common widely known solution and also a tricky way to circumvent the problem.
I don't know if it will be relevant for you. Anyway, it contains some techniques which may be useful under certain circumstances.
See also: Using TypeTokens to retrieve generic parameters
I hope it helps.
Use public class Widget<K, P> implements Metrical<K extends Widget<P>>.
public double distance(Widget other) {} becomes public double distance(Widget<P> other) {}

Categories