Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中将内部接口定义为类的实例变量_Java_Interface_Anonymous Inner Class - Fatal编程技术网

在Java中将内部接口定义为类的实例变量

在Java中将内部接口定义为类的实例变量,java,interface,anonymous-inner-class,Java,Interface,Anonymous Inner Class,我对我正在看的一些源代码感到困惑,我正试图更好地理解它们。代码如下所示,但也可以在您自己玩的地方使用 import java.util.*; import java.lang.*; import java.io.*; class Ideone { public interface Fruit { public void apple(); } Fruit interfaceFruit; public void apple(){

我对我正在看的一些源代码感到困惑,我正试图更好地理解它们。代码如下所示,但也可以在您自己玩的地方使用

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
这段代码到底是怎么回事?在一个类内部声明了一个接口(所以,是内部接口,对吗?),然后该接口被声明为该类的实例变量。这就是我困惑的地方


我认为,如果为接口
水果
实例化了一个匿名内部类,我们将创建一个实现该接口的未命名类。我不完全理解的是接口如何或为什么存储在类的实例变量中。这样做的目的是什么?这种做法叫什么?这似乎很奇怪,我真的不确定有人会从中得到什么。

这不是常见的代码,它只是一个练习,您可以看看它是如何工作的。因此,是的,事情可能看起来“奇怪”

我不完全了解接口如何或为什么存储在类的实例变量中

它不是存储的,而是定义的。可以在类中定义内部类和接口;举几个例子:

  • 类和接口仅在类的内部逻辑中使用,其他地方不需要;通常这些被定义为私有的。与匿名类的工作原理大致相同

  • 类和接口与类紧密耦合。例如,您为该bean定义了一个类和一个
    比较器
    实现;因为这样的
    比较器
    只对该类的元素有用,所以可以将其定义为嵌套类。它就像另一个层次的“包装”

例如,我擅长控制传递给我的方法的值,所以,当它有意义时,我会做类似的事情(非常愚蠢的例子)

枚举仅用于访问类的逻辑,因此它是在类中定义的

Java API中的示例是
Java.util.Map.Entry
类,它被
Map
实现用来访问它们存储的键值对。

声明:

Fruit interfaceFruit;
简单地说:“声明变量
interfaceFruit
,该变量将用于保存对实现
Fruit
的对象的引用

这样的变量可以包含对任何类的引用,只要它实现了接口。您可以使用它访问接口中定义的所有方法和常量,因为Java知道,无论该类是什么,它都将具有与
Fruit
中的声明相匹配的重写方法(在本例中,它只有
apple()

这类东西在Java中非常常用。它允许您使用变量来保存符合约定的任何对象,但可以使用它的不同实现。这种做法称为“编程到接口”。一个非常常见的示例是声明一个变量,如:

List<Integer> list;
无论指定给哪个类的对象(在
Arrays.asList
的情况下,您甚至不知道将是哪个类),它都将拥有
java.util.List
定义的所有操作,例如
add()
iterator()


因此,这同样适用于您的
Fruit
接口。它恰好是一个嵌套接口这一事实并不那么重要。

相关:接口不存储在变量中。变量被声明为接口类型。重要的是要记住,接口的嵌套只是一个词汇,换句话说:嵌套接口总是隐式地
静态的
。您所询问的行只是一个字段声明,完全独立于接口声明。您可以将接口移动到单独的源文件中,并且仍然可以将字段声明为
水果
类型。关于“存储与定义”命令nt在您的回答中,我说的是这一行
Fruit interfaceFruit;
接口被声明为一个实例变量否?然后稍后通过
setFruit()进行设置
。正如你所说,
这不是常见的代码,只是一个练习,你可以看看它是如何工作的。
-这让我感觉好一点。我写了这段代码,但它只是简化了代码库中的实际内容。
接口声明为实例变量否?
否。接口完全由
定义>接口Fruit{…}
Fruit Fruit
所做的是声明一个变量,该变量可能引用实现
Fruit
的类的实例(如果没有赋值,则为null)。接口被声明为内部接口,类中声明了一个类型为FROUT的实例变量。此外,无论是否显式,任何内部接口都被视为静态内部接口。@iullianr我不认为
内部接口被视为静态内部接口。
FROUT
interface被定义为
Ideone.Fruit
,但不是静态接口。@MaxZoom被认为是一个静态接口,与静态内部类的意义相同。正如您在Ideone.Fruit中提到的,这意味着您不需要Ideone的实例来处理Fruit(同样,在代码中,您可以声明一个匿名类,该类实现了水果,而没有Ideone实例,就像静态内部类一样)。
List<Integer> list;
list = new LinkedList<Integer>();
list = new ArrayList<Integer>();
list = Arrays.asList(1,5,8,9);