This isn't exactly the definition of implicit type conversion, but I'm curious how many standards I'm breaking with this one...
I'm creating an abstract class in Java that basically casts its variables depending on a string passed into the constructor.
For example:
public abstract class MyClass {
Object that;
public MyClass(String input){
if("test1".equals(input){
that = new Test1();
}
else{
that = new Test();
}
}
public void doSomething(){
if(that instanceof Test1){
//specific test1 method or variable
} else if(that instanceof Test2)}
//specific test2 method or variable
} else {
//something horrible happened
}
}
}
You see what I'm getting at? Now the problem I run into is that my compiler wants me to explicitly cast that into Test1 or Test2 in the doSomething method - which I understand, as the compiler won't assume that it's a certain object type even though the if statements pretty much guarantee the type.
I guess what I'm getting at is, is this a valid solution?
I have other classes that all basically do the same thing but use two different libraries depending on a simple difference and figure this class can help me easily track and make changes to all of those other objects.
You are right. This is a horrible way to achieve polymorphism in design. Have you considered using a factory? A strategy object? It sounds like what you are trying to achieve can be implemented in a more loosely-coupled way using a combination of these patterns (and perhaps others).
For the polymorphism of doSomething, for example:
interface Thing {
public void doThing();
}
class Test1 implements Thing {
public void doThing() {
// specific Test1 behavior
}
}
class Test2 implements Thing {
public void doThing() {
// specific Test2 behavior
}
}
class MyClass {
Thing _thing;
public void doSomething() {
_thing.doThing(); // a proper polymorphism will take care of the dispatch,
// effectively eliminating usage of `instanceof`
}
}
Of course, you need to unify the behaviors of Test1 and Test2 (and other concrete Thing classes, present and planned) under a set of common interface(s).
PS: This design is commonly known as Strategy Pattern.
I would create a separate class file. So you would have something like this:
1. You abstract "MyClass"
->within "MyClass" define an abstract method call doSomething...this will force the specific implementation of the method to it's subclasses.
2. Test1 would be the implementation of MyClass which would contain the implementation of the doSomething method
3. Create a utility class that does the check "instanceOf" that check should not be in the constructor it belongs in another class.
So in the end you would have 3 class files an Abstract Class, Implementation of the Abstract and a Class that does the "instanceOf" check. I know this sounds like a lot but it's the proper way to design, for what I think you are attempting to do. You should pick up a design patterns book, I think it would help you a lot with questions like these.
The Open-Closed principle would be better satisfied by moving the object creation outside of this class.
Consider changing the constructor to accept an object that implements an interface.
public MyClass {
public MyClass( ITest tester ) { m_tester = tester; }
public void doSomething(){ m_tester.doTest(); }
}
This makes it possible to change the behavior of the class (open to extension) without modifying its code (closed to modification).
The better way to do this is to create an interface which will specify a set of methods that can be guaranteed to be called on the object.
Here's an example:
public interface TestInterface
{
void doTest();
}
Now you can write your classes to implement this interface. This means that you need to provide a full definition for all methods in the interface, in this case doTest().
public class Test implements TestInterface
{
public void doTest()
{
// do Test-specific stuff
}
}
public class Test1 implements TestInterface
{
public void doTest()
{
// do Test1-specific stuff
}
}
Looks really boring and pointless, right? Lots of extra work, I hear you say.
The true value comes in the calling code...
public abstract class MyObject
{
Test that;
// [...]
public void doSomething()
{
that.doTest();
}
}
No if statements, no instanceof, no ugly blocks, nothing. That's all moved to the class definitions, in the common interface method(s) (again, here that is doTest()).
Related
I am working on creating a java utils library and have come across a problem with generics. I have found a solution that lets the library work, but it seems like bad code practice and prone to undetected program failures. For question's sake, I've simplified the program into a minimum verifiable example.
Let's say I have an interface Invokable<E>, which is called upon to effect an E.
public interface Invokable<E> {
void invoke(E e);
}
Let's say I have another interface, InvokableFactory<E>, which creates Invokable<E>s
public interface InvokableFactory<E> {
Invokable<E> create();
}
Now let's say I have a class InvokableUser<E>, that is designed to be extended. It holds an InvokableFactory<E>, and uses it to create an Invokable<E>, which it then invokes with itself.
public class InvokableUser<E> {
private InvokableFactory<E> factory;
public InvokableUser(InvokableFactory<E> factory) {
this.factory = factory;
}
public void start() {
factory.create().invoke((E) this);
}
}
You might see that my conundrum is that I'm trying to ensure that a subclass InvokableUser, extends InvokableUser of the generic type of itself. I'm trying to ensure that an InvokableUser contains a factory that produces Invokables that can be invoked with the InvokableUser object, but still be passed an object of the type of the subclass of InvokableUser so that the Invokable can utilize methods added only by the subclass of InvokableUser.
I feel like I might not be explaining this very well, so for example, let's say there's a subclass of Invokable that needs to print out the getString method added by a subclass of InvokableUser, like this:
public class PrintingInvokable implements Invokable<PrintingInvokableUser> {
#Override
public void invoke(PrintingInvokableUser e) {
System.out.println(e.getString());
}
}
public class PrintingInvokableUser extends InvokableUser<PrintingInvokableUser> {
public PrintingInvokableUser() {
super(PrintingInvokable::new);
}
public String getString() {
return "( ͡° ͜ʖ ͡°)";
}
}
If you create a new PrintingInvokableUser() and call start() on it, it will create a new PrintingInvokable() and call invoke(this) on it, when will then print out the getString() method of the PrintingInvokableUser.
While my code does work for this, it depends on the unwritten expectation that a subclass Foo of InvokableUser will extend InvokableUser<Foo>, involves an unchecked cast which is bad (and raises a compiler warning), seems to not even make use of the generic type as I could achieve the same effect with unparametrized types, and generally seems like there has to be a better way to do this.
If someone could point me in the right direction for how to do this, I'd be appreciative. Thanks!
It's hard to explain, but it's simple to show a snippet of Ruby code:
Have two modules that implement methods:
module Foo
def one
print "ONE!"
end
end
module Bar
def two
print "TWO!"
end
end
Have a class that includes them:
class Test
include Foo
include Bar
end
Now your class Test can call those two methods.
As far as I'm aware, there isn't something like this in Java. Close concepts would be:
Multiple inheritance
Which is not supported by Java.
Interfaces
They're method contracts - there is no implementation. Your class Test would need to implement the methods itself, and that's what I want to avoid. Simply for the sake of not writing the same code twice (I have several other classes, some of them may want to implement those methods too).
Abstract classes
I'd still need to inherit from two classes at the same time.
So what is the recommended solution here?
In Java 8 you could achieve this using default methods but that was never the intent of defaults so this may be bad advice:
interface Foo {
default void one () {
System.out.println("ONE!");
}
}
interface Bar {
default void two () {
System.out.println("TWO!");
}
}
class FooBar implements Foo, Bar {
}
public void test() {
FooBar fooBar = new FooBar();
fooBar.one();
fooBar.two();
}
However, I would like to reiterate what #Thomas said in his comment The need for multiple inheritance is often a sign of a flaw in the design.
The easiest solution is to create hierarchical inheritance as so :
public class foo
{
public void one()
{
System.out.println("ONE!");
}
}
public class bar extends foo
{
public void two()
{
System.out.println("TWO!");
}
}
class Test extends bar
{
//this class now has access to both methods from the two classes
}
Favour composition over inheritance. So your class would have references to both implementing classes.
MyClass {
ClassA
ClassB
}
Th alternative of subclassing twice, seems rather hacky to me and would lead to an unnecessarily complex inheritance tree.
Or with java 8's new static methods (as opposed to default which can be overridden). See comparator for examples.
interface X
{
static void foo()
{
System.out.println("foo");
}
}
interface Y
{
static void bar()
{
System.out.println("bar");
}
}
MyClass implements X, Y {
public static void main(String args[])
X.foo();
}
The interface name must be used as prefix, as static method is part of interface.
There are few solutions that might solve your case. You can use the Visitor Pattern or Strategy Pattern.
In both cases you will benefit from Interfaces and Composition.
Your class Test would need to implement the methods itself, and that's what I want to avoid.
Well, yes, but that "implementation" could just be a simple delegation (and your IDE can create the code for this wrapper automatically).
public String one(){
return foo.one();
}
The actual code can be in class Foo, and be shared (as in "used") among many classes.
As you may know, some people are declaring singletons with an Enum of 1 instance, because the JVM guarantees that there will always be a single instance with no concurrency problems to handle...
Thus what about an Enum with multiple instances?
Can we say something like an Enum is a kind of ordered set of singletons sharing a common interface?
Why?
public enum EnumPriceType {
WITH_TAXES {
#Override
public float getPrice(float input) {
return input*1.20f;
}
public String getFormattedPrice(float input) {
return input*1.20f + " €";
}
},
WITHOUT_TAXES {
#Override
public float getPrice(float input) {
return input;
}
},
;
public abstract float getPrice(float input);
public static void main(String[] args) {
WITH_TAXES.getFormattedPrice(33f);
}
}
In this code why this doesn't work:
WITH_TAXES.getFormattedPrice(33f);
What is the interest of declaring a public method if it can't be called without passing through the common interface?
I guess this is why i don't see any syntax to be able to declare an interface just for one of the instances of an Enum.
Edit:
It seems that enum instances are a special kind of anonymous classes.
Thus i understand why you can't call that method.
My question is kinda related to: why can't an anonymous class implement an interface (in addition to the interface it may already implement!)
I totally understand why we CANT do that:
Vehicle veh = new Vehicle() {
public String getName() {
return "toto";
}
};
veh.getName();
(getName here is not an override)
Why i don't understand is why we can't do that with anonymous classes:
Runnable veh = new Vehicle() implements Runnable {
#Override
public void run() {
System.out.println("i run!");
}
};
veh.run();
Or something that would result in the same thing.
Think about it: if you do not use anonymous classes you can absolutely extend the Vehicle class and then make that subclass implement any other interfaces you want...
I'm pretty sure that if it was possible we would be able to call WITH_TAXES.getFormattedPrice(33f) in a typesafe way, since WITH_TAXES would not be a real EnumPriceType but it would but a subclass of EnumPriceType, with its own interface, and by calling WITH_TAXES.getFormattedPrice(33f) with a hardcoded WITH_TAXES, you know at compile that which EnumPriceType child you are calling.
So my question is: are there any reasons why this is not possible? Or it just haven't be done yet?
Your enum is equivalent to the following normal class (in fact, that's pretty much what the compiler turns it into):
public abstract class EnumPriceType {
public static final EnumPriceType WITH_TAXES = new EnumPriceType() {
//getPrice() {...}
//getFormattedPrice() {...}
};
public static final EnumPriceType WITHOUT_TAXES = new EnumPriceType() {
//getPrice() {...}
};
public abstract float getPrice(float input);
public static void main(String[] args) {
WITH_TAXES.getFormattedPrice(33f);
}
}
The getFormattedPrice() method is unavailable on the abstract type, and therefore can't be called from the main method. Consider what would happen if the main method is rewritten to use a local variable:
public static void main(String[] args) {
EnumPriceType foo = EnumPriceType.WITH_TAXES;
foo.getFormattedPrice(33f);
}
This doesn't compile because getFormattedPrice() is not available on the base class. Since the WITH_TAXES instance is an anonymous subclass of EnumPriceType, there's no way you can define the local variable to a type where the getFormattedPrice() method is visible.
As a meta observation, this is a key difference between strongly typed languages such as Java and "duck typed" languages such as Ruby. Ruby will happily invoke the getFormattedPrice() method if happens to be there, regardless of what type of object is held in the foo variable.
As another meta observation, it doesn't make much sense for different constants of the same enum to have different sets methods. If you can't put everything you need as abstract (or concrete) methods on the base enum type, you're probably using the wrong tool to solve the problem.
Add
public String getFormattedPrice(float input) {
return input + " €";
}
outside the overrides as the default implementation. (Next to the declaration of getPrice.) And you are good to go.
You can also have enums implement interfaces, to define what everybody needs to implement.
Thus what about an Enum with multiple instances?
There is no such thing, and your example doesn't demonstrate it. You have an Enum with multiple values. They are all singletons.
First things first, please be aware I am trying to express my question as best I can with my current knowledge and vocabulary, so please excuse this...
I have an abstract class in which I want to make a method where it instantiates itself.... Of course this is impossible in an abstract class, however, what I really want is for the concrete children (those classes that "extends") to inherit this instantiation so that they then can instantiate themselves....
Basically what I want to do is this:
MyAbstract a = new this();
However this isn't allowed... Is there any way I can do what I want?
Here is some non-compiling dream-code (i.e. code I wish worked). Basically I am wanting the ConcreteChild to call a method in which it create an object of itself. The method is inherited from it's parent.
public class Abstract {
public void instantiateMyConcreteChild()
{
Abstract a = new this();
}
}
public class ConcreteChild extends Abstract{
public static void main(String[] args) {
ConcreteChild c = new ConcreteChild();
c.instantiateMyConcreteChild();
}
}
* Additional info **
Thanks for the replies but I think I missed something vital....
Basically I wanted to pass an object's self ( "this" ) into some methods of some other classes. However, creating instantiating another object within an object is a bit backwards, I can just pass "this", right...
You can do this using reflection, something like :
Abstract a = getClass().newInstance();
This is because getClass() always returns the concrete class, so this.getClass() will return the real subclass and not the current class.
However, beware that if the subclass defines a custom constructor, having more or less parameters than your abstract class, it could fail. Unless you specify in the documentation that subclasses must have a constructor with such given parameters ... but it's fragile anyway.
You can inspect it, using getClass().getConstructors() and see which constructors are there, and if there is the one you are expecting, or even search for a viable one, otherwise you can catch the exception thrown by newInstance(..), and wrap it in a more descriptive exception for the users, so that they understand better what they missed ... but it would still be a kind of a hack, cause there is no explicit language support for such a situation.
Another approach could be to implement Cloneable in your abstract class, and then use the clone method, but it could be overkill or even wrong if what you want is a new, clean instance.
You can't do this using an instance method. Because as the name implies an instance methods requires that the instance has already instantiated.
What you actually need to do here is to separate the non-changing internal functionality from the abstract class itself. So what I could do is to ,for e.g., have an inner class that really encapsulates the non-changing functionality like so:
public class Abstract {
public void instantiateMyConcreteChild()
{
Abstract a = new NonChangingOperations();
}
class NonChangingOperations
{
public void operationA() {}
}
}
Infact you really dont need to keep the class NonChangingOperations as an inner class, you could make it as an external utility class with its own class hierarchy.
Are you trying to define a constructor that the subclasses of Abstract can use? If so you could simply do it the same way you define any other constructor.
public class Abstract {
Abstract() {
//set fields, etc. whatever you need to do
}
}
public class ConcreteChild extends Abstract{
ConcreteChild() {
//call superclass's constructor
super();
}
}
Could you just have this ?
public abstract class AbstractClassWithConstructor {
public AbstractClassWithConstructor() {
init();
}
protected abstract void init();
}
FYI
In the objective-c you need to set this by calling method init. The the method init() would look like this:
protected AbstractClassWithConstructor init() {
return this;
}
I'm writing an app that has a few classes which represent things that are in a World.
The World is represented by an array of objects (of the class from which all classes of objects that exist in the world inherit - lets call it Thing).
class World {
Thing[] myObjects;
}
class Thing {}
class AAA extends Thing {}
class BBB extends Thing {}
At some point I need to know if an object at a given position is of a given type.
I have some solutions and would like to discuss the merits of each with people who are familiar with Java's object model, since I'm used to a different object model than Java's (CLOS).
Solution #1
Define methods isAThingAAA(obj) and isAThingBBB(obj) in the World class.
These methods would call obj.getClass () and check if the returned type is AAA or BBB.
The problem I see with this is having to use "getClass" to implement it. Or is there another way to implement it?
Solution #2
Define methods isAnAAA () and isAnBBB () in the Thing class, implemented to return false. Redefine them in the respective class (AAA.isAnAAA and BBB.isAnBBB) to return true.
This sesms strange because the most abstract class would have knowledge of the existance of its subclasses.
Other suggestions?
Thanks in advance.
How about writing an abstract method in class Thing, and then letting AAA's instances and BBB's instances redefine it. You seem to want to write the isAnXXX methods, maybe you could explain why.
See, using the instance of operator and isAnXXX methods can lead to no polymorphism. And that is not a good thing. You WANT polymorphism, you needs it...gollum,gollum. Also, consider that tomorrow you want to add a CCC class to your World. Your design should guarantee that the World class won't be touched, as in the Open/closed principle
So , summing up, you could do this:
In class Thing:
public abstract class Thing{
abstract void doSomething();
}
Then override it in child classes
public class AAA extends Thing{
#override
public void doSomething(){ /*do something in AAAs way*/}
}
public class BBB extends Thing{
#override
public void doSomething(){ /*do something in BBBs way*/}
}
Then you could fill your Thing[] and do this
for (Thing t:myOBjects){
t.doSomething()
}
Each instance of Thing knows how to doSomething, without having to ask for its type.
Another option is to not have these methods at all. These methods are often used to decide what to do. Something like
if(thing is a AAA) {
((AAA) thing).method();
} else if (thing is a BBB) {
((BBB) thing).method();
}
instead it is better for each Thing to know what to do when an action is required. All you should have to call is
thing.method(); // each type know what to do.
You should use instanceof operator
AAA aaa = new AAA();
if(aaa instanceof AAA) {
//do something different
}
EDIT: also Tom's answer should suffice to solve your problem and that is the good practice.
you can use instanceof or isInstance http://download.oracle.com/javase/6/docs/api/java/lang/Class.html#isInstance%28java.lang.Object%29
class World {
Thing[] myObjects;
}
class Thing {}
class AAA extends Thing {}
class BBB extends Thing {}
public class Main {
public static void main(String[] args) {
Thing[] things={new AAA(),new BBB()};
for(Thing thing:things)
if(thing instanceof AAA)
System.out.println("i am an AAA");
else if(thing instanceof BBB)
System.out.println("i am a BBB");
}
}
The simplest way would be to use Java's built-in instanceof operator. For example:
public boolean isAAA(Thing myThing)
{
return myThing instanceof AAA;
}
Many people, however, would tell you that using instanceof is symptomatic of poor class design, and that the proper way to achieve different behavior with different subclasses is through polymorphism. The problem here is that it it's very easy in Java to get a class to do something different based on what derived type it is, but it's a bit tricky getting some other object to treat a Thing differently depending upon what derived type it has a handle on. This is the Double Dispatch problem.
It would be ideal if, when handling your Thing object, you could just dispatch the problem to some other methods that would do different things with the Thing depending on what subclass it is, like so:
public void handleThing(Thing myThing)
{
reactToThing(myThing);
}
public void reactToThing(AAA myThing)
{
// Do stuff specific for AAA
}
public void reactToThing(BBB myThing)
{
// Do stuff specific for BBB
}
public void reactToThing(Thing myThing)
{
// Do stuff for generic Thing
}
In Java, however, which only supports single dispatch, regardless of the actual type of myThing in handleThing(), reactToThing(Thing) will always get called, and you'll never get your unique behavior.
What you need to do to get around this problem is use the Visitor Pattern. This just involves putting some extra code in your Thing class and all its children to give your reactToThing() methods some extra context. So let's say the above methods are all in a class called Visitor. We can rewrite the above to work by first handing the problem off to the Thing object itself, then polymorphism will give us an appropriate context (Thing, AAA, or BBB) for the object to give back to the Visitor.
So, we can rewrite the example above as follows:
public class Visitor
{
// ...
public void handleThing(Thing myThing)
{
myThing.accept(this);
}
public void reactToThing(AAA myThing)
{
// Do stuff specific for AAA
}
public void reactToThing(BBB myThing)
{
// Do stuff specific for BBB
}
public void reactToThing(Thing myThing)
{
// Do stuff for generic Thing
}
}
public class Thing
{
// ...
public void accept(Visitor visitor)
{
visitor.reactToThing(this);
}
}
public class AAA
{
// ...
public void accept(Visitor visitor)
{
visitor.reactToThing(this);
}
}
public class BBB
{
// ...
public void accept(Visitor visitor)
{
visitor.reactToThing(this);
}
}
So why did I need to rewrite the same accept() method in both subclasses? Because otherwise the object would still be in a Thing context when calling the visitor.reactToThing(this) method, and thus we have the same problem as before. By reimplementing it in all three places, the derived class overrides the parent's implementation, and the correct method is called in Visitor.
Seems like a lot of work when all you want to know is what derived class you're working with, but the payoff is extensibility and maintenance. Now you don't need to go around adding if (something instanceof somethingElse) all over the place. Specifically, you'll have less duplicate code you need to maintain if you ever decide you need to change something down the road, like extend Visitor, for example.
Hope that addresses your question.