刨根问底-02为什么Java接口中的成员变量被设计为必须是public static final的?
概述
此为"刨根问底"系列文章的第二篇,接上篇,为什么Java接口中的成员变量被设计为必须是public static final的?
网络答案
在网络上搜索到了如下两篇还算靠谱的解答!
解释
上篇我们用反证法来证明了接口方法设为public为最合适选择!
这里我们依然可以使用反证法来解释!
假设接口中的成员变量不是public static final的!
先将属性设置为private的!
public interface Person{
private int num;
}
OK!private的属性,当然只能在接口内部使用了!但是在接口里面给谁使用呢?接口里的方法只有方法头可没方法体!所以设为private,那就永远都访问不到了!
好,那我们改成protected!
public interface Person{
protected int num;
}
这样子类就能访问了!但是外部如何访问呢?方法是有的:
public interface Person{
protected int num;
int getNum();
void setNum(int num);
}
class PersonA implements Person{
public int getNum(){
return num;
}
public void setNum(int num){
this.num = num;
}
}
如果有100个类实现了Person接口!请问有多少重复代码?
接着是默认访问权限控制符:
public interface Person{
//非public static final
int num;
}
对于包外的类来说,和protected一样的问题!这里不废话了!
最后就只剩下public了!
public interface Person{
public int num;
}
public class PersonA implements Person{
public int num = 2;
}
public class Test{
public static void main(String[] args){
PersonA pa = new PersonA();
System.out.println(pa.num); //打印结果是?
Person p = pa;
System.out.println(p.num); //打印结果是?
}
}
如上代码你会发现,两者打印结果居然不相同!这就好像是,这个"协议"公开是一套,而如果你有关系,会给你另一套"内部协议"!
究其原因,就是这个成员变量是属于实现了这个接口的对象的,并不属于接口本身。因为你需要先实例化实现了此接口的类才可以操作这个成员变量,而接口本身并不能实例化!
所以如果想这个成员变量为接口所有,只能将其设为static!
public interface Person{
public static int num;
}
public class PersonA implements Person{}
public class PersonB implements Person{}
public class Test{
public static void main(String[] args){
System.out.println(Person.num); //结果?
PersonA.num = 2;
System.out.println(Person.num); //结果?
PersonB.num = 2;
System.out.println(Person.num); //结果?
}
}
如上代码的意思就是,A和B遵循了"协议"Person,但是只要A或B感觉不满意就可以随便改!那还叫"协议"吗?
所以只能加上final来限制修改!
而对于添加public final的效果,和只添加public的问题相同!不多说!
从上面的修改可以看出,public static final修饰符,缺少任何之一都会导致"协议"的不公正!
你可以把接口看作是合同!成员变量看作合同说明,确定后当然是不能变的!至于如何去执行这个合同,那就随便了!