封装的基本概念

封装的概念

基本概念:

封装是面向对象的方法应该遵循的一个重要原则!它的英文是encapsulation,有时也叫做数据隐藏。
从形式上看,封装不过是将数据和行为组合在一个包中,并对对象的使用者隐藏了数据的实现形式。
对象中的数据称为实例域(instance field),操纵数据的过程叫做方法(method)对于每个特定的类实例(也就是对象),都有一组特定的实例域值。这些值的集合就是这个对象的当前状态(state).无论何时,只要向对象发送一个消息,它的状态就有可能发生改变。
实现封装的关键在于绝对不能让类中的方法直接地访问其他类的实例域。程序仅通过对象的方法,与对象数据进行交互。封装给对象赋予了“黑盒”特征,这是提高重用性和可靠性的关键。这意味着一个类可以全面地改变存储数据的方式,只要仍旧使用同样的方法操作数据,其他对象就不会知道或介意所发生的变化。

总之一句话,封装就是指隐藏对象的属性和实现细节,仅仅对外提供公共方法去访问它。

用类和对象来打个比方:

现在,你需要去做一件你不知道怎么去做的事情,比如说你家里的灯坏了!(只是打个比方 ^_^)。现在,你还需要用到灯,但又不会修理,那该怎么办呢?还能怎么办,当然是找会修灯的人来啊!那么问题来了,你觉得你自己是不是不需要知道这灯该怎么修啊,你需要知道的就是谁会修这灯!那么这个会修灯的人就是你要找的对象。
有人或许会问,这跟封装有啥关系呢?
我个人的理解是这样的:
那个对象,也就是上边例子中的会修灯的电工,是不是会修灯,他拥有这个修灯的行为吧。没错,这就是把修灯的这个行为封装在这个对象体内了,你根本不知道怎么去修,但是你知道怎么能修好(找电工呗)。那么这也就是一种封装了。

另外,在啰嗦一句,java是一种强语言,它是纯面向对象的。
这也就是为什么我们刚开始接触java时,会听过一句话:万物皆对象!当然,人家这是一种境界,从我嘴里说出来,那就叫吹牛B了。


还有一句吹牛B的话,就是,java啊,我们学习它,就是在学习找类,找对象,难怪我还单身,原来是java没学好啊。找对象就是为了用这个对象里边封装好的方法。所以,封装的理解是很重要的,本人现在也是理解了个凤毛麟角。

封装的好处


1. 将变化隔离。不难理解,都包装好了,不让你知道它内部是怎么实现的了,你能知道它发生啥变化吗?当然是false了。

2. 便于使用,不用了解内部构造。这个就不多解释了,就像是,你根本不用去专门学习修灯(像电工致敬!礼毕!)。

3. 提高重用性。这个就好玩了,将一个事物封装起来之后,必须要对外暴露一些接口(好让人使用啊),不然,就没有存在的必要了,没有意义。而这暴露出来的方法(一般我们用public修饰),当然就不止一个人能使用了,那是千千万万的用户啊,可以重复使用。这就像是,你电脑上的USB接口,不止你一个人能用吧?

4. 提高安全性。这一点从前两点就可以说明了,这里不做过多解释了。

封装的原则


1. 将不需要对外提供的内容都隐藏起来。这个不解释,你要是不隐藏,那能叫封装吗?
2. 把属性都隐藏,提供公共方法对其访问。

这里会用到private修饰符,它是java中的权限修饰符。用于修饰类中的成员(成员变量,成员函数),私有只在本类中有效。将属性私有化以后,类以外即使建立了对象也不能直接访问,但是若要使用该属性,就要在本类中提供对应访问的方法。

常用之一:将成员变量私有化,对外提供对应的set、get方法对其进行访问,提高对数据访问的安全性。

有需求的小伙伴们,这里有我另一篇博客的链接,里面写了几个常见的封装的例子,可以供你们参考!http://blog.csdn.net/fbb360java/article/details/79206820

需要注意的是:私有仅仅是封装的一种表现形式。之所以对外提供访问方式,就是因为可以在访问方式中加入逻辑判断等语句,对访问的数据进行操作,提高代码健壮性。

之前练习的时候,有一个简单的例子:

package com.home.demo1;

/**
 * 获取年龄。
 * 
 * @author Feng 2018年2月19日上午8:10:08
 */
class Person {
    private int age;

    public void setAge(int a) {
        if (a >= 0 && a <= 130) {
            age = a;
        } else {
            System.out.println("传入参数不合法!");
        }
    }

    public int getAge() {
        return age;
    }

    public void speak() {
        System.out.println("age = " + age);
    }
}

public class PersonDemo {
    public static void main(String[] args) {
        Person p = new Person();
        // p.age = 10;无法获取。因为有private
        p.setAge(12);
        p.speak();
    }

}

这里有一个简单的内存示意图:

封装的基本概念_第1张图片

我再分析下啊,首先,我们从main方法进去,开始执行上述的代码。

第一行呢,Person p = new Person();这句代码做了什么呢?
我们都知道“=”是赋值符号,所以内存在加载的时候,把声明出的Person的引用p存到了栈内存中(不要问我为什么会存在栈里,好吧!)。
然后呢,堆内存中用new关键字开辟了一块空间,就是new Person()这个对象所存在的空间哦。有了空间,自然就要要有一个地址啊,这里堆就给new Person()这个对象分配了个0x0012,这是16进制的表示形式,用0x开头。然后,就把地址告诉了p引用,所以main方法中的p引用最后就指向了这个堆里的内存空间了。


接下来的p.setAge(12);又做了什么呢?

这个就简单描述一下吧。
在堆内存中初始化的int类型数据,并没有赋值,所以默认就是0,因为基本数据类型的默认是0,引用数据类型的默认是null,也叫“空”。


当我们用公共的setAge方法把12这个数据传进去时,首先12就给了它的形式参数,就是括号里面的那个int a,经过判断呢,12在0到130之间,就把12又给了age。所以我上边的曲线,就是把age默认的0给它覆盖掉了。

至于最后一行的调用方法,就不用说了吧(反正我也没画,是吧,哈哈)。

觉得能帮到你们的童鞋们,请点个赞再走吧。敲了这麽些字,我也不容易。还从《java核心技术(卷I)基础知识(原书第9版)》里边摘录的解释呢。

你可能感兴趣的:(java基础学习,java核心基础的接触性学习)