简体   繁体   中英

Is there a way to make two classes to use the same generic?

This code is illegal because Bar cannot use the generic T since it belongs to Foo, and Bar is static. :(

public interface Foo<T> {
    public interface Bar {
        public void bar(T t);
    }

    void foo(T t, Bar bar);
}

My question is, is there a reasonable workaround to this problem? I really need Foo and Bar to use the same generic type since Bar is a listener class for Foo and needs to return the same type. Of course I could use two generics (eg Bar<P> ) and always assign the same type to T and P, but that is funky and error prone. Is there a cleaner solution?

The solution is to make Bar generic:

public interface Foo<T> {
    public interface Bar<T> {
        public void bar(T t);
    }
    ...
}

Or, if you want to call the type parameter something different:

public interface Foo<T> {
    public interface Bar<U> {
        public void bar(U t);
    }
    ...
}

There's really nothing error-prone about it. If you need a method to, say, register a listener, it would look like:

public interface Foo<T> {
    public interface Bar<U> {
        public void bar(U t);
    }

    public void addListener(Bar<T> listener);
}

This would ensure that, if you add a listener to an instance of something that implements Foo<T> , then the listener must be something that implements Bar<T> with the same generic parameter (if you don't use raw types).

Why bother with the nested interface? Promote that to the top level, and then compose it into the Foo class.

Bar.java

public interface Bar<T> {
    void bar(T t);
}

Foo.java

public class Foo<T> {
    private Bar<T> bar;

    void foo(T t) {

    }

    void bar(T t) {
        this.bar.bar(t);
    }
}

There is no such thing as a non-static interface.

For classes you can have the desired behavior:

class A<T> {
  class B {
    void test(T works) { }
  }
}

for interfaces, you will need to use

interface A<T> {
  interface B<T> {
    void test(T works) { }
  }
}

which is essentially the same as:

interface A<T> {
}

interface B<T> {
  void test(T works) { }
}

Essentially, interfaces are always static , and static classes (and interfaces) do not inherit the parents generics , because it violates the concept of being static ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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