接口中的属性/成员变量?

Shr*_*rey 65 java interface

我想知道有没有什么方法可以让实现者强制声明对象句柄/原语与方法一样.例如:

public interface Rectangle {    
    int height = 0;
    int width = 0;

    public int getHeight();
    public int getWidth();
    public void setHeight(int height);
    public void setWidth(int width);                
}


public class Tile implements Rectangle{
    @Override
    public int getHeight() {
        return 0;
    }

    @Override
    public int getWidth() {
        return 0;
    }

    @Override
    public void setHeight(int height) {
    }

    @Override
    public void setWidth(int width) {   
    }

}
Run Code Online (Sandbox Code Playgroud)

在上面的方法中,我们如何使用接口强制Tile类声明高度和宽度属性?出于某种原因,我希望只使用界面!

我最初想过将它与继承一起使用.但事情是我必须处理3个班级.

  1. 长方形
  2. JLabel的!

 

 class Tile extends JLabel implements Rectangle {}
Run Code Online (Sandbox Code Playgroud)

会工作.!

class Tile extends JLabel extends Rectangle {}
Run Code Online (Sandbox Code Playgroud)

不要.!

Tof*_*eer 80

接口的要点是指定公共API.接口没有状态.您创建的任何变量都是常量(因此请注意在接口中创建可变对象).

基本上,接口在这里说的是实现它的类必须支持的所有方法.如果Java的创建者不允许在接口中使用常量,那么可能会更好,但是现在为时已晚(并且在某些情况下常量在接口中是合理的).

因为您只是指定必须实现哪些方法,所以不知道状态(没有实例变量).如果要要求每个类都有一个特定的变量,则需要使用抽象类.

最后,一般来说,您应该不使用公共变量,因此将变量放入接口的想法一开始就是一个坏主意.

简短的回答 - 你不能做你想要的,因为它在Java中是"错误的".

编辑:

class Tile 
    implements Rectangle 
{
    private int height;
    private int width;

     @Override
    public int getHeight() {
        return height;
    }

    @Override
    public int getWidth() {
        return width;
    }

    @Override
    public void setHeight(int h) {
        height = h;
    }

    @Override
    public void setWidth(int w) { 
        width = w;  
    }
}
Run Code Online (Sandbox Code Playgroud)

替代版本将是:

abstract class AbstractRectangle 
    implements Rectangle 
{
    private int height;
    private int width;

     @Override
    public int getHeight() {
        return height;
    }

    @Override
    public int getWidth() {
        return width;
    }

    @Override
    public void setHeight(int h) {
        height = h;
    }

    @Override
    public void setWidth(int w) { 
        width = w;  
    }
}

class Tile 
    extends AbstractRectangle 
{
}
Run Code Online (Sandbox Code Playgroud)


小智 8

接口不能要求定义实例变量 - 仅限方法.

(变量可以在接口中定义,但它们的行为不像预期的那样:它们被视为final static.)

快乐的编码.


Sim*_*n C 8

您只能使用抽象类而不是接口来执行此操作.

声明Rectangle为一个abstract class而不是一个interface并声明必须由子类实现的方法public abstract.然后类Tile扩展类Rectangle,必须实现抽象方法Rectangle.


Dun*_*ter 6

Java 8引入了接口的默认方法,您可以使用这些方法来处理方法.根据OOPs,接口应作为两个系统/各方之间的合同.

但我仍然找到了一种在界面中实现存储属性的方法.我承认这有点难看.

   import java.util.Map;
   import java.util.WeakHashMap;

interface Rectangle
{

class Storage
{
    private static final Map<Rectangle, Integer> heightMap = new WeakHashMap<>();
    private static final Map<Rectangle, Integer> widthMap = new WeakHashMap<>();
}

default public int getHeight()
{
    return Storage.heightMap.get(this);
}

default public int getWidth()
{
    return Storage.widthMap.get(this);
}

default public void setHeight(int height)
{
    Storage.heightMap.put(this, height);
}

default public void setWidth(int width)
{
    Storage.widthMap.put(this, width);
}
}
Run Code Online (Sandbox Code Playgroud)

这个界面很难看.对于存储简单属性,它需要两个哈希映射,默认情况下每个哈希映射默认创建16个条目.此外,当取消引用真实对象时,JVM还需要删除此弱引用.

  • 很有趣但很奇怪:)。您甚至可以消除内部类,而只在您的界面本身中存储静态最终映射。 (2认同)