今天突然问自己,接口的变量为什么是static和final的?
static:必须。因为接口是可以多继承的。如果一个类实现了两个接口,且两个接口都具有相同名字的变量,此时这个变量可以被实现类使用,那么如果不是static的,这个变量来自哪一个接口就会产生歧义,所以实现类使用接口中的变量必须通过接口名指定,也就只能定为static的。
看下面的例子:
此时,会报编译错误,因为a有歧义。
Reference to 'a' is ambiguous, both 'iface1.a' and 'iface2.a' match
final:我认为因为必须是static的,那么所有子类共享,而接口是一种抽象, 所以一个子类修改了值会影响到其他所有子类,因此就不应该允许子类修改这个值,所以定义为final。
到目前为止,我还没有发现一个接口需要定义常量,不知道为什么java设计的时候会允许interface有域。
当然有人会使用interface封装常量,这个在effective java中被认为是对接口的误用,主要是因为会污染导出接口列表,同时污染子类命名空间。
我个人觉得,java设计者并不想把设计做的那么绝,从语言角度禁止在interface里定义变量,它给了程序员这个空间,只是说在后续的发展中,经过实践的检验发现这种定义常量在接口种的方法并不好,所以我们尽量不这么做了。设计者把这个留给了程序员来把控。
我认为可以不像effective java里所说,禁止在interface里放常量。但是interface必须专一,即要在interface里放常量,那么该interface就只能当做常量库来使用,不应该再提供任何抽象或者被类实现,否则就会出现effective java里所说的问题。如果该interface是一个为了抽象的接口,那么它里面就不应该定义常量,应该在另一个类里面封装所有常量,只能二选一。