How can I refer to the class type a interface is implementing in Java?

后端 未结 4 1407
一生所求
一生所求 2020-12-05 07:31

I came to a problem with interfaces in a program I\'m making. I want to create a interface which have one of its methods receiving/returning a reference to the type of the o

相关标签:
4条回答
  • 2020-12-05 08:14

    I was wondering if there are any other way to do so?

    You can write it as follows:

    public interface I {
       I getSelf();
    }
    

    and then cast the result to the type you want. Your existing A and B classes will work as-is.

    (This is an example of return type covariance. Support for return type covariance was added in Java 5. This approach will give compilation errors in older JDKs.)

    The alternative version (you call it a work-around, but it isn't really) that uses generics allows you to avoid the explicit typecast. However, there is an implicit typecast in the generated code, and at runtime ... unless the JIT compiler can optimize it away.

    There are no better alternatives, AFAIK.

    0 讨论(0)
  • 2020-12-05 08:20

    There is a way to enforce using ones own class as a parameter when extending an interface:

    interface I<SELF extends I<SELF>> {
        SELF getSelf();
    }
    
    class A implements I<A> {
        A getSelf() {
            return this;
        }
    }
    
    class B implements I<A> { // illegal: Bound mismatch
        A getSelf() {
            return this;
        }
    }
    

    This even works when writing generic classes. Only drawback: one has to cast this to SELF.

    As Andrey Makarov noted in a comment below this does not work reliably when writing generic classes.

    class A<SELF extends A<SELF>> {
        SELF getSelf() {
            return (SELF)this;
        }
    }
    class C extends A<B> {} // Does not fail.
    
    // C myC = new C();
    // B myB = myC.getSelf(); // <-- ClassCastException
    
    0 讨论(0)
  • 2020-12-05 08:22

    As others have said, you can override the return type in the implementing classes:

    public interface I {
        public I getSelf();
    }
    
    public class A implements I {
        @Override
        public A getSelf() {
            return this;
        }
    }
    

    However, I have two 'why' questions for you:

    1: Why do you want an Interface to return the implementing object? It seems to run against the general ideas of interfaces and inheritance to me. Can you show an example of how this might be used?

    2: In any case, why would you want this function? If a.getSelf() == a, why not just use a?

    0 讨论(0)
  • 2020-12-05 08:26

    Java supports covariant return types, so that's one option. Take advantage of the fact that both A and B are derived from Object:

    public interface I {
        Object getSelf();  // or I, see below
    }
    public class A implements I {
        A getSelf() { return this; }
    }
    public class B implements I {
        B getSelf() { return this; }
    }
    

    The point is that both A.getSelf() and B.getSelf() are legitimate overrides of I.getSelf(), even though their return type is different. That's because every A can be treated like an Object, and so the return type is compatible with that of the base function. (This is called "covariance".)

    In fact, since A and B are also known to derive from I, you can replace Object by I for the same reasons.

    Covariance is generally a Good Thing: Someone who has an interface object of type I can call getSelf() and get another interface, and that's all she needs to know. On the other hand, someone who already knows he has an A object can call getSelf() and will actually get another A object back. The additional information can be used to get a more specific derived type, but someone who lacks that information still gets everything that's prescribed by the interface base class:

    I x = new A();
    A y = new A();
    
    I a = x.foo();    // generic
    A b = y.foo();    // we have more information, but b also "is-an" I
    A c = (A)x.foo(); // "cheating" (we know the actual type)
    
    0 讨论(0)
提交回复
热议问题