我正在测试Java中默认关键字的功能和滥用。我决定测试多继承,如果我在接口和实现接口的类中声明了两个相同名称和签名的变量,会发生什么。
import java.util.*;
import java.lang.*;
import java.io.*;
interface Foo {
default void Meh() {
System.out.println("Foo.Meh");
}
}
interface Bar {
String test="t";
default String getTest(){
return test;
}
default void doTest(){
System.out.println("Bar.doTest: -- getTest" + getTest());
}
default void Bar() {
System.out.println("Bar.Bar()");
String blahh=test;
}
static void Sup(){
System.out.println("Bar.Sup -- Test: "+test);
}
default void Meh() {
System.out.println("Bar.Meh -- Test: "+test);
}
default void mega() {
Meh();
}
}
abstract class Test {
public void Meh() {
System.out.println("Test.Meh");
}
}
class Ideone extends Test implements Foo, Bar {
public static void main (String[] args) throws java.lang.Exception
{
new Ideone().Meh();
blah();
}
public void Meh() {
Bar.super.Bar();
Bar.super.Meh();
System.out.println("Ideone.Meh -- Test: "+test);
Foo.super.Meh();
super.Meh();
Bar hack = new Bar(){
public static final String test="over";
public String getTest(){
System.out.println("Ideone.Meh.hack.super.test: " + Bar.super.getTest());
return test;
}
public void Meh(){
System.out.println("Ideone.Meh.hack.Meh()");
func();
Bar.Sup();
Bar.super.Meh();
}
public void func(){
System.out.println("Ideone.Meh.hack.func -- Test: "+test);
}
};
hack.Meh();
System.out.println("Ideone.Meh.hack.test: " + hack.test);
hack.mega();
hack.doTest();
}
public static void blah() {
}
}
结果:
Bar.Bar()
Bar.Meh -- Test: t
Ideone.Meh -- Test: t
Foo.Meh
Test.Meh
Ideone.Meh.hack.Meh()
Ideone.Meh.hack.func -- Test: over
Bar.Sup -- Test: t
Bar.Meh -- Test: t
Ideone.Meh.hack.test: t
Ideone.Meh.hack.Meh()
Ideone.Meh.hack.func -- Test: over
Bar.Sup -- Test: t
Bar.Meh -- Test: t
Ideone.Meh.hack.super.test: t
Bar.doTest: -- getTestover
Bar hack
如何能够拥有一个名为test
的变量,其值为over
,同时还有一个名为test
的变量,其值为t
Bar hack = new Bar();
?
此外,Bar
是继承自己吗?如果hack是super
的实例,那么它如何具有Bar
类型test
且包含不同的<script src="js/eskju.jquery.scrollflow.js"></script>
?
这里到底发生了什么?
答案 0 :(得分:4)
Bar hack
如何能够拥有一个名为test
的变量,其值为over
,同时还有一个名为test
的变量,其值为t
static final
?
接口只能声明常量(Bar hack
是隐式的)。因此,对象Bar hack = new Bar();
没有任何[实例]变量,它只能访问两个碰巧具有相同名称的静态最终变量,分别由接口和类声明。
此外,
Bar
是继承自己吗?如果hack是super
的实例,那么它如何具有Bar
类型test
且包含不同的Bar hack = new Bar() { ... };
?
实际上,hack
。所以Bar
是Bar
的匿名内部子类的实例。是的,这个一次性子类确实继承自类{{1}}。
这里到底发生了什么?
你正在学习Java:)
答案 1 :(得分:1)
1
How is it possible that Bar hack can have a variable called test with a value of over and at the same time have a variable called test with a value of t?
这句话是错误的。在java中有类的类和实例。静态常量/变量属于不属于该类实例的类。所以
Bar hack = new Bar() {
public static final String test="over";
以上test
常量属于Bar annonymous class(Bar $ 1.class)而不是Bar.class。值test
的{{1}}常量属于Bar.class。因此,在"t"
方法中使用它将打印最接近的范围变量,该变量显然具有值func
"over"
因此,如果您要打印public void func(){
System.out.println("Ideone.Meh.hack.func -- Test: "+test);
}
,因为test是属于Bar的公共静态常量,您可以使用以下代码。
Bar.test
2
public void func(){
System.out.println("Ideone.Meh.hack.func -- Test: "+Bar.test);
}
正如我之前所说的那样,声明结果是一个实现Bar的匿名内部类。
Also, is Bar hack = new Bar(); inheriting from itself? If hack is an instance of Bar, how can it have a super that is of type Bar and contains a different test?
真正的hack是一个Bar但是test是一个静态常量,这意味着它不属于类实例而是属于类。