美文网首页java基础
Java封装——访问权限控制

Java封装——访问权限控制

作者: 冰糖雪梨葫芦甜 | 来源:发表于2018-11-19 22:18 被阅读0次

预备术语

若将程序开发人员按照角色分类,可以分为以下两类:

类创建者

那些创建新数据类型的程序员。

客户端程序员

那些在其应用中使用类创建者提供的数据类型的类消费者。
注:客户端程序员也可以是类创建者:他在类库的设计中用到了其他程序员创建的类,同时他也将提供新的数据类型给其他类消费者。

前言

通常一个优秀的作者可能会反复的修改其作品,以使得其著作越来越完美(没有绝对的完美,希望读者不要纠结于完美这个用词),这也是为什么很多著作都会有第一版、第二版、第三版等等。
同理,一个优秀的类设计者也需要反复的修改他所创建的类,使其越来越完美。然而,有时类创建者的修改,对于一些客户端程序员可能是一场灾难。
例如,这些类消费者在其应用中大量的使用到了类的某个(或某些)方法,而类创建者在某次更新版本后声明:以前的那个方法存在极大的缺陷,现已增加了一个全新的方法替代了那个方法(甚至可能以前的方法直接被删除了),新的方法不仅避免了缺陷,更极大的提升了效率。

以下代码展示了一个具体的例子:
注:“//:”表示一个文件的开头,“//:~”表示这个文件的结尾。因此,以下代码可能不止在一个文件中。

//: Design.java —— 类设计者创建的类(新版)
public class Design {
    // 旧的有缺陷的方法
    void method() {
        //some code...
    }
    // 新的避免缺陷且更有用的方法
    void moreUserful() {
        //some code...
    }
}
//:~

//: App.java —— 客户端程序员创建的应用(大量使用了旧版的方法)
public class App {
    public static void main(String[] args) {
        //some code...
        Design d1 = new Design();
        Design d2 = new Design();
        Design d3 = new Design();
        d1.method();
        d2.method();
        d3.method();
        //some code...
    }
}
//:~

那么此时,这些客户端程序员该怎么做呢?
一,继续使用老版本的类,同时承受缺陷所带来的所有风险(这在多数情况下显然是不明智的)。
二,使用新版本的类,并把应用中所有的旧版方法修改为新版中新增的方法,根据应用大小,修改成百上千甚至上万的方法,都是有可能的(好吧,可能某位负责任的程序员在把所有方法都修改好后就直接下岗,并决定再也不从事该行业了)。
显然,无论哪个选择,都不是那么令人满意。
实际上,这是一个设计时的缺陷。一个合理的解决方案是:类创建者在设计时专门对外提供一个方法供类消费者使用,这个方法调用了任何随时可能修改的其它方法。并且跟类消费者约定好:只能用这个对外提供的方法,其它方法不要使用。

以下代码展示了改进的例子,以及在这个例子中类创建者的更改对客户端程序员的影响。

//: SmarterDesign.java —— 类设计者创建的类(新版)
public class SmarterDesign {
    // 约定好的对外提供的方法
    void provide() {
        // method();
        /* 在新版中注释掉了旧版调用了方法,
         * 使用了新的更可靠的方法,然而此时
         * 只要客户端程序员遵守约定,是不会
         * 对其原来的代码产生影响的:
         * 他们不需要修改任何原来的代码就能
         * 享有新版的特性,只需要将SmarterDesign
         * 文件替换为新版即可。
         */
        moreUseful();
    }
    // 旧的有缺陷的方法
    void method() {
        //some code...
    }
    // 新的避免缺陷且更有用的方法
    void moreUseful() {
        //some code...
    }
}
//:~

//: App2.java —— 客户端程序员创建的应用(大量使用了与类创建者约定好的对外提供的方法)
public class App2 {
    public static void main(String[] args) {
        //some code...
        SmarterDesign d1 = new SmarterDesign();
        SmarterDesign d2 = new SmarterDesign();
        SmarterDesign d3 = new SmarterDesign();
        d1.provide();
        d2.provide();
        d3.provide();
        //some code...
    }
}
//:~

可以看到,在这个例子中,只要大家都遵守约定,不管SmarterDesign的创建者以后如何修改provide()中调用的方法,都不会对客户端程序员原先的代码结构产生影响。
这个设计仍然存在一个问题:设计者的良苦用心是否起效在于使用者是否遵守约定。然而,可能会有某个(甚至某些)客户端程序员并不知道这些约定(可能他们没有仔细看设计者提供的文档),或者在开发的过程中忘了有这么回事,那么可能设计者的好心就白费了。
好在Java语言中有访问权限修饰词,它们能很好的处理这类问题:只要类创建者合理的使用了它们,那么不管是类创建者还是客户端程序员都不必那么费心了,这些修饰词会替我们好好的处理这些麻烦。

Java访问权限修饰词

Java访问权限修饰词在使用时,置于类中每个成员的定义之前。每个访问权限修饰词仅控制它所修饰的特定定义的访问权,以下是各种修饰词所定义的访问权。

public

使成员成为公共的成员,无论是谁,无论在哪里,都可以访问该成员。

默认的包访问权

本文以上所有示例中的大多数成员都没有使用任何访问权限修饰词,这些成员默认的拥有包访问权,即同一个包中任何地方都能访问到该成员。

protected

使成员成为受保护的成员,该成员只有在本类、本类的子类以及同一个包中可以被访问。也就是说,protected修饰的成员同时拥有包访问权。

private

使成员成为私有的成员,该成员只有在本类中可以被访问。

回到问题

让我们回顾之前SmarterDesign的例子,利用修饰词,类创建者只需将需要对外提供的成员修饰为public的(例子中的provide()),将需要隐藏的实现修饰为private的(例子中的method()和moreUseful()),即可避免以后修改(甚至是删除)隐藏的实现对客户端程序员的代码结构造成影响。

*练习

请读者尝试给SmarterDesign例子中的成员添加合适的修饰词,来达到类设计者预期的效果(相信这对您而言并不是一件难事)。

相关文章

  • Go封装、继承、多态

    封装 封装主要是通过访问权限控制实现的。 在Java中,共有public 、protected、default、p...

  • Java封装——访问权限控制

    预备术语 若将程序开发人员按照角色分类,可以分为以下两类: 类创建者 那些创建新数据类型的程序员。 客户端程序员 ...

  • java权限控制

    浅析Java中的访问权限控制 今天我们来一起了解一下Java语言中的访问权限控制。在讨论访问权限控制之前,先来讨论...

  • Java访问控制符

    Java访问控制符的访问权限

  • Java基础学习六 关键字

    java语言中的访问控制权限修饰符 访问控制权限修饰来控制元素的访问范围。 访问控制权限修饰符包括:public ...

  • 访问控制权限

    在之前所学习到的private就属于一种访问控制权限,而这种访问控制权限只是封装的一部分,在java里面提供有4种...

  • iOS之类的三大特性(封装、继承、多态)

    一、封装: 封装就是对类中的一些字段、方法进行保护,不被外界所访问到,有一种权限的控制功能,Java中有四种访问权...

  • Java面向对象

    面向对象 封装 Java语言中,访问修饰符可以出现在类,成员变量,成员方法以及构造方法前,用来控制权限。Java提...

  • Java--封装的实现

    封装的实现-使用访问控制符 Java是使用“访问控制符”来控制哪些细节需要封装,哪些细节需要暴露的。Java中4种...

  • 2018-07-07学习小结 - 包及访问权限4

    学习 18.2 类成员的访问控制权限 Java中有四种访问控制权限,private、default、protect...

网友评论

    本文标题:Java封装——访问权限控制

    本文链接:https://www.haomeiwen.com/subject/hktzfqtx.html