Java:为什么接口中的声明不充分?
大类包含Format-interfcase和Format-class。 Format 类包含方法,接口包含字段的值。我可以在类格式中包含字段,但目标是接口。那么我是否只是创建虚拟变量来消除错误、设计问题或其他问题?
关键: 声明与初始化
- 通过术语解释一下,为什么必须在接口中进行初始化。
- 其背后的逻辑是什么?
- 接口的使用会导致什么样的问题?
具有初始化接口问题的示例代码
import java.util.*;
import java.io.*;
public class FormatBig
{
private static class Format implements Format
{
private static long getSize(File f){return f.length();}
private static long getTime(File f){return f.lastModified();}
private static boolean isFile(File f){if(f.isFile()){return true;}}
private static boolean isBinary(File f){return Match.isBinary(f);}
private static char getType(File f){return Match.getTypes(f);}
private static String getPath(File f){return getNoErrPath(f);}
//Java API: isHidden, --- SYSTEM DEPENDED: toURI, toURL
Format(File f)
{
// PUZZLE 0: would Stack<Object> be easier?
size=getSize(f);
time=getTime(f);
isfile=isFile(f);
isBinary=isBinary(f);
type=getType(f);
path=getPath(f);
//PUZZLE 1: how can simplify the assignment?
values.push(size);
values.push(time);
values.push(isfile);
values.push(isBinary);
values.push(type);
values.push(path);
}
}
public static String getNoErrPath(File f)
{
try{return f.getCanonicalPath();
}catch(Exception e){e.printStackTrace();}
}
public static final interface Format
{
//ERR: IT REQUIRES "="
public long size;
public long time;
public boolean isFile=true; //ERROR goes away if I initialise wit DUMMY
public boolean isBinary;
public char type;
public String path;
Stack<Object> values=new Stack<Object>();
}
public static void main(String[] args)
{
Format fm=new Format(new File("."));
for(Object o:values){System.out.println(o);}
}
}
Big class contains Format-interfcase and Format-class. The Format-class contains the methods and the interface has the values of the fields. I could have the fields in the class Format but the goal is with Interface. So do I just create dummy-vars to get the errors away, design issue or something ELSE?
KEY: Declaration VS Initialisation
- Explain by the terms, why you have to init in interface.
- What is the logic behind it?
- To which kind of problems it leads the use of interface?
Sample Code having the init-interface-problem
import java.util.*;
import java.io.*;
public class FormatBig
{
private static class Format implements Format
{
private static long getSize(File f){return f.length();}
private static long getTime(File f){return f.lastModified();}
private static boolean isFile(File f){if(f.isFile()){return true;}}
private static boolean isBinary(File f){return Match.isBinary(f);}
private static char getType(File f){return Match.getTypes(f);}
private static String getPath(File f){return getNoErrPath(f);}
//Java API: isHidden, --- SYSTEM DEPENDED: toURI, toURL
Format(File f)
{
// PUZZLE 0: would Stack<Object> be easier?
size=getSize(f);
time=getTime(f);
isfile=isFile(f);
isBinary=isBinary(f);
type=getType(f);
path=getPath(f);
//PUZZLE 1: how can simplify the assignment?
values.push(size);
values.push(time);
values.push(isfile);
values.push(isBinary);
values.push(type);
values.push(path);
}
}
public static String getNoErrPath(File f)
{
try{return f.getCanonicalPath();
}catch(Exception e){e.printStackTrace();}
}
public static final interface Format
{
//ERR: IT REQUIRES "="
public long size;
public long time;
public boolean isFile=true; //ERROR goes away if I initialise wit DUMMY
public boolean isBinary;
public char type;
public String path;
Stack<Object> values=new Stack<Object>();
}
public static void main(String[] args)
{
Format fm=new Format(new File("."));
for(Object o:values){System.out.println(o);}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
接口中的字段隐式是
public final static
。static
意味着它们独立于实例。这可能不是您想要的。final
意味着它们需要在类初始化期间只分配一次,因为这些字段也是静态
。这通常意味着在声明中分配,但可以使用静态初始化程序。如果它们是实例字段(非静态
),那么它们需要在声明中、构造函数中分配(隐式或显式调用super
而不是“this
" 构造函数)或在实例初始化程序中。您可能应该将实例字段移动到实现类中,并将它们标记为
final
。Fields in interfaces are implicitly
public final static
.static
will mean that they are independent of instances. This is probably not what you want.final
means they need to be assigned exactly once during class initialisation, as the fields are alsostatic
. This usually means assigning in the declaration, but could use a static initialiser. If they were instance fields (non-static
), then they would need to be assigned either in the declaration, in constructors (that implicitly or explicitly callsuper
rather than a "this
" constructor) or in an instance initialiser.You should probably move instance fields into the implementing class, and mark them
final
.@Tom 已经回答了你的直接问题。基本上,您不能在接口中声明实例级属性(或类级变量)。实例级属性必须在类中声明。
如果您希望多个类共享相同的属性声明,您可以将它们放入抽象超类中。但最佳实践是将属性声明为
private
并通过 getter 和 setter 访问它们。您的代码还存在一些其他问题:
您不能在同一命名空间中声明具有相同名称的类和接口。您有一个名为
Format
的类,它实现了一个名为Format
的接口,这两个接口都在FormatBig
的命名空间中声明。即使你可以(例如,因为它们是在不同的命名空间中声明的),这也是不好的做法。为类和接口指定不同的名称。您应该谨慎使用嵌套类。在我看来,为了方便起见,您可能将
Format
类和接口嵌套在FormatBig
中,这样您只需编辑和编译一个文件。那是懒惰。或者,如果您这样做是为了组织代码,请学习如何使用 Java 包。@Tom has answered your direct question. Basically, you cannot declare instance-level attributes (or class-level variables) in an interface. Instance level attributes must be declared in a class.
If you want multiple classes to share the same attribute declarations, you could put them into an abstract superclass. But best practice is to declare the attributes as
private
and access them via getters and setters.There are a couple of other problems with your code:
You cannot declare a class and an interface with the same name in the same namespace. You have a class called
Format
that implements an interface calledFormat
, both declared in the namespace of theFormatBig
. And even if you could (e.g. because they were declared in different namespaces), this is bad practice. Give the class and interface distinct names.You should use nested classes sparingly. It looks to me like you might have nested the
Format
class and interface insideFormatBig
as a convenience so that you only have to edit and compile one file. That is lazy. Alternatively, if you are doing it to organize your code, learn how to use Java packages.