Java:为什么接口中的声明不充分?

发布于 2024-08-31 03:22:37 字数 2520 浏览 7 评论 0原文

大类包含Format-interfcase和Format-class。 Format 类包含方法,接口包含字段的值。我可以在类格式中包含字段,但目标是接口。那么我是否只是创建虚拟变量来消除错误、设计问题或其他问题?

关键: 声明与初始化

  1. 通过术语解释一下,为什么必须在接口中进行初始化。
  2. 其背后的逻辑是什么?
  3. 接口的使用会导致什么样的问题?

具有初始化接口问题的示例代码

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

  1. Explain by the terms, why you have to init in interface.
  2. What is the logic behind it?
  3. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

说不完的你爱 2024-09-07 03:22:38

接口中的字段隐式是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 also static. 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 call super rather than a "this" constructor) or in an instance initialiser.

You should probably move instance fields into the implementing class, and mark them final.

葬シ愛 2024-09-07 03:22:38

@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 called Format, both declared in the namespace of the FormatBig. 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 inside FormatBig 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文