我遇到了这个问题:
下面的输出是什么?
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
关键字的意思是:实例化。
i=new I() {}; 创建一个实现接口I的匿名类。由于接口I没有任何抽象方法要实现,括号{}内的匿名类的主体可以是空的。
我不明白是因为它加了“{}”吗?
您正在实例化匿名类
I i = new I() {};
这句话没有错:
I i = new I() {};
它只是实例化一个实现I
接口的匿名类。由于I
接口只有默认方法,如果不是因为toString()
方法的问题,一个空体就足以实现它。
JLS 9.4.1.2规定接口不能有toString()
方法的默认实现:
如果默认方法的重写等价于类对象的非私有方法,则这是编译时错误,因为实现接口的任何类都将继承其自己的方法实现。
禁止将Object方法之一声明为默认方法可能令人惊讶。毕竟,有像java.util.List这样的情况,其中toString和equals的行为是精确定义的。然而,当一些更广泛的设计决策被理解时,动机就变得更加清晰了:
toString()
是对象
类的方法,因此在任何接口中都不能有默认实现。
在搜索Java语言规范来回答这个问题时,我了解到 在初始化一个类之前,必须初始化它的直接超类,但是该类实现的接口没有初始化。类似地,在初始化接口之前,不会初始化接口的超级接口。 出于我自己的好奇心,我尝试了它,正如预期的那样,接口没有初始化。 这个程序打印 但是,如果接口声明了一个方法,则会发生初始化。考虑<代码>接口类型>代码>接口 然后上面相同的程序会打印 换句话说,初始化接口的字段(详细初始
具有默认方法的接口将被初始化,即使重写了此方法,并且根本没有调用该方法。 示例: 印刷品: 这里到底有什么问题?
下面是一个简单的例子,展示了我的问题: 在中,我提供了方法和的实现,这是来自的唯一抽象方法。但是,当我编译时,我仍然会遇到以下错误: 类型MyWork必须实现继承的抽象方法AbstractCollection.size() 或者 我的任务。java:3:错误:MyTask不是抽象的,并且不重写AbstractList中的抽象方法get(int) (取决于编译器)。当然,我使用的是java 8。 所
问题内容: 考虑以下情况, 在上面的例子中我得到以下输出这是 相当 期待。 我一直在阅读有关默认方法的信息, 尤其是 关于扩展包含默认方法的接口的信息 2 第二子弹:重新声明的默认方法,这使得它的抽象。 在上面的示例中,我有两个接口的默认方法具有相同的名称,并且当我实现这两个接口时,我只能实现对的引用。 我对此几乎没有疑问, 我怎样才能 到达 的方法 和 如果我不能比,为什么? 没有这种行为从本质
我试图使用以下代码理解Java接口中的默认方法,但我无法编译它: 编译器生成了以下输出: 我无法理解这些错误。我如何更正代码中的问题?
我想通过创建一个具体实现类的对象来执行接口中默认方法的定义体,该对象也覆盖了该方法。无论我是直接创建具体实现类的对象,还是通过动态绑定/多态,实现类中定义/重写的主体都只是得到执行。请看下面的代码 我想知道如何在控制台内部界面银行打印以下内容--loan()