Java 为什么可以';接口没有字段吗?

Java 为什么可以';接口没有字段吗?,java,interface,Java,Interface,忽略所有内容,直到第二次编辑 我正在尝试这样做: public interface IModifier{ public String nameTag; public void foo(); } String getNameTag(); 我尝试这样做的原因是: 我有一个类特定的修改器 还有许多非常类似的类也实现了IModifier。 我希望实现IModifier的每个类都有一个公共字符串名称标记 编辑:我已经得到确认,我不能这样做,但有人能解释为什么接口不能需要一个字段吗 编辑两个

忽略所有内容,直到第二次编辑

我正在尝试这样做:

public interface IModifier{
   public String nameTag;
   public void foo();
}
String getNameTag();
我尝试这样做的原因是: 我有一个类特定的修改器 还有许多非常类似的类也实现了IModifier。 我希望实现IModifier的每个类都有一个公共字符串名称标记

编辑:我已经得到确认,我不能这样做,但有人能解释为什么接口不能需要一个字段吗

编辑两个:

我对抽象类和接口的用途的理解。接口纯粹用于声明实现它的任何对象的必要部分,以便所有对象都具有可引用的公共部分。而抽象类用于为多个类提供公共功能

public interface Auditable<USER_TYPE> {
    Instant getCreatedOn();
    void setCreatedOn(Instant)

    USER_TYPE getCreatedBy();
    void setCreatedBy(USER_TYPE creator);
这有点过于简化,但不管怎样,除了语言设计者的疏忽之外,我仍然看不到接口不能有抽象字段的原因

有人能提供原因吗?

没有

接口只能需要方法,而不需要字段(或构造函数)


您可以通过在接口中放置getter和/或setter方法来实现相同的效果。

不,您不能。java中的接口只能包含方法和常量但是,有一种替代方法。添加如下方法:

public interface IModifier{
   public String nameTag;
   public void foo();
}
String getNameTag();
看到了吗?这样,实现必须包含一个
nameTag
字段,或者它们可以执行一些其他操作来返回字符串


另外,据我所知,您不需要向接口方法添加访问修饰符。

接口是为方法和常量制作的

您需要根据需要使用
抽象类

public abstract class IModifier{
   public String nameTag;
   public abstract void foo();
}
现在回答您的问题
为什么接口不需要字段?
答:因为这是
抽象类的特性。
接口
抽象类
之间几乎没有区别


我希望我能回答你棘手的问题。

从设计的角度来看: 接口定义了一个约定行为的契约,该契约是通过其他方法可以完成的。(例如int getAge())以及如何操作的较少内容。 那么,实现行为所需的部分实例字段(int age)自然不适合。接口上仍然可以使用非特定于实现的静态final字段(例如Static final int centuriage=100)


然后,在约定好契约之后,如果您转到行为实现,则转到类和抽象类等。

接口指定了一个契约,实现接口的具体类必须遵守该契约。此合同描述了实现应如何操作。在接口规范中,应该有明确的注释来描述每个方法的用途。接口的使用将契约与实际实现分离。字段是一个实现细节,因为字段不描述类应该如何“充当”

例如,接口通常用作声明的类型,而具体实现用作实际类型

    Map<Key,Value> m = new HashMap<>();
现在您可以有一个具体的类

   class SpecificModifier extends IModParent{

      SpecificModifier(String nameTag){ this.nameTag = nameTag; }

      @Override
      public void foo(){ System.out.println(nameTag); }
   }
和一份声明

    IModifier imod = new SpecificModifier("MyName");

这为您提供了使用接口类型的灵活性,同时仍然能够通过一个不可实例化的抽象类在您想要的具体类组中共享实现细节。

如果您查找java文档,您将从中获得实际的语句

抽象类类似于接口。您不能实例化它们,它们可能包含使用或不使用实现声明的方法的混合。但是,对于抽象类,您可以声明非静态和最终的字段,并定义公共、受保护和私有的具体方法。对于接口,所有字段都自动是公共的、静态的和最终的,并且您声明或定义的所有方法(作为默认方法)都是公共的。此外,您只能扩展一个类,不管它是否抽象,而您可以实现任意数量的接口

您应该使用哪一种,抽象类还是接口

如果以下任何语句适用于您的情况,请考虑使用抽象类:

  • 您希望在几个密切相关的类之间共享代码
  • 您希望扩展抽象类的类有许多共同点 方法或字段,或要求访问修饰符而不是public(如protected和private)
  • 您想要声明非静态或非最终字段。这使您能够定义可以访问和修改其所属对象状态的方法
  • 如果以下任何陈述适用于您的情况,请考虑使用接口:

    1.您希望不相关的类将实现您的接口。例如 可比较和可克隆的接口由许多不相关的类实现

    2.您希望指定特定数据类型的行为,但不关心是谁 实现其行为

    3.您希望利用类型的多重继承

    但是,根据您的问题第一次编辑,您可以在界面中定义一个字段,但是有一个警告。它必须是公共的、静态的和最终的。 换句话说,只定义常量;)


    上面的代码将被编译。

    以下是我在许多项目中所做的工作,以便能够定义一个“接口”,该接口定义的不是字段,而是字段的“契约”

    本主题前面提出的使用
    abstract
    基类的建议有严重的局限性。一个具体的类可以用Java有限的多重继承形式实现多个接口,但是。。。它只能扩展一个基类。这意味着基类方法只适用于一个需要
    @Getter @Setter
    public AuditableExpirableObject implement Auditable<String>, Expirable {
        private String createdBy
        private Instant createdOn;
        private Instant expirationDate;