Java forced type narrowing?

In Java, you can narrow the return type in override methods.

But is this narrowing possible during the announcement?

For example, this may be good in a template where the inner class is subclassed simultaneously with the outer one:

public class Try_ForceNarrow {

    public interface IMember {

    }

    public interface Container<M extends IMember> {
        M createMember();
    }

    public static class A implements Container<A.Member> {

        @Override
        public Member createMember() {
            return new Member();
        }

        public class Member implements IMember {
        }
    }

    public static class B extends A implements Container<B.Member> {

        @Override
        public Member createMember() {
            return new Member();
        }

        public class Member extends A.Member {

        }

    }

    public static void main(String[] args) {

    }

}

This code was not compiled with the error "The interface container cannot be implemented several times with different arguments."

How to avoid this?

Of course I can just write

public static class B extends A  {

        @Override
        public Member createMember() {
            return new Member();
        }

        public class Member extends A.Member {

        }

    }

But in this way I can forget to override createMember()and break the pattern.

+4
source share
4 answers

What about A<T> implements Container<T>? You can limit T further as you like ...

0

, , C createMember factory, . , C1 factory, C1, C2 extends C1, C2 - C1.

, , , , , -, :

abstract class MemberBase {

    protected abstract MemberBase doCreateMember();
    protected abstract Class<?> memberClass();

    public MemberBase createMember() {
         MemberBase result = doCreateMember();
         if (result.getClass() != memberClass()) {
             throw new RuntimeException("createMember returned the wrong class");
         }
         return result;
    }

}
public static class A extends MemberBase {

    @Override
    protected Member doCreateMember() {
        return new Member();
    }

    @Override
    protected Class<?> memberClass() {
        return Member.class;
    }

    public class Member implements IMember {
    }
}
public static class B extends A {

    // If you forget to define this, the doCreateMember in A will be
    // inherited, but it will return the wrong class and lead to a
    // run-time exception
    @Override
    protected Member doCreateMember() {
        return new Member();
    }

    @Override
    protected Class<?> memberClass() {
        return Member.class;
    }

    public class Member extends A.Member {
    }
}

, , , . , , . , , .

0

, , .

, Container, , static:

class Try_ForceNarrow {

    public interface IMember {

    }

    public interface Container<M extends IMember> {
        M createMember();
    }

    //The abstract class that lets you continually extend or "narrow"
    public static abstract class A<E extends A.Member> implements Container<E> {

        public static class Member implements IMember {
        }
    }

    //Here is the first class that extends the Abstract Class A
    public static class B extends A<B.Member> { //This class now Implements Container<B.Member>

        @Override
        public Member createMember() {
            return new Member();
        }

        //Since this is the first extension we will extend A.Member
        public static class Member extends A.Member {

        }

    }

    //This is an additional class that extends A but we want to extend the functionality of B.Member also.
    public static class C extends A<C.Member> { //This class now Implements Container<C.Member>


        @Override
        public Member createMember() {
            return new Member();
        }

        //C.Member properly extends B.Member
        //if this class is going to be extended this needs to be static
        public class Member extends B.Member {

        }

    }
}

, , ,

@Override
public Member createMember() {
    return new Member();
}

.

0

, , A Container<A.Member>, B A, Container<B.Member>, class B extends A implements Container<A.Member> Container<B.Memeber>, Container<A.Member> Container<B.Member> - , , , , , , B class B extends A implements Container Container, . , , bridge method VM Generics.

-1
source

All Articles