当前位置: 首页 > 知识库问答 >
问题:

实例化具有默认方法的接口[重复]

施越彬
2023-03-14

我遇到了这个问题:

下面的输出是什么?

1  public class A {
2      public static void main(String[] args){
3          I i = new I() {};
4          System.out.println(I.x + i.getValue() + "" + i);
5      }
6  }
7
8  interface I {
9      int x = 10;
10
11     public default int getValue() {
12         return 5;
13     }
14
15     public default String toString() {
16         return "I";
17     }
18 }

我的想法是:

我的第一直觉告诉我-i=new I(){}?因此,我们不能实例化接口-问题1。

那么我认为公共默认字符串是toString()?重写对象类方法?听起来不太好-问题2

可能的答案:

a)10I

b) 15I

c)由于第11行编译失败

d)由于第15行编译失败

e)由于多个错误导致编译失败

解释完我的想法后,我选择了错误的答案。正确答案是D,我也答对了。

我的问题-为什么下面的陈述是有效的?

I i = new I() {};

由于添加了“{}”,该语句是否正在做一些我不理解的事情?据我所知,new关键字的意思是:实例化。

共有3个答案

昝欣可
2023-03-14

i=new I() {}; 创建一个实现接口I的匿名类。由于接口I没有任何抽象方法要实现,括号{}内的匿名类的主体可以是空的。

王伯寅
2023-03-14

我不明白是因为它加了“{}”吗?

您正在实例化匿名类

I i = new I() {};
呼延河
2023-03-14

这句话没有错:

I i = new I() {};

它只是实例化一个实现I接口的匿名类。由于I接口只有默认方法,如果不是因为toString()方法的问题,一个空体就足以实现它。

JLS 9.4.1.2规定接口不能有toString()方法的默认实现:

如果默认方法的重写等价于类对象的非私有方法,则这是编译时错误,因为实现接口的任何类都将继承其自己的方法实现。

禁止将Object方法之一声明为默认方法可能令人惊讶。毕竟,有像java.util.List这样的情况,其中toString和equals的行为是精确定义的。然而,当一些更广泛的设计决策被理解时,动机就变得更加清晰了:

  • 首先,允许从超类继承的方法重写从超接口继承的方法(§8.4.8.1)。因此,每个实现类都会自动覆盖接口的toString默认值。这是Java编程语言中的长期行为。我们不希望通过默认方法的设计来改变它,因为这将与允许接口不引人注目地进化的目标相冲突,只有当类还没有通过类层次结构时才提供默认行为。
  • 其次,接口不继承Object,而是隐式声明许多与Object相同的方法(§9.2)。因此,在Object中声明的toString和在接口中声明的toString没有共同的祖先。充其量,如果两者都是一个类继承的候选人,它们就会冲突。解决这个问题需要笨拙地混合类和接口继承树。
  • 第三,在接口中声明Object方法的用例通常假设一个线性接口层次结构;该特性不能很好地推广到多个继承场景。
  • 第四,Object方法是如此基本,以至于允许任意超级接口默默地添加默认方法来更改其行为似乎是危险的。

toString()对象类的方法,因此在任何接口中都不能有默认实现。

 类似资料:
  • 在搜索Java语言规范来回答这个问题时,我了解到 在初始化一个类之前,必须初始化它的直接超类,但是该类实现的接口没有初始化。类似地,在初始化接口之前,不会初始化接口的超级接口。 出于我自己的好奇心,我尝试了它,正如预期的那样,接口没有初始化。 这个程序打印 但是,如果接口声明了一个方法,则会发生初始化。考虑<代码>接口类型>代码>接口 然后上面相同的程序会打印 换句话说,初始化接口的字段(详细初始

  • 具有默认方法的接口将被初始化,即使重写了此方法,并且根本没有调用该方法。 示例: 印刷品: 这里到底有什么问题?

  • 下面是一个简单的例子,展示了我的问题: 在中,我提供了方法和的实现,这是来自的唯一抽象方法。但是,当我编译时,我仍然会遇到以下错误: 类型MyWork必须实现继承的抽象方法AbstractCollection.size() 或者 我的任务。java:3:错误:MyTask不是抽象的,并且不重写AbstractList中的抽象方法get(int) (取决于编译器)。当然,我使用的是java 8。 所

  • 问题内容: 考虑以下情况, 在上面的例子中我得到以下输出这是 相当 期待。 我一直在阅读有关默认方法的信息, 尤其是 关于扩展包含默认方法的接口的信息 2 第二子弹:重新声明的默认方法,这使得它的抽象。 在上面的示例中,我有两个接口的默认方法具有相同的名称,并且当我实现这两个接口时,我只能实现对的引用。 我对此几乎没有疑问, 我怎样才能 到达 的方法 和 如果我不能比,为什么? 没有这种行为从本质

  • 我试图使用以下代码理解Java接口中的默认方法,但我无法编译它: 编译器生成了以下输出: 我无法理解这些错误。我如何更正代码中的问题?

  • 我想通过创建一个具体实现类的对象来执行接口中默认方法的定义体,该对象也覆盖了该方法。无论我是直接创建具体实现类的对象,还是通过动态绑定/多态,实现类中定义/重写的主体都只是得到执行。请看下面的代码 我想知道如何在控制台内部界面银行打印以下内容--loan()