简体   繁体   中英

Parameterizing superclass with static member class from subclass

Is there a way to parameterize a superclass with a static member class of the subclass?

Contrived Example

ExampleSuperClass.java :

package foo;

public class ExampleSuperClass<T> {
    protected T field;

    public ExampleSuperClass(T field) {
        this.field = field;
    }

    public T getField() {
        return field;
    }
}

ExampleSubClass.java :

package foo;

public class ExampleSubClass extends ExampleSuperClass<Member> {

    static class Member {

    }

    public ExampleSubClass() {
        super(new Member());
    }
}

Compilation fails on ExampleSubClass.java with error:

 [javac] ExampleSubClass.java:3: error: cannot find symbol [javac] public class ExampleSubClass extends ExampleSuperClass<Member> { [javac] ^ [javac] symbol: class Member [javac] 1 error 

or in Eclipse with:

Member cannot be resolved to a type

in Eclipse the super invocation also has the error:

The constructor ExampleSuperClass(Member) refers to missing type Member


It works fine (aka no errors) if ExampleSubClass is instead parameterized with another package-protected top-level class.


Summary

The driving force behind this is that I have a generic super class and many different ${SubClass-extends-GenericSuperClass}.java and ${ClassUsedBySubClass}.java pairs. But since ClassUsedBySubClass is only ever referenced by SubClass , it would be nice to:

  1. restrict ClassUsedBySubClass 's access by making it a static member class and
  2. cut down on the number of files by not giving ClassUsedBySubClass its own file.

So, is there a way to use a subclass's member class in parameterizing the superclass?

If there isn't -- is there an alternative approach?

Yes, you can do it. However, since Java uses the scope outside the declaration for name resolution, you must qualify Member with the name of ExampleSubClass :

public class ExampleSubClass extends ExampleSuperClass<ExampleSubClass.Member> {
    ...
}

Because Member is an inner class, you need to specify that when using it as a generic type. I'm able to get it to compile by using the following:

static class ExampleSubClass extends  ExampleSuperClass<ExampleSubClass.Member> {
    static class Member {

    }

    public ExampleSubClass() {
        super(new Member());
    }
}

Member is a static nested class. Static nested class is accessed using the enclosing class name:

ExampleSubClass.Member

You do this every time a static nested class occurs outside the scope of its outer class.

Therefore, the following is correct:

public class ExampleSubClass extends ExampleSuperClass<ExampleSubClass.Member> {
                                                              ^
                                                     enclosing class name
    static class Member {
        ...
    }
}

Same as when you want to create an object for the static nested class:

ExampleSubClass.Member member = new ExampleSubClass.Member();

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