• 【Java编程思想读书笔记】接口成员变量默认static final的原因


    一、提出问题

    今天在阅读Java编程思想的时候,读到接口部分,在说到接口的数据变量都是默认被static final修饰,这个突然产生一个思考,为什么接口中的数据成员都是默认被static final 修饰呢?为什么要这么设计呢?

    二、解释问题

    2.1 回顾接口

    在解释这个原因之前,需要先回顾一下接口的作用以及接口的特性。接口所要体现的思想是"like a",所抽象的是行为,接口不提供具体的实例,因此不能实例化接口。在Java编程思想中有这样的一句话:

    接口这样描述自己:“对于实现我的所有类,看起来都应该象我现在这个样子”。因此,采用了一个特定接
    口的所有代码都知道对于那个接口可能会调用什么方法。这便是接口的全部含义。

    接口只是比抽象类“更纯”的一种形式。它的用途并不止那些。由于接口根本没有具体的实施细节——也就
    是说,没有与存储空间与“接口”关联在一起——所以没有任何办法可以防止多个接口合并到一起。

    因此,接口主要的思想在于设计。而不是具体。

    2.2.宏观角度

    从宏观的角度上来看,接口更像是一种约定,一种协议,一种设计。可以把接口看作是一张房子的设计图。这张设计图所要体现的只是这个房子应该像什么样子,需要有哪些东西,某某房间需要有一个窗户,客厅某某地方是用于放电视的,而具体做这个窗户用什么材料,那个地方摆的是哪个品牌的电视,则不是接口所关心的。建造房子,接口就是设计图,但是设计图里放一块砖,有必要吗?

    2.3.微观角度

    回到具体的Java中来谈,从三方面来谈谈。

    第一:从设计的角度上考虑。因为接口是一种规范,规范的东西是不能随意变化的,因此接口中数据成员都是用final来修饰。由于static作用于类定义,如果不用static声明,这就代表该成员是属于具体的对象,而接口不允许实例化,那么如果没有static,那么该数据变量就毫无意义了。反之,如果该数据变量是被static修饰的,那么这就意味着该成员变量是属于该接口,这就让该数据成员有了意义。

    第二:从内存的角度来考虑。在上面引用的Java编程思想中的话中有提到,没有存储空间与接口关联在一起,但是一个接口中又可以定义数据成员,那么也就必须要有一个地方用于存放这个数据成员,因此需要用static为接口中的数据成员指定一块内存位置。

    第三:从开发避错的角度上考虑。假设这样的一种情况,在接口1中有一个数据变量为a,在接口2中也有一个数据成员为a,由于接口是多实现的,这个时候,某个类同时实现了接口1和接口2,那么这个时候就产生了两个名为a的数据成员。那么应该用哪个a呢?这个时候就产生了歧义,一个a同时有了两个值,因此这个时候用static 修饰,表明这个数据只能有一份,放在静态存储区,并在编译时期报错,告诉你这个a姑娘已经有主了,你赶紧改名吧。

    而从开发的角度上来想其实为什么用final也很好理解,因为接口是一种规范嘛,实现这个接口的类不止一个,假设接口中的数据不被final修饰,意味着这个数据可变,并且所有实现改接口的类都会受这次修改的影响,牵一发而动全身,那么所有如果随随便便来个类都可以把规范(接口)中的东西给改了。那还叫什么规范呢,那开发岂不是乱套了吗。

    三、验证问题

    上代码

    interface interOne{
        int a = 8;
    }
    interface interTwo{
        int a = 12;
    }
    public class Concrete implements  interOne,interTwo {
        public static void main(String[] args) {
            System.out.println(a);//这里会报错
        }
    }
    
    

    此时,IDE提示了一个错误,错误为:

    Reference to 'a' is ambiguous, both 'interOne.a' and 'interTwo.a' match
    

    由此可以验证我们的解释正确。以上是我的个人理解,如有错误,望不吝指教。

  • 相关阅读:
    vue-lazyLoad 图片懒加载
    div块居中
    OpenFire源码学习之三十三:windows打包
    OpenFire源码学习之三十二:使用Tsung测试openfire(下)
    OpenFire源码学习之三十一:使用Tsung测试openfire(上)
    OpenFire源码学习之三十:haproxy负载均衡
    OpenFire源码学习之二十八:与其他系统的用户整合
    OpenFire源码学习之二十七:Smack源码解析
    OpenFire源码学习之二十六:Spark&Tinder
    OpenFire源码学习之二十五:消息回执与离线消息(下)
  • 原文地址:https://www.cnblogs.com/blackmlik/p/12362672.html
Copyright © 2020-2023  润新知