开发者

Java - For a given function foo(X i); in Interface X, why can't implementing class Y change it to foo(Y i)?

开发者 https://www.devze.com 2022-12-25 07:23 出处:网络
For example public interface X{ public void foo(X i); } public class Y implements X{//error: doesn\'t implement foo(X i)...

For example

public interface X{
    public void foo(X i);
}

public class Y implements X{//error: doesn't implement foo(X i)...
    public void foo(Y i){
        fooBar(foo);
    }
    ....
}

Why can't I do that? And ho开发者_如何转开发w can I change it so this is possible? What can I do to declare foo in X with a parameter, and then be able to use Y as the parameter type in Y?


Additionally to what Don Boyle said, you can't change it without hinting the compiler of the intention. You do this by introducing Generics to the interface, like so:

public interface X<T> {
    public void foo(T i);
}

public class Y implements X<Y> {
    public void foo(Y i){
        fooBar(foo);
    }
}


By changing the type of the input parameter in class Y, you have changed the signature of the method which means the compiler sees it as a completely different method.

A Java interface is like a contract. Anything implementing it must implement the exact methods it defines. By using a different method signature you are not really implementing the defined method and so you are breaking that contract.


Try something like

interface X<T extends X> {
    public void foo(T a);
}

class Y implements X<Y> {
    public void foo(Y a);
}


Suppose you had done as you want, and suppose Java allowed it. And let's say another class - call it Z - also implements X. Because Z implements X, and because of the definition of X, you must be able to call X.foo(z) for any Z z. But Y, which is an X, doesn't know what to do if you pass a Z to its foo(). That's why.


By implementing the interface X, you promise that you implement all methods on this interface, which means that your foo method can take an arbitrary X. Now if you would just accept Ys as the parameter to your foo method, you would not fully implement the interface as all other classes implementing X were not valid parameters for foo.


Because Interface specifies common behavior for all implementing classes. Let's say you'd have some other classes all implementing X you would expect that if you have object of class X you can call foo with parameter that is of class X (which can be any of it's subclasses or implementations) so let's say you'd have code like this:

class Z implements X {
  ...
}

Z z = new Z();
X x = new Y();
x.foo(z);

Which would be false since with your code foo would only accept arguments of class Y

0

精彩评论

暂无评论...
验证码 换一张
取 消