区分一个组件设计的好不好,唯一的评价因素就是看对于外界组件,能不能隐藏起来细节,只通过API进行通信,每个模块不知道其他模块的细节实现,这就是封装或者信息隐藏的概念。封装一个非常大的好处就是可以接触组件之间的耦合,也就是解耦。解耦使组件之间可以独立的开发,测试,优化,使用和修改。这些组件并行化的开发,加快了开发的速度。
    封装的工具:访问控制机制,也就是类,方法,成员的可访问性(public,protect,default,private)
    封装的规则:尽可能的使每个类或成员不被外界访问。也就是对每个类要赋予尽可能最小的访问级别。
    私有的成员外界无法访问,因此改变只会影响这个类的内在。如果把某个类,方法,成员设置成public,那以后一定要维护这个类的兼容性。
    继承时访问权限的限制:子类的访问权限一定不能低于超类的访问权限。例如:

    1. public class Person {
    2. protected void testAcessable(){
    3. System.out.println("this is parent and the accessalbe is protected");
    4. }
    5. }
    6. public class Child extends Person {
    7. //至少是protected级别的否则无法编译,这里就无法编译
    8. private void testAcessable(){
    9. System.out.println("this is child and the accessable level is private");
    10. }
    11. }

    公有类的实例域绝不能是公有的,一旦成为公有,这个类就失去了对这个域的限制,而且这也很容易造成线程不安全。静态域也是同样的限制,只有一种情况例外,那就是通过静态公有final域来暴露某些常量。

    要注意final修饰数组的时候并不是说数组不可变,而是数组引用不可变,如果想要实现一个不可变的数组可以使用List代替,Collections.unmodifiableList(Arrays.asList(array));另一种实现不可变数组的情况是使用数组的浅拷贝,返回一个本数组的地址引用

    import java.util.Arrays;
    import java.util.Collections;
    import java.util.List;
    
    public class FINALARRAY {
        private static final Integer[] array = new Integer[10];
        //也可以使用克隆返回一个唯一的final地址引用。
        public static final Integer[] values(){
            return array.clone();
        }
        public static void main(String[] args) {
            Integer[] array = FINALARRAY.array;
            array[2] = 3;
            array[4] =5;
            System.out.println(array.toString());
            final List<Integer> finalList = Collections.unmodifiableList(Arrays.asList(array));
            finalList.set(2, 4);
            System.out.println(finalList.toString());
    
        }
    }
    }
    /*
    [Ljava.lang.Integer;@6e0be858
    Exception in thread "main" java.lang.UnsupportedOperationException
        at java.util.Collections$UnmodifiableList.set(Collections.java:1313)
        at item15.FINALARRAY.main(FINALARRAY.java:14)
    */
    

    总结:应该始终尽可能降低元素的访问级别,仔细设计一个具有最小公有API之后,应该防止把任何散乱的类,接口或者成员变成API的一部分,除了公有静态final域的特殊情况外(充当常量),共有类不应该包含公有域,而且要保证公有静态final域所引用的对象都是不可变的。