接口中的属性/成员variables?

我想知道有没有什么方法可以让实现者声明对象句柄/原语,就像他们对方法所做的那样。 例如:

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) { } } 

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

我最初想到inheritance使用它。 但事情是我必须处理3class。

  1. 长方形
  2. JLabel的!

  class Tile extends JLabel implements Rectangle {} 

会工作。!

 class Tile extends JLabel extends Rectangle {} 

不要!

接口的要点是指定公共API。 一个接口没有状态。 你创build的任何variables都是常量(所以要小心在接口中创build可变对象)。

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

因为你只是指定要实现什么方法,所以没有状态的概念(没有实例variables)。 如果你想要求每个类都有一个特定的variables,你需要使用一个抽象类。

最后,一般来说,你应该不使用公共variables,所以把variables放入界面的想法是一个不好的主意。

简短的回答 – 你不能做你想做的,因为它在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; } } 

一个替代版本将是:

 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 { } 

你只能用抽象类来做,而不能用接口。

Rectangle声明为abstract class而不是interface并将必须由子类实现的方法声明为public abstract 。 然后,类Tileinheritance类Rectangle并且必须从Rectangle实现抽象方法。

接口不能要求定义实例variables – 只有方法。

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

快乐的编码。

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

但是,我仍然发现了一种在界面中实现存储属性的方法。 我承认这有点不好实现。

  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); } } 

这个界面很丑。 为了存储简单的属性,它需要两个hashmaps,默认情况下每个hashmap默认创build16个条目。 另外,当真实对象被解除引用时,JVM还需要删除这个弱引用。

在Java中,你不能。 接口与方法和签名有关,它不需要处理对象的内部状态 – 这是一个实现问题。 这也是有意义的 – 我的意思是,仅仅因为某些属性存在,并不意味着它们必须被实施类使用。 getHeight实际上可以指向宽度variables(假设实现者是虐待者)。

(注意 – 所有语言都不是这样,ActionScript允许声明伪属性,我相信C#也是这样)

接口中的字段隐式地为public static final 。 (也有方法是隐式公开的,所以你可以删除public关键字。)即使你使用抽象类而不是接口,我强烈build议使所有非常量(原始或不可变对象引用的public static final )为private 。 更一般的“更喜欢组合inheritance” – Tile不是一个Rectangle (当然,你可以用“is-a”和“has-a”来玩文字游戏)。

汤姆说过一件重要的事情:

如果你使用has-a的概念,你可以避免这个问题。

实际上,如果不是使用extendsimplements来定义两个属性,即矩形的一个types,即Tile类中的JLabeltypes之一,则可以将Rectangle定义为接口或类。

此外,我通常会鼓励使用与has-a有关的接口,但是我想这会对你的情况有所帮助。 但是,您是唯一可以决定这一点的人(权衡灵活性/过度工程)。