Inheritance and Multiple Collaborators - java

I have several Java interfaces/ABCs/classes:
public abstract class Target {
public abstract void fire(Load load);
}
public class HttpTarget extends Target {
#Override
public void fire(Load load) {
// ...
}
}
public interface Load {
// ...
}
public class HttpLoad implements Load {
// ...
}
// Inside a driver
Target target = testSuite.getTarget();
Load load = testSuite.getLoad();
target.fire(load);
So essentially a Target can fire() a Load. My main app Driver doesn't care about what kind of Target is returned by getTarget(), or what kind of Load is returned by getLoad(). It's job is to make sure that a load is fired.
I'd like to change the fire() method definition inside HttpTarget to:
#Override
public void fire(HttpLoad httpLoad) {
// ...
}
However when I do that, Java complains that the method override doesn't match the definition provided by its parent Target class (as Load and HttpLoad are two different things).
What's the solution here? Generics? Abstract factories? Ultimately, I want to be able to enforce that HttpTarget's fire() method can only accept HttpLoads, but still be compatible with the Driver code. Can someone provide a code example? Thanks in advance!

Yes, you would need generics:
public abstract class Target<L extends Load> {
public abstract void fire(L load);
}
public class HttpTarget extends Target<HttpLoad> {
#Override
public void fire(HttpLoad load) {
...
}
}
public interface TestSuite<L extends Load> { // or class
L getLoad();
Target<L> getTarget();
}
public class HttpTestSuite implements TestSuite<HttpLoad> {
#Override
public HttpLoad getLoad() {
...
}
#Override
public Target<HttpLoad> getTarget() {
return new HttpTarget();
}
}
The reason Java refuses to compile your HttpTarget class is because it doesn't override the Target's fire(Load) method. Indeed, a Target, by contract is supposed to accept any kind of Load as argument. And the HttpTarget's fire() method only accepts instances of HttpLoad, and thus breaks the Liskov principle. Generics are the solution to this problem.

You will have to use generics and even then it is not exactly what you want.
public interface Load<T extends Load> {
public void someMethod();
}
public class HttpLoad implements Load<HttpLoad> {
#Override
public void someMethod() {
System.out.println("Http Load");
...
}
}
public abstract class Target<T extends Load> {
public abstract void fire(Load<T> load);
}
public class HttpTarget extends Target<HttpLoad> {
#Override
public void fire(Load<HttpLoad> load) {
load.someMethod();
}
}
Now if you write
Target<HttpLoad> httpTarget = new HttpTarget();
Load<HttpLoad> httpLoad = new HttpLoad();
Load<OtherLoad> otherLoad = new OtherLoad();
Load otherLoad2 = new OtherLoad();
httpTarget.fire(httpLoad);
httpTarget.fire(otherLoad); // this doesn't compile
httpTarget.fire(otherLoad2) // this how ever compiles

Related

Cannot reference this before supertype constructer has been called + Consumer

I'm attempting to define a generic abstract class that handles the processing/retrying logic of the implementing class. I want all implementing classes to pass a "process" and "fail" function that is executed by the abstract class. The abstract class also holds retry attempt logic and some other generic boilerplate code that I would like to reuse.
Specifically, I have the following abstract class:
public abstract class EnvelopeDispatcher<T> {
protected Consumer<T> processFn;
protected Consumer<T> failFn;
private MetricsRegistry metricsRegistry;
public EnvelopeDispatcher(MetricsRegistry metricsRegistry, Consumer<T> processFn, Consumer<T> failFn) {
this.metricsRegistry = metricsRegistry;
this.processFn = processFn;
this.failFn = failFn;
}
protected void process(T envelope) {
//abstract processing logic calling processFn and failFn
}
}
And the following implementing class:
public class ActionEnvelopeDispatcher extends EnvelopeDispatcher<ActionEnvelope> implements Consumer<ActionEnvelope> {
public ActionEnvelopeDispatcher(MetricsRegistry metricsRegistry ) {
super(metricsRegistry, this::processEnvelope, this::failEnvelope)
}
#Override
public void accept(#NonNull ActionEnvelope envelopeToProcess) {
super.process(envelopeToProcess);
}
private void processEnvelope( ... ) {
//processing logic
}
private void failEnvelope( ... ) {
//failure case logic
}
}
When I attempt to call super while referencing this::processEnvelope and this::failEnvelope I get "Cannot reference this before supertype constructer has been called".
I understand why this is happening, but I'm not sure of the alternatives. Does anyone know how to get around this or a better implementation pattern?
What you could do is don't make the dispatcher abstract and create it using factory methods.
Something like this:
class EnvelopeDispatchers {
// factory method
public static EnvelopeDispatcher<ActionEnvelope> actionEnvelopeDispatcher(MetricsRegistry metricsRegistry) {
return new EnvelopeDispatcher(metricsRegistry,
EnvelopeDispatchers::processEnvelope,
EnvelopeDispatchers::failEnvelope);
}
private static void processEnvelope(ActionEnvelope env) {
//processing logic
}
private static void failEnvelope(ActionEnvelope env) {
//failure case logic
}
}

Java: How can I design this class for having optional generics ParameterType?

I have this class in my code
public abstract class MyAbstractEventListener<E extends IMyEvent> {
public abstract void handleEvent(E e);
}
and I can make instances in this way (let's call it A):
new MyAbstractEventListener<IMyEvent>() {
#Override
public void handleEvent(final IMyEvent e) {
// Method implementation
}
};
But for my purposes, it would be ideal being able also to do this as well when there's no required event info (let's call this B):
new MyAbstractEventListener() { // Or receiving some unused parameter
#Override
public void handleEvent() {
// Method implementation
}
};
without having the warning about the class being raw and reccomending to parameterize it.
To clarify, I want the class to allow either the A or B instantiation, having the personal choice of using the one I prefer each time. If there's some generics parameter, the method receiving the IMyEvent object and if not, the method without parameters.
An example of code using this class would be:
EventBus.getInstance().addEventListener("some.string", new
AbstractEventListener<IMyEvent>() {
#Override
public void handleEvent(final IMyEvent e) {
// Sometimes does use 'e', sometimes doesn't. That's the point
MyConfirmationWindow.showConfirmationWindow(MyWindowType.WARNING, "kk", "lll");
}
});
Is there a way? Any link or resource will be appreciated.
Well, you could make an abstract subclass :
public abstract class BlindListener extends MyAbstractEventListener<IMyEvent> {
public abstract void handleEvent();
#Override
public void handleEvent(IMyEvent iMyEvent) {
handleEvent(); // delegate to abstract method that ignores the argument
}
}
This is actually a class that uses generics, but clients won't ever have to deal with them :
new BlindListener() {
#Override
public void handleEvent() {
}
}
Instances that do need a specific type can still use the MyAbstractEventListener directly
I don't think you will be able to avoid having tow handleEvent methods the way you described here.
But here is another approach using Null Object design pattern and single handleEvent method:
new MyAbstractEventListener<IMyEvent>() {
#Override
public void handleEvent(final IMyEvent e) {
// Method implementation
}
};
new MyAbstractEventListener<NullIMyEvent>() {
#Override
public void handleEvent(final NullIMyEvent e) {
// Method implementation
}
};
public interface IMyEvent{}
public class NullIMyEvent implements IMyEvent{}
public static abstract class MyAbstractEventListener<E extends IMyEvent> {
public abstract void handleEvent(E e);
}
public abstract class MyAbstractEventListener<E extends IMyEvent> {
But for my purposes, it would be ideal being able also to do this as well when there's no required event info (let's call this B):
The question is: what does the class MyAbstractEventListener do with the information that the parameter type E extends IMyEvent? Is there any method in that class working on type IMyEvent?
If not you could simple remove extends IMyEvent to achieve your goal.
Otherwise you need a different class since MyAbstractEventListener relies on type Eextending (or implementing) IMyEvent.

C# equivalent to implement interface inside super keyword in Java [duplicate]

I am not sure how am I suppose to go about my question. It is about Android can Instantiate Interface. I am trying to do in C#. Now I am pretty sure that the rules for both Java and C# is you can't create an Instance of abstract and Interface as being said.
But I would really like to know how Android does this practice.
In Android you can do this.
public interface Checkme{
void Test();
void Test2();
}
public void myFunc(Checkme my){
//do something
}
// Now this is the actual usage.
public void Start(){
myFunc(new Checkme(){
#Override
public void Test()
{
}
#Override
public void Test2()
{
}
});
}
Actually once you press Enter on new Checkme() You will automatically get the Override methods of the Interface. Like auto Implement method of an Interface in C#.
I hope my question make sense.
C# doesn't support anonymously auto-implemented interfaces because it has delegates:
public void Foo(Func<string> func, Action action) {}
// call it somewhere:
instance.Foo(() => "hello world", () => Console.WriteLine("hello world"));
With delegates you can fill the gap and it can be even more powerful than implementing interfaces with anonymous classes.
Learn more about delegates.
This is an Anonymous Class:
public void Start(){
myFunc(new Checkme() {
#Override
public void Test() {
}
#Override
public void Test2() {
}
});
}
An anonymous class is an unnamed class implemented inline.
You could also have done it using a Local Class, but those are rarely seen in the wild.
public void Start(){
class LocalCheckme implements Checkme {
#Override
public void Test() {
}
#Override
public void Test2() {
}
}
myFunc(new LocalCheckme());
}
These both have the advantage that they can use method parameters and variables directly, as long as they are (effectively) final.
As a third option, you could do it with an Inner Class.
private class InnerCheckme implements Checkme {
#Override
public void Test() {
}
#Override
public void Test2() {
}
}
public void Start(){
myFunc(new InnerCheckme());
}
An inner class cannot access method variables (obviously because it's outside the method), but can be used by multiple methods.
Any local values from the method can however be passed into the constructor and stored as fields of the inner class, to get the same behavior. Just requires a bit more code.
If the inner class doesn't need access to fields of the outer class, it can be declared static, making it a Static Nested Class.
So, all 3 ways above a very similar. The first two are just Java shorthands for the third, i.e. syntactic sugar implemented by the compiler.
C# can do the third one, so just do it that way for C#.
Of course, if the interface only has one method, using a Java lambda or C# delegate is much easier than Anonymous / Local / Inner classes.
If I understand correcly, you're defining a class that implements an interface, and when you specify that the class implements an interface, you want it to automatically add the interface's methods and properties.
If you've declared this:
public interface ISomeInterface
{
void DoSomething();
}
And then you add a class:
public class MyClass : ISomeInterface // <-- right-click
{
}
Right-click on the interface and Visual Studio will give you an option to implement the interface, and it will add all the interface's members to the class.
you mean something like this?
pulic interface Foo{
void DoSomething();
}
public class Bar : Foo {
public void DoSomething () {
//logic here
}
}
myFunc(new Checkme(){
#Override
public void Test()
{
}
#Override
public void Test2()
{
}
});
You're passing into myFunc() something that is called an anonymous class. When it says "new Checkme() { .... }", it is defining an anonymous implementation of the Checkme interface. So, it's not an instance of the interface itself, just an instance of a type that implements it.
In C# anonymously implemented classes for Interface are not auto generated just like in java, you need to follow the below procedure to workout.
public class MyClass {
public void someMethod (string id, IMyInterface _iMyInterface) {
string someResponse = "RESPONSE FOR " + id;
_iMyInterface.InterfaceResponse (someResponse);
}
}
public interface IMyInterface {
void InterfaceResponse (object data);
void InterfaceResponse2 (object data, string x);
}
public class MyInterfaceImplementor : IMyInterface {
private readonly Action<object> actionname;
private readonly Action<object, string> actionInterfaceResponse2;
public MyInterfaceImplementor (Action<object> InterfaceResponse) {
this.actionname = InterfaceResponse;
}
public MyInterfaceImplementor(Action<object> interfaceResponseMethod, Action<object, string> interfaceResponseMethod1) {
this.actionname = interfaceResponseMethod ?? throw new ArgumentNullException(nameof(interfaceResponseMethod));
this.actionInterfaceResponse2 = interfaceResponseMethod1 ?? throw new ArgumentNullException(nameof(interfaceResponseMethod1));
}
public void InterfaceResponse (object data) {
this.actionname (data);
}
public void InterfaceResponse2(object data, string x) {
this.actionInterfaceResponse2(data, x);
}
}
Gist Source : https://gist.github.com/pishangujeniya/4398db8b9374b081b0670ce746f34cbc
Reference :

Abstract callback in reflection method of java

I have a class in jar of which I want to invoke a method. But that method has parameter of abstract class and that abstract class is inner method of class in jar. AbstractClassA is a HIDDEN class. Here is code:
public class A{
private invokeThisMethod(AbstractClassA object){
}
public abstract class AbstractClassA {
public void update(int remaining){}
}
}
public class myClass{
//using Reflection get object of class A
objectOfClassAusingReflection.inovke("invokeThisMethod", params)
}
Problem here is how do I create concrete implementation of AbstractClassA to pass in invoke method and get update method callbacks ?
Something like this should work:
AbstractClassA a = new AbstractClassA() {
public void update(int remaining) {... do something...}
};
objectOfClassAusingReflection.inovke("invokeThisMethod", a);
You cannot create an instance of abstract class or any interface at runtime.
Instead create an anonymous class for this.
public abstract class A {
public void fun(){....}
public abstract void absFun();
}
public class MyClass {
objectOfClassA = new A(){
public void absFun(){...}
}
}
Or you can first create implementation for that abstract classes for which you will have to create another class extending A
class AWrapper extends A {
public class ImplementationClassA extends AbstractClassA {
// override abstract functions...
}
}
Now you can use this Awrapper class
AWrapper wrapperObj = new AWrapper();
A obj = wrapperObj; // just to make it clear that A can hold wrapperObj as it is implementation of it.
A.AbstractClassA absObj = wrapperObj.new ImplementationClassA();
...
objectOfClassAusingReflection.inovke("invokeThisMethod", params)
Below code should work--
Here, i used anonymus classes for both outer and inner class and then with the help of getdeclatedMethod called your update method.
"TestAbs" is your jar class--
public abstract class TestAbs {
private void invokeThisMethod(AbstractClassA object) {
}
public abstract class AbstractClassA {
public void update(int remaining) {
}
}
}
Then calling your jar class from "TestAbs1" like below--
public class TestAbs1 {
public static void main(String[] args) {
TestAbs.AbstractClassA abs = new TestAbs() {
AbstractClassA a = new AbstractClassA() {
public void update(int remaining) {
System.out.println("Inside update method : " + remaining);
}
};
}.a;
try {
int i = 1;
Class<?> class1 = Class.forName("app.test.mytest.TestAbs$AbstractClassA"); -- (*Getting instance of inner class*)
System.out.println(class1.getDeclaredMethod("update", int.class));
class1.getDeclaredMethod("update", int.class).invoke(abs, i);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The output i got is --
public void app.test.mytest.TestAbs$AbstractClassA.update(int)
Inside update method : 1
Answer to your Comment:-
What I understood from your comment is that, you wanted to call method from abstractClass which is hidden in outerclass.
As per my understanding, there is one way like below--
public abstract class TestAbs {
private void invokeThisMethod(AbstractClassA object) {
}
private abstract class AbstractClassA { --- your hidden class
public void update(int remaining) {
}
}
public class ImplementedClass extends AbstractClassA{ -- use implemented class here
....
...
}
}
And after that, use your ImplementedClass the same way mentioned above.
You can find reference example for private inner class here from java docs.
Note: In your question context, since your inner class and outer class is in jar, so I think it is difficult for you add implementation class in your jar.
In case, you find any alternatives, please let all knows about this;
thanks.

Overwriting methods: how to "inject" into the super-method?

Assuming three classes, one being a subclass of the other. Each overwrite the parents' method.
public class BaseClass {
public void doStuff() {
performBaseTasks();
}
}
public class MiddleClass extends BaseClass {
// {BaseClass} Overrides
public void doStuff() {
performMiddleTasks();
super.doStuff();
}
}
public class FinalClass extends MiddleClass {
// {BaseClass} Overrides
public void doStuff() {
performFinalTasks();
super.doStuff();
}
}
When calling new FinalClass().doStuff(), this would lead to a method
invokation order as follows:
performFinalTasks();
performMiddleTasks();
performBaseTasks();
I want to bring the perfomFinalTasks() between performMiddleTasks() and
performBaseTasks(). How can I do this?
performMiddleTasks();
performFinalTasks();
performBaseTasks();
Write a public method in final class doStuffDifferently() and invoke these methods in that order. I am not sure it's possible to do it via any other tricks in the doStuff() method.
One possible way, if you can make the middle class abstract:
public abstract class MiddleClass extends BaseClass {
// {BaseClass} Overrides
public void doStuff() {
performMiddleTasks();
doProxyExec();
super.doStuff();
}
public abstract void doProxyExec();
}
You override the proxy method in your subclass:
public class FinalClass extends MiddleClass {
// {BaseClass} Overrides
public void doStuff() {
super.doStuff();
}
// {MiddleClass} Overrides
public void doProxyExec(
performFinalTasks();
}
}
A not very polymorphic way of method call chaining, but then again the original design is kind of ... odd.

Categories