在 Class 中初始化在接口中声明的 Java 集合
Initialize a Java Collection in Class that was declared in Interface
在接口中声明了一个Vector并将其设置为null,想稍后在实现接口的class中初始化它,java下面的代码出错了,我怎么能以其他方式初始化它?
import java.util.Vector;
interface machine {
Vector<Integer> temp = null;
public int compute();
}
class App implements machine {
App(Vector<Integer> x) {
//error here, can't assign value to temp as it is declared in interface, any other way of initializing??
temp = x;
}
@Override
public int compute() {
int sum = 0;
for (int x : temp) {
sum += x;
}
return sum;
}
}
public class Finals {
public static void main(String[] args) {
Vector<Integer> x = new Vector<>();
for (int i = 0; i < 10; i++) {
x.add(i);
}
App a = new App(x);
System.out.println(a.compute());
}
}
根据我的理解,您不能这样做,因为接口变量是静态最终的,因此您必须在接口本身中进行初始化。
Java 语言在设计时考虑了以下想法:
字段从未真正被视为类型“public API”的一部分。是的,可以编写 public 字段并可以从外部对其进行修改,但是几乎没有 java 代码可以做到这一点,而且许多语言特性根本不支持它。例如,方法引用存在(someExpr::someMethodName
是合法的 java),但是没有字段引用这样的东西。
接口存在仅传达API - 传达类型应该能够做什么,它是不是 旨在传达如何 的事情。换句话说,接口(因此得名)是,实现号。
将这两个概念加在一起,您就会明白为什么您想要的(在界面中放置一个字段)不受支持。字段不是接口的一部分(规则 #1),因此它必须是实现,接口不能携带实现细节(规则 #2),因此:你不能将字段放在接口中.
因此,java 语言规范规定接口中的任何字段声明本质上都是 public static final
- 它是一个常量。你不能让它成为 not-public-static-final - 将 private
作为修饰符放在它上面是编译器错误。没有表示 'unstatic'.
的修饰符
您有 2 个选择:
您打算将该字段仅用作实现:您决定实现此接口的 所有 class 将需要此字段,因此,可能以及在界面中声明它并保存输入,对吗?那么,您在那里所做的是将 实现 的共同方面组合在一起。 Java 支持这一点,但 仅在摘要中 classes。这种情况一直发生在 java 中:有 java.util.List
(接口)和 java.util.AbstractList
(实现该接口的抽象 class,它提供了一堆常见的行为) 和 java.util.ArrayList
(最常用的实现。它扩展了 AbstractList)。
您实际上需要该字段的 'interface' 部分:您想在接口文件本身(通过 default
方法)或代码中编写一些代码接收类型为您的 machine
接口的对象,并希望直接访问该字段。在罗马时,像罗马人一样行事。编程时 java,像其他 java 程序员一样工作。这意味着:不要将字段视为接口 - 如 API。如果 'a machine' 的本质(也就是说:一个对象是 class 的一个实例,并且 class 实现了 machine
)是它可以提供一个表示 temp
概念的整数列表,然后 使接口的一部分 :在接口中写入 Vector<Integer> getTemp;
,并让每个实现 class 提供一个实现。如果您期望所有实施 classes 可能只是想要:
private Vector<Integer> temp;
public Vector<Integer> getTemp() {
return temp;
}
然后你可以把它放在实现接口的抽象 class 中,并让你所有的实现实现抽象 class.
如果这一切都在你的脑海中飞来飞去,我可以让它更简单:
- 无论你写不写,接口里的所有字段decls都必然是
public static final
。您不能声明不是的字段,语言根本不允许您这样做。
- 这是有充分理由的 - 请参阅上面的解释。
注意:
您似乎使用了一些非常过时的(此时至少有 25 年了!!)指南。因此,此代码不会通过任何审查。 Vector
已过时,不应使用,并且已过时 20 年:你想要 ArrayList
,大概。 Java 约定规定 TypesGoLikeThis、methodNamesLikeThis、variableNamesAlsoLikeThis 和 CONSTANTS_LIKE_THIS。因此,它将是 public interface Machine
,而不是 public interface machine
。编译器可以让你做任何你想做的事,但如果你不遵守约定,当你将它与任何其他 java 代码集成时,你的代码会变得不必要地奇怪和不方便。
在接口中声明了一个Vector并将其设置为null,想稍后在实现接口的class中初始化它,java下面的代码出错了,我怎么能以其他方式初始化它?
import java.util.Vector;
interface machine {
Vector<Integer> temp = null;
public int compute();
}
class App implements machine {
App(Vector<Integer> x) {
//error here, can't assign value to temp as it is declared in interface, any other way of initializing??
temp = x;
}
@Override
public int compute() {
int sum = 0;
for (int x : temp) {
sum += x;
}
return sum;
}
}
public class Finals {
public static void main(String[] args) {
Vector<Integer> x = new Vector<>();
for (int i = 0; i < 10; i++) {
x.add(i);
}
App a = new App(x);
System.out.println(a.compute());
}
}
根据我的理解,您不能这样做,因为接口变量是静态最终的,因此您必须在接口本身中进行初始化。
Java 语言在设计时考虑了以下想法:
字段从未真正被视为类型“public API”的一部分。是的,可以编写 public 字段并可以从外部对其进行修改,但是几乎没有 java 代码可以做到这一点,而且许多语言特性根本不支持它。例如,方法引用存在(
someExpr::someMethodName
是合法的 java),但是没有字段引用这样的东西。接口存在仅传达API - 传达类型应该能够做什么,它是不是 旨在传达如何 的事情。换句话说,接口(因此得名)是,实现号。
将这两个概念加在一起,您就会明白为什么您想要的(在界面中放置一个字段)不受支持。字段不是接口的一部分(规则 #1),因此它必须是实现,接口不能携带实现细节(规则 #2),因此:你不能将字段放在接口中.
因此,java 语言规范规定接口中的任何字段声明本质上都是 public static final
- 它是一个常量。你不能让它成为 not-public-static-final - 将 private
作为修饰符放在它上面是编译器错误。没有表示 'unstatic'.
您有 2 个选择:
您打算将该字段仅用作实现:您决定实现此接口的 所有 class 将需要此字段,因此,可能以及在界面中声明它并保存输入,对吗?那么,您在那里所做的是将 实现 的共同方面组合在一起。 Java 支持这一点,但 仅在摘要中 classes。这种情况一直发生在 java 中:有
java.util.List
(接口)和java.util.AbstractList
(实现该接口的抽象 class,它提供了一堆常见的行为) 和java.util.ArrayList
(最常用的实现。它扩展了 AbstractList)。您实际上需要该字段的 'interface' 部分:您想在接口文件本身(通过
default
方法)或代码中编写一些代码接收类型为您的machine
接口的对象,并希望直接访问该字段。在罗马时,像罗马人一样行事。编程时 java,像其他 java 程序员一样工作。这意味着:不要将字段视为接口 - 如 API。如果 'a machine' 的本质(也就是说:一个对象是 class 的一个实例,并且 class 实现了machine
)是它可以提供一个表示temp
概念的整数列表,然后 使接口的一部分 :在接口中写入Vector<Integer> getTemp;
,并让每个实现 class 提供一个实现。如果您期望所有实施 classes 可能只是想要:
private Vector<Integer> temp;
public Vector<Integer> getTemp() {
return temp;
}
然后你可以把它放在实现接口的抽象 class 中,并让你所有的实现实现抽象 class.
如果这一切都在你的脑海中飞来飞去,我可以让它更简单:
- 无论你写不写,接口里的所有字段decls都必然是
public static final
。您不能声明不是的字段,语言根本不允许您这样做。 - 这是有充分理由的 - 请参阅上面的解释。
注意:
您似乎使用了一些非常过时的(此时至少有 25 年了!!)指南。因此,此代码不会通过任何审查。 Vector
已过时,不应使用,并且已过时 20 年:你想要 ArrayList
,大概。 Java 约定规定 TypesGoLikeThis、methodNamesLikeThis、variableNamesAlsoLikeThis 和 CONSTANTS_LIKE_THIS。因此,它将是 public interface Machine
,而不是 public interface machine
。编译器可以让你做任何你想做的事,但如果你不遵守约定,当你将它与任何其他 java 代码集成时,你的代码会变得不必要地奇怪和不方便。