我对某些我正在查看的源代码感到困惑,并且我试图更好地理解。代码如下,但它也可用at Ideone,您可以自己使用它。
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone
{
public interface Fruit {
public void apple();
}
Fruit interfaceFruit;
public void apple(){
System.out.println("apple");
if (interfaceFruit != null) {
interfaceFruit.apple();
}
}
public void setFruit(Fruit f) {
interfaceFruit = f;
}
public static void main (String[] args) throws java.lang.Exception
{
Ideone test = new Ideone(){
@Override
public void apple() {
System.out.println("local override of apple");
}
};
System.out.println("1) ---");
test.apple();
Ideone test2 = new Ideone();
System.out.println("2) ---");
test2.apple();
test2.setFruit(new Fruit() {
@Override
public void apple() {
System.out.println("interface override of apple");
}
});
System.out.println("3) ---");
test2.apple();
}
}
输出结果为:
1) ---
local override of apple
2) ---
apple
3) ---
apple
interface override of apple
此代码究竟发生了什么?在类内部声明了一个接口(所以,一个内部接口,对吗?)然后将接口声明为该类的实例变量。这是我感到困惑的地方。
我认为发生的事情是,如果为接口Fruit
实例化匿名内部类,我们将创建一个实现接口的未命名类。我没有完全理解的是接口是如何或为什么存储在类的实例变量中的。这样做的目的是什么?这种做法叫做什么?这看起来很奇怪,而且我不确定某人会从中得到什么。
答案 0 :(得分:1)
这不是通常的代码,它只是一个练习,所以你可以看到它是如何工作的。所以是的,事情可能看起来很奇怪"。
(?i) # Case insensitive
^ # BOS
(?= [a-z] ) # First char alpha
(?! # Not these
.*?
(?:
\._ # dot, underscore
| _\. # underscore, dot
| \.{2} # 2 or more dots
| _{2} # 3 or more underscore
| ( [a-z\d] ) # (1), 3 or more repeated alpha-num's
\1{2}
)
)
[a-z\d._]+ # Get valid char's: alpha-num, dot and underscore
$ # EOS
它不是存储,它是定义的。您可以在类中定义内部类和接口;几个例子:
类和接口仅用于类的内部逻辑,而其他地方则不需要;通常那些被定义为私人。与匿名类或多或少相同。
类和接口与类紧密耦合。例如,您为该bean定义了一个类和What I'm not totally getting is how or why the interface is stored in an instance variable to the class
实现;因为这样的Comparator
仅对该类的元素有用,所以将其定义为嵌套类。它的工作方式与另一层次的包装"。
例如,我擅长控制传递给我的方法的值,所以,当它有意义时,我做的事情(非常愚蠢的例子)
Comparator
枚举仅用于访问类的逻辑,因此它在类中定义。
Java API中的示例是public class Calendar {
public static enum WeekDay {
MONDAY,
...
SUNDAY;
}
public Date getNextDay(WeekDay weekDay) {
...
}
}
类,java.util.Map.Entry<K,V>
实现使用它来访问它们存储的键值对。
答案 1 :(得分:1)
宣言:
Fruit interfaceFruit;
简单地说:&#34;声明变量interfaceFruit
,它将用于保存对实现Fruit
的对象的引用。
这样的变量可以保存对任何类的引用,前提是它实现了接口。你能用它来做的是访问界面中定义的所有方法和常量,因为Java知道无论类是什么,它都会有覆盖Fruit
中声明的覆盖方法(在这种情况下) ,只有apple()
)。
这种东西在Java中非常常用。它允许您使用变量来保存符合合同的任何对象,但是在它的不同实现中使用它。这种做法被称为&#34;编程到界面&#34;。一个非常常见的例子是声明一个变量:
List<Integer> list;
(其中List
是接口java.util.List
),然后为其分配特定的实现:
list = new LinkedList<Integer>();
list = new ArrayList<Integer>();
list = Arrays.asList(1,5,8,9);
无论你指定的对象是哪一类(在Arrays.asList
的情况下,你甚至都不知道会是哪一堂课),它将拥有全部java.util.List
定义的操作 - 例如add()
或iterator()
。
因此同样适用于您的Fruit
界面。它恰好是嵌套接口这一事实并不重要。