作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!

总结之前的内容,对象(object)指代某一事物,类(class)指代象的类型。对象可以有状态和动作,即数据成员和方法。

到现在为止,数据成员和方法都是同时开放给内部和外部的。在对象内部,我们利用this来调用对象的数据成员和方法。在对象外部,比如当我们在另一个类中调用对象的时,可以使用 对象.数据成员 和 对象.方法() 来调用对象的数据成员和方法。

我们将要封装(encapsulation)对象的成员(成员包括数据成员和方法),从而只允许从外部调用部分的成员。利用封装,我们可以提高对象的易用性和安全性。

封装与接口

封装(encapsulation)是计算机常见的术语,即保留有限的外部接口(interface),隐藏具体实施细节。比如在Linux架构,就可以看到Linux操作系统封装了底层硬件的具体细节,只保留了系统调用这一套接口。用户处在封装的外部,只能通过接口,进行所需的操作。

封装在生活中很常见。比如下面是一个充电电筒:

一个用户即使不看说明书,也可以猜到这个电筒的操作: 开关和充电。这个电筒用一个塑料壳将用户不需要接触的内部细节隐藏起来,只保留了两个接口,开关和电插头。使用这两个接口,用户足以使用该产品在设计中想要实现的功能。如果所有的细节都同时暴露给用户,那么用户会对产品感到不知所措 (比如下面不加壳的遥控器)。因此,封装提高了产品的易用性。

如果产品不封装,电筒或者遥控器的许多细节会暴露在用户面前: 电池、电路、密封的橡胶等等。尽管这可以让用户更自由的对产品实施操作,比如直接给电池放电,取出一个LED灯等等。然而,用户往往要承担更大的损坏产品的风险。因此,封装提高了产品的安全性。

一个Java软件产品与一个日常产品相同。一个对象内部可以有许多成员(数据成员和方法)。有一些数据成员和方法只是内部使用。这时,我们会希望有一个给对象“加壳”的机制,从而封装对象。这样,用户可以比较容易学习和使用外部的接口,而不必接触内部成员。

对象成员的封装

Java通过三个关键字来控制对象的成员的外部可见性(visibility): public, private, protected。

  • public: 该成员外部可见,即该成员为接口的一部分
  • private: 该成员外部不可见,只能用于内部使用,无法从外部访问。

(protected涉及继承的概念,放在以后说)

我们先来封装以前定义的Human类:

public class Test
{
public static void main(String[] args)
{
Human aPerson = new Human(160);
System.out.println(aPerson.getHeight());
aPerson.growHeight(170);
System.out.println(aPerson.getHeight());
aPerson.repeatBreath(100);
} } class Human
{
/**
* constructor
*/
public Human(int h)
{
this.height = h;
System.out.println("I'm born");
} /**
* accessor
*/
public int getHeight()
{
return this.height;
} /**
* mutator
*/
public void growHeight(int h)
{
this.height = this.height + h;
} /**
* encapsulated, for internal use
*/
private void breath()
{
System.out.println("hu...hu...");
} /**
* call breath()
*/
public void repeatBreath(int rep)
{
int i;
for(i = 0; i < rep; i++) {
this.breath();
}
} private int height; // encapsulated, for internal use
}

内部方法并不受封装的影响。Human的内部方法可以调用任意成员,即使是设置为private的height和breath()

外部方法只能调用public成员。当我们在Human外部时,比如Test中,我们只能调用Human中规定为public的成员,而不能调用规定为private的成员。

通过封装,Human类就只保留了下面几个方法作为接口:

  • getHeight()
  • growHeight()
  • repBreath()

我们可以将Human类及其接口表示为如下图的形式:

“加了壳的遥控器”

如果我们从main中强行调用height:

System.out.println(aPerson.height);

将会有如下错误提示:

Test.java:6: height has private access in Human
        System.out.println(aPerson.height);
                                  ^
1 error

Beep, 你触电了! 一个被说明为private的成员,不能被外部调用。

在Java的通常规范中,表达状态的数据成员(比如height)要设置成private。对数据成员的修改要通过接口提供的方法进行(比如getHeight()和growHeight())。这个规范起到了保护数据的作用。用户不能直接修改数据,必须通过相应的方法才能读取和写入数据。类的设计者可以在接口方法中加入数据的使用规范。

类的封装

在一个.java文件中,有且只能有一个类带有public关键字,比如上面的Test类。所以,从任意其他类中,我们都可以直接调用该类。Human类没有关键字。更早之前,我们对象的成员也没有关键字。这种没有关键字的情况也代表了一种可见性,我将在包(package)的讲解中深入。

练习 封装一个Torch类,来表示电筒。接口有开关和充电。内部的成员有电量。

总结

封装,接口

private, public

欢迎继续阅读“Java快速教程”系列文章

Java基础04 封装与接口的更多相关文章

  1. Java基础04 封装与接口(转载)

    数据成员和方法都是同时开放给内部和外部的.在对象内部,我们利用this来调用对象的数据成员和方法.在对象外部,比如当我们在另一个类中调用对象的时,可以使用 对象.数据成员 和 对象.方法() 来调用对 ...

  2. Java基础之抽象类与接口

    Java基础之抽象类与接口 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的时候 ...

  3. java Vamei快速教程04 封装和接口

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 总结之前的内容,对象(object)指代某一事物,类(class)指代象的类型.对 ...

  4. 程序猿的日常——Java基础之抽象类与接口、枚举、泛型

    再次回顾这些基础内容,发现自己理解的又多了一点.对于一些之前很模糊的概念,渐渐的清晰起来. 抽象类与接口 抽象类通常是描述一些对象的通用方法和属性,并且默认实现一些功能,它不能被实例化.接口仅仅是描述 ...

  5. Java基础之浅谈接口

    前言 前几篇文章我们已经把Java的封装.继承.多态学习完了,现在我们开始比较便于我们实际操作的学习,虽然它也是Java基础部分,但是其实入门容易,精通很难. 我认真的给大家整理了一下这些必须学会.了 ...

  6. Java基础 -- Collection和Iterator接口的实现

    Collection是描述所有序列容器(集合)共性的根接口,它可能被认为是一个“附属接口”,即因为要表示其他若干个接口的共性而出现的接口.另外,java.util.AbstractCollection ...

  7. 黑马程序员——JAVA基础之抽象和接口 , 模版方法设计模式

    ------- android培训.java培训.期待与您交流! ---------- 抽象定义:           抽象就是从多个事物中将共性的,本质的内容抽取出来.           例如:狼 ...

  8. java基础(四)-----抽象类与接口

    抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力.他们两者之间对抽象概念的支持有很大的相似,甚至可以互换,但是也有区别. 一.抽象类 我们 ...

  9. Java基础之封装

    封装(Encapsulation)是java面向对象的三大特性,之前学java迷迷糊糊,一直也没弄清楚什么是封装以及为什么要封装,直到这次看书才有一种被点醒的感觉. java中的封装是针对某个类而言的 ...

随机推荐

  1. Sublime Text 2使用技巧汇总

    一.下载链接: Windows-64bit: http://pan.baidu.com/s/1o6QdKYu 其它版本请移步官网: http://www.sublimetext.com/ 二.破解Li ...

  2. python中os.walk浏览目录和文件

    #!/usr/bin/env python # 2.py # use UTF-8 # Python 3.3.0 # os.walk()的使用 import os # 枚举dirPath目录下的所有文件 ...

  3. C中的宏

    1. 简单宏定义 简单的宏定义有如下格式: [#define指令(简单的宏)] #define  标识符替换列表 替换列表是一系列的C语言记号,包括标识符.关键字.数.字符常量.字符串字面量.运算符和 ...

  4. 深入浅出—JAVA(8)

    8.接口与抽象类 不是抽象的类就被称为具体类 不同继承树的类也可以实现相同的接口,类可以实现多个接口.

  5. js获取select默认选中的Option (非当前选中值)

    js函数方法: <script> function getDefaultSelectedOption(selectId, valIfNull) { var selectId = selec ...

  6. cyq.data开源

    终于等到你:CYQ.Data V5系列 (ORM数据层)最新版本开源了 前言: 不要问我框架为什么从收费授权转到免费开源,人生没有那么多为什么,这些年我开源的东西并不少,虽然这个是最核心的,看淡了就也 ...

  7. Windows Phone 8初学者开发—第7部分:本地化应用程序

    原文 Windows Phone 8初学者开发—第7部分:本地化应用程序 第7部分:本地化应用程序 原文地址: http://channel9.msdn.com/Series/Windows-Phon ...

  8. COM组件

    COM组件   COM component(COM组件)是微软公司为了计算机工业的软件生产更加符合人类的行为方式开发的一种新的软件开发技术.在COM构架下,人们可以开发出各种各样的功能专一的组件,然后 ...

  9. BestCoder Round #50 (div.1) 1003 The mook jong (HDU OJ 5366) 规律递推

    题目:Click here 题意:bestcoder 上面有中文题目 分析:令f[i]为最后一个木人桩摆放在i位置的方案,令s[i]为f[i]的前缀和.很容易就能想到f[i]=s[i-3]+1,s[i ...

  10. Android:mimeType

    接收从其他应用传过来的数据,要用到清单文件 <activity android:name="com.terry.myActivity2" android:label=&quo ...