简体   繁体   English

java在通用方法中使用它(继承)

[英]java using this in generic method (inheritance)

I'm trying to get access to child class methods and fields, when creating lambda, which is used in parent class.在创建在父类中使用的 lambda 时,我试图访问子类方法和字段。 Code explains it more easily:代码更容易解​​释:

class Parent {
    List<Processor<? extends Parent>> processors;

    private void doSmth() {
        for (Processor<? extends Parent> processor : processors) {
            processor.doJob(this);  //this lines gives compile error
        }
    }

    public void registerListeners(Processor<? extends Parent> ... subscribers) {
        this.subscriberList = Arrays.asList(subscribers);
    }
}

Where Processor is a FunctionalInterface .其中ProcessorFunctionalInterface

public interface Processor<T extends Parent> extends BiFunction<T, Message,  Boolean> {
    AtomicReference<Boolean> ok = new AtomicReference<>(false);

    default void doJob(T client, Message message) {
        if (apply(client, message))
            ok.set(true);
    }

    default boolean isDone() {
        return ok.get();
    }
}

The example of wanted usage of these classes:这些类的想要使用的示例:

Child childInstance= new Child(); //where Child class extends Parent
childInstance.registerListeners((child, message) -> child.callSomeChildMethod());
childInstance.doSmth(message);

It would be really cool to create lambda without redundant specifying of parameter type like in this line:在没有冗余指定参数类型的情况下创建 lambda 真的很酷,就像这一行:

childInstance.registerListeners((Processor<Child>) (child, message) -> child.callSomeChildMethod());

(because it always should be type for which I register the listeners) (因为它始终应该是我注册侦听器的类型)
The problem is that code doesn't compile with error问题是代码没有编译错误
incompatible types: Parent cannot be converted to capture#1 of ? extends Parent
Which is quite logical (I understand the reason).这是非常合乎逻辑的(我理解原因)。 Is there some way in java I can get this code working?在java中有什么方法可以让这段代码工作吗?
Thanks in advance!提前致谢!

Your idea of having List<Processor<? extends Parent>> processors;你有List<Processor<? extends Parent>> processors; List<Processor<? extends Parent>> processors; in Parent class is not suggestible.Parent类中是不建议的。 As you see, since you have not mentioned the type of processes the list has;如您所见,由于您没有提到列表中的进程类型; wherever you call processor.doJob(anyObjectHere) an error gets thrown, one way or the other(unless you do explicit cast)无论您在何处调用processor.doJob(anyObjectHere)都会以一种或另一种方式抛出错误(除非您进行显式转换)

Try doing something like this;尝试做这样的事情;

  1. Declare a Client instead of your Parent which holds the type of processors in List<Processor<? extends Parent>> processors声明一个Client而不是你的Parent ,它在List<Processor<? extends Parent>> processors List<Processor<? extends Parent>> processors ; List<Processor<? extends Parent>> processors

     abstract class Client<T extends Client<T>> { List<Processor<T>> processors; public void doSmth(Message message) { for (Processor<T> processor : processors) { processor.doJob(getThis(), message); } } abstract T getThis(); public void registerListeners(Processor<T> subscribers) { this.processors = Arrays.asList(subscribers); } }
  2. Change your Processor definition to incorporating Client rather that Parent将您的Processor定义更改为合并Client而不是Parent

     interface Processor<T extends Client<T>> extends BiFunction<T, Message, Boolean> { AtomicReference<Boolean> ok = new AtomicReference<>(false); default void doJob(T client, Message message) { if (apply(client, message)) ok.set(true); } default boolean isDone() { return ok.get(); } }
  3. Now you can create your Child like this;现在你可以像这样创建你的Child

     class Child extends Client<Child> { boolean callSomeChildMethod() { return true; } @Override Child getThis() { return this; } }
  4. And call them the same way you did before;并像以前一样称呼它们;

     Child childInstance= new Child(); //where Child class extends Parent childInstance.registerListeners((child, message) -> child.callSomeChildMethod()); childInstance.doSmth(message);

This way you have neither compile errors nor warnings这样你既没有编译错误也没有警告

You could simply cast the processor object to declare that you want to pass it an object of a class derived from Parent (it could be Child ), and cast this to the same type.你可以简单地把processor对象申报要经过它派生的类的对象Parent (也可能是Child ),投this同一类型。 It can even be generic:它甚至可以是通用的:

private <T extends Parent> void doSmth() {
    for (Processor<? extends Parent> p : processors) {
        Processor<T> processor = (Processor<T>) p; // explicit cast
        processor.doJob((T) this);  //no compile error
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM