【问题标题】:Creating object with reference to Interface参照接口创建对象
【发布时间】:2013-02-06 11:28:58
【问题描述】:

引用变量可以声明为类类型或接口类型。如果变量声明为接口类型,则它可以引用任何实现该接口的类的任何对象。

根据上面的说法,我做了一个代码理解。如上所述声明为接口类型,它可以引用任何实现该接口的类的任何对象

但在我的代码中显示displayName() 方法未定义在objParent.displayName():

public class OverridenClass {
    public static void main(String[] args) {
        Printable objParent = new Parent();
        objParent.sysout();
        objParent.displayName();
    }
}

interface Printable {
    void sysout();
}

class Parent implements Printable {
    public void displayName() {
        System.out.println("This is Parent Name");
    }

    public void sysout() {
        System.out.println("I am Printable Interfacein Parent Class");
    }
}

我确定我理解错了。有人可以解释一下吗?

【问题讨论】:

  • 您只能访问在创建引用的接口上定义的方法。所以在你的情况下,只有 sysout() 方法被成功调用。

标签: java class oop inheritance


【解决方案1】:

但在我的代码中显示的是未定义的 displayName() 方法。

对,因为displayName 没有在Printable 接口中定义。您只能通过声明为具有该接口的变量访问接口上定义的方法,即使具体类具有其他方法。这就是为什么你可以打电话给sysout,但不能打电话给displayName

如果您考虑这样的示例,其原因会更明显:

class Bar {
    public static void foo(Printable p) {
        p.sysout();
        p.displayName();
    }
}

class Test {
    public static final void main(String[] args) {
        Bar.foo(new Parent());
    }
}

foo 中的代码不得依赖于 Printable 接口中的功能以外的任何内容,因为我们在编译时不知道具体类可能是什么。

接口的意义在于仅使用接口引用来定义代码可用的特性,而不考虑所使用的具体类。

【讨论】:

  • 但是在 kathy bates 中,如果变量被声明为接口类型,它可以引用任何实现该接口的类的任何对象。它们究竟是什么意思的任何实现的类的任何对象界面
  • 他们的意思是它可以保存实现该接口的任何对象,但是要访问在实现器中定义的附加方法,您需要对其进行类型转换。看我的回答
  • @JavaBeginner:它可以引用任何实现接口的对象,但它只能使用接口定义的对象的特性。这就是拥有接口引用的重点:避免耦合到任何特定的具体类。
  • @T.J. Crowder - 你的意思是没有 Casting
  • @JavaBeginner:是的,但是如果你不得不求助于强制转换,那么你的代码很可能需要重构。使用接口的目的是对接口进行编码,而不是依赖具体类的特性。如果您需要使用具体类的功能,请使用该类而不是接口来声明您的变量。
【解决方案2】:

您需要键入强制转换才能访问Parent 方法

((Parent)objParent).displayName();

【讨论】:

  • 感谢回复 Eclipse 建议相同
  • 欢迎 :) 希望对您有所帮助
  • @JavaBeginner:没有点这样做。您也可以简单地将objParent 声明为Parent
【解决方案3】:

displayName() 方法显示为未定义,因为objParent 声明为Printable 类型并且接口没有该方法。为了能够使用方法displayName(),您可以在接口Printable中声明它:

interface Printable {
    void sysout();
    void displayName();
}

或者在调用方法displayName()之前先将objParent转换成Parent

Printable objParent = new Parent();
objParent = (Parent) objParent;
objParent.displayName();

【讨论】:

    【解决方案4】:

    编译器不关心运行时。就编译器而言,它会检查引用类型在您的接口类型中是否有一个名为 display 的方法。

    在您的子类或实现类中声明的方法不是一部分 你的超级类/接口。因此你不能调用这些方法 在具有超类/接口引用的子类中声明 输入。

    【讨论】:

      【解决方案5】:

      接口基本上是另一种方式 - 打破单一继承的规则。

      通过使用接口,子类既可以继承它的父方法,又可以强制实现它的接口方法。产生易于扩展和维护的继承树等。

      然而,问题是,当在父级下引用子级时,您只能访问父级方法。要访问接口方法,您需要在接口引用类型下强制转换或创建子项。

      接口还允许将不同族的多个类集合到接口类型下。有什么好处我还没有发现。

      在我看来,这是没有意义的,因为无论如何我仍然无法实现完全成熟的多态性 - 仅使用父引用类型并且仍然可以访问接口实现。

      【讨论】:

        【解决方案6】:

        该接口的方法签名驻留引用不会给出任何错误。在您的示例中,您的方法 sysout() 在接口中,因此接口的引用不会给出任何错误,但对于方法 displayName() 接口引用会给出错误。为此,您必须使用您的课程参考。

        【讨论】:

          猜你喜欢
          • 2011-10-28
          • 1970-01-01
          • 1970-01-01
          • 2015-05-21
          • 2011-01-12
          • 2013-08-28
          • 2019-11-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多