I'm using the Observable class / Observer interface in Java to implement the observer pattern. The Observer interface requires overwriting the update(Observable o, Object arg) method.
The problem is that I'm observing a fair number of classes, and my update() method has gotten very large:
public class Foo implements Observer {
....
public void update(Observable o, Object param) {
if (o instanceof A) {
// large chunk of code
...
} else if (o instanceof B) {
// large chunk of code
...
}
...
} else if (o instanceof H) {
...
}
}
}
In order to split up the method, I'm thinking of extending the Observer interface with e.g. AObserver interface, BObserver interface.. which requires overwriting onAUpdate, onBUpdate .. respectively. This method will also make it easy to determine what Observables the class is observing based on the interfaces it's implementing.
class Foo implements AObserver, BObserver {
....
public void onAUpdate(Observable o, Object param) {
if (o instanceof A) {
// large chunk of code
...
}
public void onBUpdate(Observable o, Object param) {
if (o instanceof B) {
// large chunk of code
...
}
}
The problem is that if I inherit Observer, I still have to implement the update() method. I can't rename it to onAUpdate or some other name of my choosing.
Any advice? Thanks.
I'll suggest to create an UpdateHandler interface to do the processing for any given code block. Each case can be handle with a map.
Sample code follows:
// Interface to implement for each case
public interface UpdateHandler {
public void update(Observable source, Object data) ;
}
Add an instance field to your main class as follows:
private Map<Class<?>, UpdateHandler> handlers = new HashMap<Class<?>, Update Handler>();
Create a method to have the handlers initialized
protected void initializeHandler() {
handler.put(Integer.class, new IntegerUpdateHandler());
handler.put(String.class, new StringUpdateHandler());
...
}
The updates method will simply find the appropriate handler and dispatch the call
public void update(Observable source, Object data)
{
UpdateHandler handler = handlers.get(data.getClass()) ;
if (handler == null)
{
// use a default handler ? throw an exception ? your choice ;)
} else {
handler.update(source, data) ;
}
}
This implementation will allow you to add new handler as needed with minimal changes.
Another possible implementation can be done base on the previous work, just a 3 step procedure.
1) Change the declaration of the handlers field.
Map<Class<?>, Class<? extends UpdateHandler>> handlers ;
2) change the initialize method
handlers.put(Integer.class, IntegerInputHandler.class);
3) change the main update method to create a new instance of the provided UpdateHandler implementation.
UpdateHandler handlerInstance = null ;
Class<? extends UpdateHandler> handler = null ;
handler = handlers.get(data.getClass()) ;
...
handlerInstance = handler.newInstance() ;
handlerInstance.update(source, data) ;
Here I coded a raw implementation using observer and visitor pattern. You can take this as an idea to enhance upon it and to fill wherever you see some holes.
public interface IObserver extends Observer {
public void add(AbstractObservable observable, IObserverVisitor visitor);
public void remove(AbstractObservable observable);
public void removeAll();
}
public class Observer implements IObserver {
Map<AbstractObservable, IObserverVisitor> observableMap =
new HashMap<AbstractObservable, IObserverVisitor>();
public void add(AbstractObservable observable, IObserverVisitor visitor) {
observableMap.put(observable, visitor);
}
public void remove(AbstractObservable observable) {
observableMap.remove(observable);
}
public void removeAll() {
observableMap.clear();
}
public void update(Observable o, Object arg) {
observableMap.get(o).visit(this, o, arg);
}
}
public class AbstractObservable extends Observable{
public synchronized void addObserver(IObserver o, IObserverVisitor visitor) {
o.add(this, visitor);
super.addObserver(o);
}
public synchronized void deleteObservers(IObserver o) {
o.removeAll();
super.deleteObservers();
}
public synchronized void deleteObserver(IObserver o) {
o.remove(this);
super.deleteObserver(o);
}
#Override
public synchronized void deleteObserver(Observer o) {
throw new UnsupportedOperationException();
}
#Override
public synchronized void addObserver(Observer o) {
throw new UnsupportedOperationException();
}
#Override
public synchronized void deleteObservers() {
throw new UnsupportedOperationException();
}
#Override
public synchronized int countObservers() {
return super.countObservers();
}
#Override
public synchronized boolean hasChanged() {
return super.hasChanged();
}
#Override
public void notifyObservers() {
super.notifyObservers();
}
#Override
public void notifyObservers(Object arg) {
super.notifyObservers(arg);
}
#Override
protected synchronized void clearChanged() {
super.clearChanged();
}
#Override
protected synchronized void setChanged() {
super.setChanged();
}
}
public class Observable1 extends AbstractObservable {
public void changeSomething() {
setChanged();
notifyObservers();
}
}
public class Observable2 extends AbstractObservable {
public void changeSomething() {
setChanged();
notifyObservers();
}
}
public interface IObserverVisitor {
void visit(IObserver obsrvr, Observable obsrvable, Object o);
}
public class ObserverVisitor1 implements IObserverVisitor{
public void visit(IObserver obsrvr, Observable obsrvable, Object o) {
System.out.println("updated one");
}
}
public class ObserverVisitor2 implements IObserverVisitor{
public void visit(IObserver obsrvr, Observable obsrvable, Object o) {
System.out.println("updated two");
}
}
public class ObserverTest {
#Test
public void testAnything() {
Observable1 obsrvable1 = new Observable1();
Observable2 obsrvable2 = new Observable2();
Observer obsrvr = new Observer();
obsrvable1.addObserver(obsrvr, new ObserverVisitor1());
obsrvable2.addObserver(obsrvr, new ObserverVisitor2());
obsrvable1.changeSomething();
obsrvable2.changeSomething();
}
}
I hope you are not lost. :)
Move the chunks of code within each condition to appropriately named methods.
public void update(Observable o, Object param) {
if (o instanceof A) {
onAUpdate(o, param);
}
if (o instanceof B) {
onBUpdate(o, param);
}
}
public void onAUpdate(Observable o, Object param) {
// large chunk of code
}
public void onABUpdate(Observable o, Object param) {
// large chunk of code
}
Related
Suppose I have a class hierarchy in Java:
interface Item { ... };
class MusicBox implements Item { ... };
class TypeWriter implements Item { ... };
class SoccerBall implements Item { ... };
and I have another class in the same package:
class SpecialItemProcessor {
public void add(Item item)
{
/* X */
}
}
where I want to do something different for each item type, but I don't want to define that action in the different Item classes (MusicBox, TypeWriter, SoccerBall).
One way to handle this is:
class SpecialItemProcessor {
public void add(Item item)
{
if (item instanceof MusicBox)
{
MusicBox musicbox = (MusicBox)item;
... do something ...
}
else if (item instanceof MusicBox)
{
TypeWriter typewriter = (TypeWriter)item;
... do something ...
}
else if (item instanceof SoccerBall)
{
SoccerBall soccerball = (SoccerBall)item;
... do something ...
}
else
{
... do something by default ...
}
}
}
This works but it seems really clunky. Is there a better way to do this, when I know of special cases? (obviously if Item contains a method doSomethingSpecial then I can just call that item's method without caring what type it is, but if I don't want that differentiation to occur within the item itself how do I deal with it?)
In Java you can do multiple dispatch with a visitor(-like) pattern. The Item implementations don't need to contain the processing logic, they just need an accept() type of method.
public interface Item {
/** stuff **/
void processMe(ItemProcessor processor);
}
public interface ItemProcessor {
void process(MusicBox box);
void process(SoccerBall ball);
//etc
}
public class MusicBox implements Item {
#Override
public void processMe(ItemProcessor processor) {
processor.process(this);
}
}
public class ItemAddingProcessor implements ItemProcessor {
public void add(Item item) {
item.processMe(this);
}
#Override
public void process(MusicBox box) {
//code for handling MusicBoxes
//what would have been inside if (item instanceof MusicBox) {}
}
//etc
}
I think I'm going to use the idea of inversion of control and the visitor pattern:
interface Item {
public void accept(Visitor visitor);
...
public interface Visitor {
public void visit(Item item);
}
}
class MusicBox implements Item {
public interface Visitor extends Item.Visitor {
public void visitMusicBox(MusicBox item);
}
...
#Override public accept(Item.Visitor visitor)
{
if (visitor instanceof MusicBox.Visitor)
{
((MusicBox.Visitor)visitor).visitMusicBox(this);
}
}
}
class TypeWriter implements Item {
public interface Visitor extends Item.Visitor {
public void visitTypeWriter(TypeWriter item);
}
...
#Override public accept(Item.Visitor visitor)
{
if (visitor instanceof TypeWriter.Visitor)
{
((TypeWriter.Visitor)visitor).visitTypeWriter(this);
}
}
}
class SoccerBall implements Item {
public interface Visitor extends Item.Visitorr {
public void visitSoccerBall(SoccerBall item);
}
...
#Override public accept(Item.Visitor visitor)
{
if (visitor instanceof SoccerBall.Visitor)
{
((SoccerBall.Visitor)visitor).visitSoccerBall(this);
}
}
}
and then do the following, which at least reduces the instanceof to one check per add() call:
class SpecialItemProcessor
implements
MusicBox.Visitor,
TypeWriter.Visitor,
SoccerBall.Visitor,
Item.Visitor
{
public void add(Item item)
{
item.accept(this);
}
#Override public void visitMusicBox(MusicBox item)
{
...
}
#Override public void visitTypeWriter(TypeWriter item)
{
...
}
#Override public void visitSoccerBall(SoccerBall item)
{
...
}
#Override public void visit(Item item)
{
/* not sure what if anything I should do here */
}
}
Why not define some callback function to Item interface?
public Interface Item {
void onCallBack();
}
Then in each class that implements Item, such as MusicBox, it should implement the callback function.
public class MusicBox {
#override
public void onCallBack() {
// business logic
...
...
}
}
Then you could create a dispatcher, which you name is "SpecialItemProcessor".
public SpecialItemProcessor {
private final Item _item;
public SpecialItemProcessor(Item item) {
_item = item;
}
public dispatch() {
_item.onCallBack()
}
}
And then, in the Client class which contains the SpecialItemProcessor could just call the method, like:
public void XXXX() {
....
SpecialItemProcessor specialItemProcessor = new SpecialItemProcessor(new MusicBox());
specialItemProcessor.dispatch();
....
}
Actually, in C++, this is Dynamic Binding. And this is why pure abstract class exists...
You could create a bridge pattern for Item, in which the other side were the associated processes to do when add() is called. You could also add a factory method to the mix.
class SpecialItemProcessor {
public void add(Item item)
{
Process p = Item.createCorrespondingProcessor( p );
p.doWhenAddin();
}
}
Hope this helps.
I have a class called Router that takes care of interfacing with Retrofit. So in here are all the core methods. Then i have an abstract class called ConfigurableRouter (that extends Router), that allows me to configure my router. Now i want that i can create children of the ConfigurabelRouter (In fact it is an abstract class) with different defults values.
This is an example how it works:
Router.configure(M_Rout.class)
.setPath("close-pi")
.setParams(params)
.setRequestMethod(Router.RequestMethod.POST)
.setIsAuthRequested(true)
.setCallback(new RequestResponse() {
#Override
protected void onSuccess(HashMap<String, String> responseItems) {}
#Override
protected void onGeneralError(int responseCode) {}
#Override
public void onFailure() {}
})
.sendRequest(getActivity());
This is how the Router.configure() methods work:
public static ConfigurableRouter configure(Class<? extends ConfigurableRouter> aClass){
ConfigurableRouter configurableRouter = null;
try {
configurableRouter = aClass.newInstance();
//obj is a newly created object of the passed in type
} catch (Exception ignored) { }
return configurableRouter;
}
And this is an example of a ConfigurableRouter method:
public ConfigurableRouter setParams(HashMap<Stthring, Object> params){
super.setRouterParams(params);
return this;
}
And this is the M_Router class:
public class M_Rout extends ConfigurableRouter {
#Override
public String setBasepath() {
return "www.xxxxxxx.xx/";
}
#Override
public String setInDebigBasePath() {
return "www.debugxxxxxxx.xx/";
}
#Override
public boolean isDebugging() {
return false;
}
#Override
public RequestMethod setDefultRequestMethod() {
return RequestMethod.POST;
}
#Override
public RequestResponse setDefultResponse() {
return new RequestResponse() {
#Override
protected void onSuccess(HashMap<String, String> responseItems) {
Log.d("RouterLog", "PigSUCSESSSpig");
}
#Override
protected void onGeneralError(int responseCode) {
}
#Override
public void onFailure() {
}
};
}
#Override
public ConfigurableRouter setAuthToken(String authToken) {
return super.setAuthToken("tokenExample");
}
public void setIsAuthRequested(boolean b){
//
}
}
Now my problem is that i cannot acces the non-overriden methods in M_Router class, like setIsAuthRequested(), that is in the first snippet. I have no idea how i can do.. tried in different ways but nothing. How can i do?
public abstract class Person {
abstract void sayName();
}
which has two implementations:
public class LoudPerson extends Person {
void sayName() {
System.out.println("I yell my name!!");
}
}
and
public class RegularPerson extends Person {
void sayName() {
System.out.println("I will say my name");
}
void givesBusinessCard() {
// whatever
}
}
Now, if you create a method like this:
public void handlePerson(Person person) {
}
you will be able to call the sayName() method on it, because no matter what type of Person it is, it will always have an implementation of sayName()
Now, let's say you want to pass an instance of RegularPerson, and call the givesBusinessCard(), this won't immediately work.
Even if all you ever pass as parameters are of type RegularPerson, the JVM running the code doesn't (can't) know this
Someone else could create other subclasses, and change that line of thought.
As far as the JVM knows, it's just a Person, and all Person provides is the sayName() method.
Let's say you need to be able to call the givesBusinessCard() method, you have 3 options.
Alter the method you call. If you need givesBusinessCard() to be called, you know it's a RegularPerson, so you can say:
public void handlePerson(RegularPerson person) {
}
Alter your abstract class, add the method there, and provide either a failing or an empty implementation of the method in LoudPerson
public abstract class Person {
abstract void sayName();
abstract void givesBusinessCard();
}
and
public class LoudPerson extends Person {
void sayName() {
System.out.println("I yell my name!!");
}
void givesBusinessCard() throws UnsupportedOperationException {
throw new UnsupportedOperationException("not needed here");
}
}
or
public class LoudPerson extends Person {
void sayName() {
System.out.println("I yell my name!!");
}
void givesBusinessCard() {
}
}
Cast your person to RegularPerson before calling it, but make sure to do an instance check:
public void handlePerson(Person person) {
// ..
if ( person instanceof RegularPerson ) {
RegularPerson p = (RegularPerson)person;
p.givesBusinessCard();
}
// ..
}
I have one parent type
public class IObject{}
and can have a lot of sub-classes (even new ones in the future)
public class Object1 extends IObject{}
public class Object2 extends IObject{}
public class Object3 extends IObject{}
...
public class ObjectN extends IObject{}
Then based on the type of these objects I have to do different operations.
public class StrategyForObject1(){void do{}}
public class StrategyForObject2(){void do{}}
public class StrategyForObject3(){void do{}}
...
public class StrategyForObjectN(){void do{}}
So I want from my Context class:
public Conext {
IObject o;
public void setObject(IObject o) {
this.o = o;
}
void logic() {
if (o instanceOf Object1) {
new StrategyForObject1().do();
}
if (o instanceOf Object2) {
new StrategyForObject2().do();
}
if (o instanceOf Object3) {
new StrategyForObject3().do();
}
...
if (o instanceOf ObjectN) {
new StrategyForObjectN().do();
}
}
}
So based on the type to execute different algorithms, but I want to be extensible like in Strategy pattern if I need to add new sub-class of IObject just to add new StrategyForObject**N** class, but not to change the Conext class.
In Strategy pattern we have to specify the Strategy but here we have to do the opposite: to choose the strategy based on the type of the object. How to do that in Java in the best way?
Edit:
The IObject can not be changed in order to add additional methods.
I must separate logic from data,so it is not desirable to add implementation of the logic in Object1 class for example.
I think you need to implement the visitor pattern. Basically for what you have it would look something like this:
interface IObjectVisitor {
void visit(IObject1 obj1);
void visit(IObject2 obj2);
...
void visit(IObjectN objN);
}
interface IObjectVisitable {
void accept(IObjectVisitor visitor);
}
public abstract class IObject implements IObjectVisitable {
...
}
public class IObject1 extends IObject {
public void accept(IObjectVisitor visitor) {
visitor.visit(this);
}
}
public class IObject2 extends IObject {
public void accept(IObjectVisitor visitor) {
visitor.visit(this);
}
}
...
public class IObjectN extends IObject {
public void accept(IObjectVisitor visitor) {
visitor.visit(this);
}
}
public class SomeLogicIObjectVisitor implements IObjectVisitor {
void visit(IObject1 obj1) {
//something with obj1
}
void visit(IObject2 obj2) {
//something with obj2
}
...
void visit(IObjectN objN) {
//something with objN
}
}
Then you haven some logic to apply to some IObject like this:
public void someLogic(IObject obj) {
SomeLogicIObjectVisitor visitor = new SomeLogicIObjectVisitor():
visitor.visit(obj);
}
Object-Oriented wise, this is the best pattern you can implement. The reason is because it allows you for a modular and extensible approach, applying the right separation of concerns. Look at the answer provided by #nhouser9 for instance. While defining abstract void do(); in IObject seems to work at first glance, you would be embedding business logic inside your domain object, which most likely doesn't belong there. Also, if now you consider some other logic, lets call it, "logic2" now you have no option but to create abstract void do2(); on every IObject implementation, and continue to embed business logic there. With the visitor pattern, IObject implementations don't change, and you don't embed any logic inside the IObjects, simply just create a new visitor, Logic2IObjectVisitor and implement the logic of each IObject implementation there. And you'd call it like this:
public void someLogic2(IObject obj) {
Logic2IObjectVisitor visitor = new Logic2IObjectVisitor():
visitor.visit(obj);
}
First, your IObject class should be abstract, as it is only intended to be extended by other classes. Then you can declare a method inside it that must be overridden by classes which inherit from it, like this:
public abstract class IObject {
abstract void do();
}
Then all of the classes that implement it must override that method with your custom logic:
public class Object1 extends IObject {
#Override
void do() {
//custom logic
}
}
In other words, you should be putting do() inside Object1 instead of StrategyForObject1.
This structure will allow you to call do() on a generic object of type IObject, as all children of IObject will implement the do() method. So in your logic method, you can just do this:
void logic(){
o.do();
}
Have a look at the Visitor Pattern. I think its exactly what you are looking for.
Edit: To clarify:
import java.util.Arrays;
import java.util.List;
public class Test {
public static abstract class IObject {
public abstract void doSomeWork(StrategyVisitor strat);
}
public static class Object1 extends IObject {
#Override
public void doSomeWork(StrategyVisitor strat) {
strat.doWork(this);
}
}
public static class Object2 extends IObject {
#Override
public void doSomeWork(StrategyVisitor strat) {
strat.doWork(this);
}
}
public static class Object3 extends IObject {
#Override
public void doSomeWork(StrategyVisitor strat) {
strat.doWork(this);
}
}
public static interface StrategyVisitor {
void doWork(Object1 o);
void doWork(Object2 o);
void doWork(Object3 o);
}
public static void main(String[] args) {
List<IObject> objs = Arrays.asList(new Object1(), new Object2(), new Object3());
StrategyVisitor visitor = new StrategyVisitor() {
#Override
public void doWork(Object1 o) {
System.out.println("Object1");
}
#Override
public void doWork(Object2 o) {
System.out.println("Object2");
}
#Override
public void doWork(Object3 o) {
System.out.println("Object3");
}
};
objs.stream().forEach(o -> o.doSomeWork(visitor));
}
}
(See https://en.wikipedia.org/wiki/Visitor_pattern)
IObject could have an abstract method, do().
Then Context's logic() method just calls o.do().
This is a classic example of polymorphism.
I want to write a method which would receive different type of objects dynamically. Once I receive the dynamic object, I have logic inside method to do something based on the properties associated with that object. It would be something like below:
MainClass{
class1 obj1;//all these are pojo
class2 obj2;
class3 obj3;
method1(<dynamic_object>)
}
method1(<dynamic_object>){
if(dynamic_object.property 1 == true){
callmethod2(dynamic_object.property 1)
}
else{
callmethod3(dynamic_object.property 1)
}
}
Here dynamic_objects are of different type.
How can I achieve this in Java? I do not want to use reflection here.
In order to recognize the type of the object you can use the instanceof operator.
private void instanceOfMethodExample(Object object){
if(object instanceof String)
print("Its a String!");
else if(object instanceof Integer)
print("Its an Int!");
else
print("Its a " + object.getClass().getName()); // by calling getClass().getName() method you take the class name of the object as a String
}
Use the visitor pattern, In a nutshell you can have something like this:
public class Visitor {
interface UserVisitor {
public void visit(CarUser user1);
public void visit(BusUser user2);
}
static class VehicleVisitor implements UserVisitor {
private Car vehicle;
private Bus bus;
VehicleVisitor(Car vehicle, Bus bus) {
this.vehicle = vehicle;
this.bus = bus;
}
public void visit(CarUser user1) {
user1.setCar(vehicle);
}
public void visit(BusUser user2) {
user2.setBus(bus);
}
}
interface UserVisitorClient {
void accept(UserVisitor visitor);
}
static class CarUser implements UserVisitorClient {
private Car car;
public void accept(UserVisitor visitor) {
visitor.visit(this);
}
public void setCar(Car car) {
this.car = car;
}
public Car getCar() {
return car;
}
}
static class BusUser implements UserVisitorClient {
private Bus bus;
public void accept(UserVisitor visitor) {
visitor.visit(this);
}
public void setBus(Bus bus) {
this.bus = bus;
}
public Bus getBus() {
return bus;
}
}
static class Car {
#Override
public String toString() {
return "CAR";
}
}
static class Bus {
#Override
public String toString() {
return "BUS";
}
}
public static void main(String[] args) {
List<UserVisitorClient> users = new ArrayList<UserVisitorClient>();
CarUser user1 = new CarUser();
users.add(user1);
BusUser user2 = new BusUser();
users.add(user2);
for (UserVisitorClient user : users) {
VehicleVisitor visitor = new VehicleVisitor(new Car(), new Bus());
user.accept(visitor);
}
System.out.println(user1.getCar());
System.out.println(user2.getBus());
}
}
Which is just an example. But it shows that basically you can use this pattern to support what you're trying to accomplish.
In your code, you could have:
void method1(VisitorClient client) {
client.accept(someVisitor);
}
This will allow you to reach o more object oriented solution, relying in polymorphism instead of reflection or instanceof.
The best option is to use a common interface
interface HasProperty {
boolean isSet();
}
void method1(HasProperty object) {
if (object.isSet())
method2(object);
else
method3(object);
}
Or even better have a method to call to perform an action.
interface MethodOne {
void method1();
}
MethodOne object = ...
object.method1(); // calls the appropriate method for this object.
Use superclass of all objects- "Object" and check the type of object using instanceof operator.
method1(Object obj){
if(obj instanceof dynamic_object){
callmethod2(dynamic_object.property 1)
}
else if(obj instanceof dynamic_object2) {
callmethod3(dynamic_object2.property 1)
}
}
EDIT: Given your newly posted code, you may even simply wish to use an common interface, or base class, for the dynamic objects.
Interface:
public interface CommonInterface {
boolean isValid();
void method1();
void method2();
void method3();
}
Class Example:
public Class1 implements CommonInterface {
public boolean isValid() {
return true;
}
public void method1() {
System.out.println("Method 1");
}
public void method2() {
System.out.println("Method 2");
}
public void method3() {
System.out.println("Method 2");
}
}
Code:
public void doSomethingWithCommonObjects(CommonInterface object) {
object.method1();
if (object.isValid()) {
object.method2();
} else {
object.method3();
}
}
Each of the dynamic objects simply need to implement the CommonInterface interface, which would enforce method1(), method2(), method3() and property1() signatures for each object to implement.
Previous answer details for reference:
You will either have to use Java Generics, potentially with some common interface or base class for the objects in question so that you can then call their methods.
E.g.
public static <T extends Comparable<T>> T maximum(T x, T y, T z) {
T max = x; // assume x is initially the largest
if (y.compareTo(max) > 0) {
max = y; // y is the largest so far
}
if (z.compareTo(max) > 0) {
max = z; // z is the largest now
}
return max; // returns the largest object
}
If, however, you require to call particular methods without knowing the interface for those methods beforehand programmatically, then you're into Reflection territory.
I have the following code
public abstract class Event {
public void fire(Object... args) {
// tell the event handler that if there are free resources it should call
// doEventStuff(args)
}
// this is not correct, but I basically want to be able to define a generic
// return type and be able to pass generic arguments. (T... args) would also
// be ok
public abstract <T, V> V doEventStuff(T args);
}
public class A extends Event {
// This is what I want to do
#Overide
public String doEventStuff(String str) {
if(str == "foo") {
return "bar";
} else {
return "fail";
}
}
}
somewhere() {
EventHandler eh = new EventHandler();
Event a = new A();
eh.add(a);
System.out.println(a.fire("foo")); //output is bar
}
However I don't know how to do this, as I cannot override doEventStuff with something specific.
Does anyone know how to do this?
It's not really clear what you're trying to do, but perhaps you just need to make Event itself generic:
public abstract class Event<T, V>
{
public abstract V doEventStuff(T args);
}
public class A extends Event<String, String>
{
#Override public String doEventStuff(String str)
{
...
}
}
You're using generics but you are not providing a binding.
public abstract class Event<I, O> { // <-- I is input O is Output
public abstract O doEventStuff(I args);
}
public class A extends Event<String, String> { // <-- binding in the impl.
#Override
public String doEventStuff(String str) {
}
}
Or simpler with only one generic binding...
public abstract class Event<T> { // <-- only one provided
public abstract T doEventStuff(T args);
}
public class A extends Event<String> { // <-- binding the impl.
#Override
public String doEventStuff(String str) {
}
}