简体   繁体   English

为什么超类实现了应该由子进程实现的接口方法?

[英]Why does a superclass implement interface methods which are supposed to be implemented by the child?

Here is a parent class 这是一个父类

public class Parent {
    public void f() {

    }
}

Here is a simple interface 这是一个简单的界面

public interface If {
    public void f();
}

Here is a child class 这是一个儿童班

public class Child extends Parent implements If{}

My question is: Although it is Child which claims to implement the interface If , the interface method is implemented in Parent . 我的问题是:虽然它是声称实现接口If Child ,但接口方法是在Parent实现的。 Why is this allowed? 为什么允许这样做?

Why is this allowed? 为什么允许这样做?

Because Child satisfies the contract. 因为Child满足合同。 The contract Child makes, by implementing If , is that it will provide a public f function that accepts no arguments and has no return value. Child通过实现If使得它将提供一个不接受任何参数且没有返回值的公共f函数。 It does that. 它做到了。 How it does it, in this case by inheriting it from a superclass, is irrelevant. 它是如何做到的,在这种情况下,通过从超类继承它,是无关紧要的。 The contract is satisfied, which is all that matters. 合同是满意的,这是最重要的。

the interface method is implemented in Parent 接口方法在Parent中实现

Not really, it just happens to have the f method. 不是真的,它碰巧有f方法。 If you did If inst = new Parent() you'd get get a compilation error, because Parent doesn't say it implements If (there's no implements If on it); 如果你做了If inst = new Parent()你会得到一个编译错误,因为Parent没有说它实现了If (没有implements If ); implementing If isn't part of its contract. 实施If不是其合同的一部分。 Child , on the other hand, does provide that contract, and so If inst = new Child() works just fine. 另一方面, Child 确实提供了合同,所以If inst = new Child()工作正常。

FWIW, you probably wouldn't do this on purpose , although there's arguably nothing wrong with it. FWIW,你可能不会故意这样做,尽管可以说没有任何问题。 But it could come up if it just happened that the superclass you want to use has a perfect fit for one of the methods in the interface you want to implement. 但是如果你想要使用的超类完全适合你想要实现的接口中的一个方法,它就会出现。

When that happens, you have three choices: 当发生这种情况时,您有三种选择:

  1. Do nothing and let Parent 's method directly implement the interface method. 什么都不做,让Parent的方法直接实现接口方法。

  2. Override Parent 's method even though you're not going to do anything differently, eg: 即使您不打算做任何不同的事情,也要覆盖Parent的方法,例如:

     @Override public void f() { super.f(); } 

    ...which really doesn't accomplish anything unless you have code you want to run prior to or after calling Parent 's f . ...除非你有想要在调用Parentf之前或之后运行的代码,否则它实际上没有任何成就。

  3. Override f and implement it yourself, ignoring Parent 's version. 覆盖f并自己实现它,忽略Parent的版本。 But that only makes sense if Parent 's f does something completely different from the interface method's f — in which case, you shouldn't be subclassing Parent in the first place, because if you reimplement f in terms of the interface's behavior, your f won't satisfy the Parent#f contract anymore (in terms of its behavior) and you'll break the "is a" rule for subclassing. 但是,如果Parentf与接口方法的f 完全不同 ,那只会有意义 - 在这种情况下,你不应该首先将Parent子类化,因为如果你根据接口的行为重新实现f ,你的f将不再满足Parent#f合同(就其行为而言),你将打破子类化的“是一个”规则。

So really, option 1 is perfectly reasonable if it happens organically. 所以,如果它有机地发生,那么选项1是完全合理的。 You just probably wouldn't set it up on purpose. 你可能不会故意设置它。

It is completely legal because when you implement the method, it works for both. 这是完全合法的,因为当您实现该方法时,它适用于两者。

From class perspective and from interface perspective. 从课堂角度和界面角度。 A single implementation would serve the both purpose and there is no point of ambiguity it. 单个实现既有两个目的,也没有任何含糊之处。

There is no way to restrict a Class or Interface to having same method signature, unless you have a relationship with them, but in this case there will be no problems. 没有办法限制类或接口具有相同的方法签名,除非您与它们有关系,但在这种情况下将没有问题。

The main point of an interface is to list a set of methods, which could be called on any object of a class implementing the interface. 接口的要点是列出一组方法,这些方法可以在实现接口的类的任何对象上调用。

By declaring that a class implements an interface you declare that this set of methods can be called on your class. 通过声明一个类实现一个接口,您声明可以在您的类上调用这组方法。

As soon as this is the case (eg in your example), there is no problem. 只要是这种情况(例如在您的示例中),就没有问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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