简体   繁体   English

类如何将其超类的方法视为接口方法的实现?

[英]How does a class consider its super class's method as it's interface method's implementation?

Instead of talking theory, let me directly jump to the example to demonstrate what I'm trying to ask. 让我直接讨论示例,而不是讲理论,以演示我要提出的问题。

// The below piece of code is present in a single java file named "MyMain.java"
public class MyMain {
    public static void main(String args[]) {
        IFace iFace = new CSub();
        iFace.method(); // This method essentially belongs to CSuper which doesn't implement IFace
    }
}

interface IFace {
    void method(); // Method in the interface
}

class CSuper {
    public void method(){ // some method in this class, but not the one which implements the method of IFace
        System.out.println("I'm not implementing IFace's method");
    }
}

class CSub extends CSuper implements IFace {} // No method implemented in the class and yet no error.

Obviously the above piece of code works as I was able to get the output I'm not implementing IFace's method upon execution. 显然,上面的代码可以正常工作,因为我能够在执行时获得未实现IFace方法的输出。

My question is, how does CSub take the method() of CSUper as the implementation of the method() of IFace interface. 我的问题是,如何CSubmethod()CSUper作为实施method()IFace接口。 It seems like inheritance is the one behind this, but I need some concrete answer for that. 似乎继承是背后的原因,但是对此我需要一些具体的答案。 And also, is there a JLS reference for this which can clarify how this is possible via inheritance? 而且,是否有JLS参考可以澄清如何通过继承来实现?


And a follow up question for that is, say there is some reason why this works(As I'm guessing that it is inheritance but need to be sure about it), why doesn't the same code snippet work if I do either of the below changes? 还有一个后续问题,就是说这样做有一定原因(因为我猜想它是继承的,但需要确定),如果我做任何一个,为什么相同的代码片段不起作用下面的变化?

Change 1: 变更1:

class CSuper {
    void method(){ // there is no access specifier, thus default(package)
        System.out.println("I'm not implementing IFace's method");
    }
}

Change 2: 变更2:

class CSuper {
    protected void method(){ // access specifier is now protected
        System.out.println("I'm not implementing IFace's method");
    }
}

For both the above changes I do, I get an compilation error saying The inherited method CSUper.method() canoot hide the public abstract method in IFace on this line 对于我所做的上述两个更改,我收到一个编译错误,指出继承的方法CSUper.method()无法在IFace的这行上隐藏公共抽象方法

class CSub extends CSuper implements IFace {}

Why is it so? 为什么会这样呢? Since it is inheritance, both protected and default access specifier should work, as all the classes are present in the very same file. 由于它是继承,因此protected访问说明符和默认的访问说明符都应该起作用,因为所有类都存在于同一文件中。 And method() must have been inherited to the CSub class, just like how it did in the part one of the question. 而且method()必须已经继承到CSub类,就像它在问题的第一部分中所做的一样。 Can anybody highlight on this case too? 有人也可以强调此案吗?

Tim's answered most of this. 蒂姆回答了大部分问题。 For the JLS reference, from section 8.1.5 : 对于JLS参考,请参见第8.1.5节

Unless the class being declared is abstract, the declarations of all the method members of each direct superinterface must be implemented either by a declaration in this class or by an existing method declaration inherited from the direct superclass , because a class that is not abstract is not permitted to have abstract methods (§8.1.1.1). 除非要声明的类是抽象类,否则每个直接超接口的所有方法成员的声明都必须通过此类中的声明或通过从直接超类继承的现有方法声明来实现 ,因为非抽象类不是允许具有抽象方法(第8.1.1.1节)。

The answer to part 1 is quite simple - the Interface simply requires that the class the Interface is part of implement a method with that signature. 第1部分的答案非常简单-接口仅要求接口类是实现具有该签名的方法的一部分。

It doesn't care where the method is actually defined - so long as it exists then the Interface is valid. 不管方法在哪里实际定义-只要它存在,接口就有效。

The reason for that is fairly obvious as well. 原因也很明显。 All the Interface is saying is "any object with this interface, you can call a function called X with parameters Y and it will return Z". 该接口的全部意思是“具有该接口的任何对象,您可以使用参数Y调用一个名为X的函数,它将返回Z”。 By inheriting that method from a super class you are meeting that requirement. 通过从超类继承该方法,您可以满足该要求。

This also answers part 2. To implement an Interface the implementing method must be Public - so anyone can access it. 这也回答了第2部分。要实现接口,实现方法必须是公共的-任何人都可以访问它。

By making the super class method package private or protected it is no longer meeting the requirement. 通过使超类方法包私有或受保护,它不再满足要求。

class CSub extends CSuper implements IFace {
     public method() {
         super.method();
     }
}

By doing that you can make the method public (making access more broad through inheritance is allowed, you just can't make things more restricted) and it will now satisfy the interface again. 通过这样做,您可以将方法公开(允许通过继承使访问范围更广,只是不能使事情受到更多限制),现在它将再次满足该接口。

The access restrictions are part of the method signature. 访问限制是方法签名的一部分。 To explain why think about a class being handed an IFace x . 为了解释为什么要考虑将类交给IFace x They will then try to call x.method() which is defined in the Interface. 然后,他们将尝试调用接口中定义的x.method()

If they are not in the same package as your implementation they still need to be able to call x.method() . 如果它们与您的实现不在同一个程序包中,则它们仍需要能够调用x.method() Because of this x.method() must be public in order to satisfy the interface - since otherwise people can get an IFace but the method will not be available to them. 因此, x.method()必须是公共的才能满足该接口的要求-因为否则人们可以获得IFace但该方法将对他们不可用。

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

相关问题 Java 接口未考虑超级 class 的方法实现 - Java Interface does not take into consideration method implementation from the super class 如何从 super 的关联 class 调用子类方法 - How to call a subclass method from super's associated class 为什么java.lang.Class的getInterfaces()方法返回Class <?> []而不是班级 <? super T> []? - Why does java.lang.Class's getInterfaces() method return Class<?>[] and not Class<? super T>[]? 方法不会覆盖其父类中的方法 - Method doesnot override method from it's super class 重写方法时调用超类的方法的目的是什么? - What is the purpose of calling super class's method while overriding a method? 子类的方法是否指“this”,是否也指超级 class? - Does a child class's method refers to "this", does it also refer to the super class? 无法覆盖子类中超类的方法 - Can't override super class's method in sub class 无法在初始化为超类的 ArrayList 中调用派生类的方法 - Unable to call derived class's method in ArrayList initialized to super class 哪个类在运行时实现接口的方法 - Which class implements interface's method at runtime 为什么继承的公共方法操纵父类的私有属性而不是子类? - Why does inherited public method manipulate the super class's private property instead of the child class?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM