Handling all subtypes of a supertype - java

What is the best way to handle different subtypes of an abstract supertype as an argument, for instance when handling events.
The situation is as follows:
The supertype:
public interface MySuperInterface {
}
A subtype
public class SubclassA implements MySuperInterface {
}
Another subtype
public class SubclassB implements MySuperInterface {
}
Some class that should be able to handle any subtype of MySuperInterface
public class MySuperHandler {
public void handle(MySuperInterface mysuper) {
//do it
}
}
My different approaches are
a switch/case statement in the handler method. (which I dont like)
a method receive(MySuperHandler) in the interface and a dispatch to this method
inside the handle method: mysuper.receive(this) (which means the interface knows the handler class)
Adding a handle method for every subtype in the MySuperHandler class (this does not ensure that every subtype can be handled)
but for the mentioned reasons I'm not content with these solutions.
are there any options to handle this situation?
thanks

One approach is to use the Visitor Pattern. It would look something like this:
public interface MySuperInterface {
<T> T acceptVisitor(MySuperInterfaceVisitor<T>);
}
public interface MySuperInterfaceVisitor<T> {
T visitA(SubclassA a);
T visitB(SubclassB a);
}
public class SubclassA implements MySuperInterface {
<T> T acceptVisitor(MySuperInterfaceVisitor<T> visitor) {
return visitor.visitA(this);
}
}
public class SubclassB implements MySuperInterface {
<T> T acceptVisitor(MySuperInterfaceVisitor<T> visitor) {
return visitor.visitB(this);
}
}
public class MySuperHandler implements MySuperInterfaceVisitor<Foo>{
Foo visitA(SubclassA a) {
// construct Foo from SubclassA instance
}
Foo visitB(SubclassB a) {
// construct Foo from SubclassB instance
}
}
This is a bit like your #2, except the interface (and the subclasses) don't need to know about the handler. They just need to know about the visitor interface. This is good if you don't want MySuperInterface and its implementations to know about your specific handlers.
BTW, instead of calling:
myHandler.handle(myImpl);
you'd call:
myImpl.acceptVisior(myHandler);
This approach is nice if you want to ensure that every handler can handle every implementation of your interface, yet still keep the implementations from knowing about all of the "handlers" that exist.
If you add another implementation of your interface (MySuperInterface) the compiler will force you to add an acceptVisitor method. This method can either use one of the existing visit* methods, or you'll have to go and add a new one to the visitor interface. If you do the latter, you must then update all of the visitor (aka "handler") implementations. This ensures that every subtype can be handled, going forward.
This approach is more complex than the one in assylias's answer, and only really makes sense if you either want to break the coupling between the implementations of MySuperInterface and your handler code, or you have a strong desire to organize your handler code such that all of the code for a particular type of handling is "together".
One common use of the visitor pattern is rendering objects in different ways. Suppose you want to be able to convert an object into a PDF or HTML. You could have a toHTML and a toPDF method in your interface. The downside to this approach is that now your classes are dependent upon your libraries for generating HTML and PDF. Also, if someone later wants to add a new type of output they need to modify these core classes, which may be undesirable. With the visitor pattern, only the vistior classes need to know about the PDF or HTMl libraries, and new visitors can be added without modifying the core classes. (But again, adding new core classes means you either need to have them reuse an existing visit* method, or you'll have to modify all of the visitor implementations.)

Your description is a bit vague but if you have several subclasses, some of which share a common "handle" behavior, this could work - if you only have 2 subclasses and don't plan to have more in the future, the Abstract step is probably unnecessary:
public interface MySuperInterface {
void handle();
}
public abstract AbstractMySuperInterface {
public void handle() {
//implement default behavior
}
}
public class SubclassA implements MySuperInterface {
//nothing here, just use default behavior
}
public class SubclassB implements MySuperInterface {
public void handle() {
//implement another behavior
}
}
public class MySuperHandler {
public void handle(MySuperInterface mysuper) {
mysuper.handle();
}
}

Related

Java polymorphism: finding the right design pattern

Disclaimer: I know there are a lot of questions about polymorphism out there, but I couldn't find a suitable answer for my problem. If your Google-fu is better than mine, please forgive the dupe.
I have a model using inheritance, such as in the example below.
public abstract class Base {
// ...
}
public class ConcreteA extends Base {
private String someString;
// ...
}
public class ConcreteB extends Base {
private boolean someBool;
// ...
}
And I also have a List<Base>, which is composed of objects that are either ConcreteAs or ConcreteBs.
I need to generate a graphical view for each object in the list, but the resulting element is not the same for ConcreteAs and ConcreteBs. From the example above, the view for ConcreteA would be a text field, while the view for a ConcreteB would be a check box.
How can I achieve this using OO principles?
The problem that you have is that you somewhere return a List<Base> when the caller must know the concrete type.
Usually this is caused because one tried to make a method more generic. E.g. if someone has this service methods
public List<ConcreteA> doSomethingA(){ ... }
public List<ConcreteB> doSomethingB(){ ... }
he might think it is a better idea to introduce a superclass, Base so that both methods can be substituted by
public List<Base> doSomething(){ ... }
This is a good idea if the caller is only interessted in a Base object. This means that ConcreateA and ConcreteB have some common behavior that the caller only depends on.
But in your case it seems that the caller needs the concrete type information that is not available anymore, because of the more generic method.
So you either must preserve or reconstruct the type information.
Preserve the type by using a custom return type instead of making the method generic
public class Result {
private List<ConcreteA> concreteA;
private List<ConcreteB> concreteA;
}
public Result doSomething();
Recunstruct the type information using instanceof
Reconstruct the type information by introcucing a visitor pattern.
Not a pattern - this is what abstraction is all about. Declare a method you want all subclasses of Base to implement and each must implement it in their own way.
Obviously you would pass parameters and/or get results of the methods.
public abstract class Base {
abstract void graphicalView();
}
public class ConcreteA extends Base {
#Override
void graphicalView() {
}
}
public class ConcreteB extends Base {
#Override
void graphicalView() {
}
}
public void test() throws IOException {
List<Base> bases = new ArrayList<>();
for ( Base b : bases ) {
b.graphicalView();
}
}
I think you're looking for Visitor Design Pattern.
From Wikipedia :
In object-oriented programming and software engineering, the visitor
design pattern is a way of separating an algorithm from an object
structure on which it operates. A practical result of this separation
is the ability to add new operations to extant object structures
without modifying the structures. It is one way to follow the
open/closed principle.
In essence, the visitor allows adding new virtual functions to a
family of classes, without modifying the classes. Instead, a visitor
class is created that implements all of the appropriate
specializations of the virtual function. The visitor takes the
instance reference as input, and implements the goal through double
dispatch.
In such cases, I usually use generics something like this
public abstract class Base <T extends Shape>{
public abstract T drawShape();
}
public class ConcreatA extends Base<Circle> {
#Override
public Circle drawShape() {
return null;
}
}
public class ConcreatB extends Base<Square> {
#Override
public Square drawShape() {
return null;
}
}
So now you can use list of Shapes

Ensure subclass is instance of generic type of superclass

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!

Inheritance type issue: is there a clean solution?

I have an abstract class inherited by two concrete classes.
public abstract class AbstractClass {
public abstract void operation1();
}
public class ConcreteClassA extends AbstractClass {
#Override
public void operation1() {
// Do work
}
public void operation2() {
// Do some other work
}
}
public class ConcreteClassB extends AbstractClass {
#Override
public void operation1() {
// Do work
}
}
Now, to take advantage of dynamic binding I create two objects while programming to the interface.
private AbstractClass classA = new ConcreteClassA();
private AbstractClass classB = new ConcreteClassB();
But this does not allow me to call method operation2() on classA. I can fix this by using a downcast.
((ConcreteClassA) classA).operation2();
But downcasts are considered ugly in OOP especially when you have to use them a lot. Alternatively, I can give up programming to the interface.
private ConcreteClassA classA = new ConcreteClassA();
But then I lose the dynamic binding. Another option is to move operation2() to the AbstractClass so that I can restore the dynamic binding.
public abstract class AbstractClass {
public abstract void operation1();
public abstract void operation2();
}
But then ConcreteClassB needs to override operation2() leaving the implementation empty since this class does not need this method.
Lastly, I could move operation2() to the AbstractClass and provide a default implementation which may be overridden or not.
public abstract class AbstractClass {
public abstract void operation1();
public void operation2() {
// Some default implementation
}
}
But this gives classB access to operation2() which I would rather avoid.
There does not seem to be a clean solution to call subclass specific methods while maintaining dynamic binding at the same time. Or is there?
There are at least a few ways to deal with this circumstance and, really, the right one depends on your particular requirements.
Ask yourself, "are both operation1 and operation2 part of the contract specified by my type?"
If the answer is clearly no, then you should not pollute the contract of your type by adding collateral methods to it. You should next ask yourself, "why am I not using interfaces to specify separate types, eg.: instead of AbstractClass, why am I not using MyInterface1 and MyInterface2 (each with its own separate contract)? Interfaces provide a limited form of multiple inheritance, and your implementing classes can implement any and all interfaces that pertain to it. This is a strategy commonly used by the Java Platform Libraries. In this circumstance, explicit casting to the type whose contract you want to use is exactly the right thing to do.
If the answer is clearly yes, then you should have both methods in your type ... but you should still ask yourself, "why am I not specifying my type with an interface"? In general, you should specify types with interfaces rather than abstract classes, but there are reasons to use the latter.
If the answer is somewhere in between, then you can consider specifying optional methods in your type. These are methods which are included in the contract of your type, but which implementing classes are not required to implement. Before Java 8, each implementing type would need to throw a UnsupportedOperationException for any optional methods that it did not implement. In Java 8, you can do something like this for optional methods:
======
public interface MyType {
void contractOperation1();
default void optionalOperation2() {
throw new UnsupportedOperationException();
}
}
A class that implements this interface will need to provide an implementation for contractOperation1(). However, the class will not need to provide an implementation for optionalOperation2() and if this method is invoked on an implementing class that has provided no implementation of its own, then the exception is thrown by default.
abstract class don't have the object,we just create the reference of that class and use it.
like:
instead of this-
private AbstractClass classA = new ConcreteClassA();
private AbstractClass classB = new ConcreteClassB();
use this one
private AbstractClass classA;
private AbstractClass classB;
If we will create an object of the abstract class and calls the method having no body(as the method is pure virtual) it will give an error. That is why we cant create object of abstract class. Here is a similar StackOverflow question. In short, it is legal to have a public constructor on an abstract class.
more details are here:about abstraction instance

Using Generics and Reflections in Java for interface method implementation

I am trying to solve an exercise using Guice. I have done pretty much everything else, but this method implementation is confusing the soul out of me. The purpose of this method is to act as a registrar of loggers and there is another method which will act as a dispatch messages to the correct logger (#named loggers). I am not worried about the dispatcher too much as I know how to do that. But the registrar method MUST use generics and reflections. I am badly stuck here and my Java experience is almost non-existent when it comes to using reflections with "java.lang.Class".
The code is given below:
class MyManagerImpl implements MyMgr {
/* MyListener below is an interface */
public synchronized void regService(Class<? extends MyListener> loggerObj) {
...
...
...
}
public synchronized void dispatch(String msg, String logger) {
/ * dispatches the messages to the correct logger which
* I know how to do
*
*/
}
}
I understand that the above wildcard-enabled type expression says "Class contains anytype that implements of, or extends, MyListener interface". But I am quite new to using Class for anonymity. Is it possible to see an example where this loggerObj is actually being modified/used to invoke a member function.
Your code doesn't make much sense I guess, what one will pass is the Class instance, thus to use for reflection, you can't call any method on it. You can perhaps do some reflection.
A better attempt would be:
public synchronized void doService(<? extends MyListener> listenerObj) {
//...
//...
//...
}
but that would be rather pointless, because you can replace it by:
public synchronized void doService(MyListener listenerObj) {
//...
//...
//...
}
The generics are merely used for Collection<T> types like:
public synchronized void doService(Collection<? extends MyListener> listenerObj) {
//...
//...
//...
}
Such that you can call it with ArrayList<SubMyListener> or ArrayList<SubSubMyListener>, etc. This because the following inheritance relation doesn't hold:
ArrayList<SubSubMyListener> extends ArrayList<SubMyListener>
Why is this useful?:
Say you expect some kind of collection with MyListener objects, now you can provide a method with the signature:
Foo method (Collection<? extends MyListener> bars) {
}
But if one wants to call the method with a Collection<SubMyListener>, it doesn't follow inheritance, so the compiler won't allow it. By using wildcards, you can do this.
You can use this constraint, to call a method defined on MyListener. For instance:
void callAll (Collection<? extends MyListener> bars) {
for(MyListener bar : bars) {
bar.call();
}
}
Now in the for-loop, Java derives an Iterator<? extends MyListener>. In other words, Java knows, the Iterator will only emit objects that inherit from MyListener, this can be used so that Java can perform type-checking and this is thus more safe than hoping the objects are indeed MyListener objects.

Implicit object type in Java?

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()).

Categories

Resources