8

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

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

但在我的代码中显示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");
    }
}

我确信我理解错误的方式。有人可以解释一下吗?

4

6 回答 6

9

但在我的代码中显示未定义的 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接口中的特性以外的任何东西,因为我们在编译时不知道具体类可能是什么。

接口的要点是仅使用接口引用来定义代码可用的特征,而不考虑正在使用的具体类。

于 2013-02-21T08:01:29.777 回答
3

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

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

或在调用方法之前先objParent转换为类型:ParentdisplayName()

Printable objParent = new Parent();
objParent = (Parent) objParent;
objParent.displayName();
于 2013-02-21T08:08:43.350 回答
2

您需要输入强制类型才能访问Parent方法

((Parent)objParent).displayName();
于 2013-02-21T08:02:32.713 回答
1

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

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

于 2013-02-21T08:02:18.657 回答
0

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

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

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

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

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

于 2014-08-07T13:30:06.220 回答
0

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

于 2018-07-28T09:24:11.523 回答