简体   繁体   English

Java实现的接口方法不能从子类访问

[英]Java implemented interface methods not accessible from subclass

Description of issue:问题描述:

When trying to run methods in a subclass that implements an interface, the compile will error out with the error当尝试在实现接口的子类中运行方法时,编译会报错

Main.java:5: error: cannot find symbol

This occurs regardless of package locations, code location (ie: all code in one file vs. split out into separate *.java files), or methods implemented.无论包位置、代码位置(即:一个文件中的所有代码与拆分为单独的 *.java 文件)或实现的方法如何,都会发生这种情况。

Example of the issue:问题示例:

I have 2 classes and an interface, A, B, and myInterface.我有 2 个类和一个接口 A、B 和 myInterface。 Class A is abstract while B inherits from A and implements myInterface.类 A 是抽象的,而 B 继承自 A 并实现了 myInterface。 The problem is, when I run my code, I cannot call any methods from the interface I implemented.问题是,当我运行我的代码时,我无法从我实现的接口调用任何方法。

interface myInterface {
  public void printSomething();
}

abstract class A {
  int aVal;

  A() {
    this.aVal = 0;
  }

  public int getVal() {
    return aVal;
  }
}

class B extends A implements myInterface {
  B() {
    super();
  }
}

public void printSomething() {
  System.out.println("Something");
}

class Main {
  public static void main(String[] args) {
    A bObj = new B();

    bObj.printSomething();
    // Throws
    // Main.java:5: error: cannot find symbol
    //       bObj.printSomething();
    //           ^
    // symbol:   method printSomething()
    // location: variable bObj of type A
    // 1 error
  }
}

For easier running and viewing, I have the same code as above saved here as well.为了更容易运行和查看,我也在这里保存了与上面相同的代码。

https://repl.it/repls/IdealMobileUserinterface https://repl.it/repls/IdealMobileUserinterface

Why is this happening, and how would I go about resolving the issue?为什么会发生这种情况,我将如何解决这个问题? I've stumped myself and my teacher trying to figure this one out.我已经难倒自己和我的老师试图解决这个问题。

I believe the issue is that you're putting everything into a class A reference, which doesn't implement myInterface, and so doesn't necessarily have a printSomething method to call.我相信问题在于您将所有内容都放入 A 类引用中,该引用没有实现 myInterface,因此不一定有要调用的 printSomething 方法。

You have an object of type A .您有一个A类型的对象。 And you're trying to call printSomething on it, but types of A don't necessarily have that method.并且您正在尝试对其调用printSomething ,但是A类型不一定具有该方法。 Only things that implement myInterface have that method.只有实现 myInterface 的东西才有那个方法。 So, you need to specifiy that A has that method.因此,您需要指定A具有该方法。

Or create a generic method that only works on types of A that implement that interface.或者创建一个仅适用于实现该接口的 A 类型的通用方法。

Let me try to answer this canonically.让我尝试规范地回答这个问题。

Here's your interfaces:这是您的接口:

interface iA {
    void fromA();
}
interface iB {
    void fromB();
}

and a class hierarchy.和一个类层次结构。

class cX implements iA {
    public void fromX() {}
    public void fromA() {} // to implement iA
}
class cY extends cX implements iB {
    public void fromY() {}
    public void fromB() {} // to implement iB
}

Note that cY also implicitly implements iA - it's handed down from inheriting from cX .请注意, cY还隐式implements iA - 它是从cX继承而来的。

Now let's look at what's valid.现在让我们看看什么是有效的。

cY cy = new cY();
cy.fromA();  // valid - cY extends cX implements iA
cy.fromB();  // valid - cY implements iB
cy.fromX();  // valid - cY extends cX
cy.fromY();  // valid - cy is a cY

cX cx = new cY(); // valid - cY extends cX
cx.fromA();  // valid - cx implements iA
cx.fromB();  // INVALID - cX does not implement iB. The compiler doesn't know cx is actually a cY instance.
cx.fromX();  // valid - cY extends cX
cx.fromY();  // INVALID - cX is not a cY

iA ia = new cY(); // valid cY extends cX implements iA
ia.fromA();  // valid - fromA() is an iA method
ia.fromB();  // INVALID - iA is not a cY
ia.fromX();  // INVALID - iA does not have that method. Again, compiler doesn't know ia is a cY instance.

Since you ask about "polymorphism" in the comments: this is the polymorphism part:由于您在评论中询问“多态性”:这是多态性部分:

iA v = new cY();  // can assign a cY instance to an iA variable
v = new cX();     // can assign a cX instance to an iA variable

This is also the reason you can't now call v.fromX() or v.fromY() ;这也是你现在不能调用v.fromX()v.fromY() v can have been assigned either, so only the common denominator is available - namely the iA methods. v也可以被赋值,所以只有公分母可用——即iA方法。

由于您在类 A 中没有方法 printSomething() 并且您使用类 A 的引用来保存子对象 B,因此根据继承原则,您无法使用父引用访问子特定方法。

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

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