java Vamei快速教程04 封装和接口
作者: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 Vamei快速教程04 封装和接口的更多相关文章
- java Vamei快速教程00
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Java是面向对象语言.这门语言其实相当年轻,于1995年才出现,由Sun公司出品 ...
- java Vamei快速教程05 实施接口
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在封装与接口中,private关键字封装了对象的内部成员.经过封装,产品隐藏了内部 ...
- java Vamei快速教程08 继承
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 继承(inheritance)是面向对象的重要概念.继承是除组合(composit ...
- java Vamei快速教程18 容器
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Java中有一些对象被称为容器(container).容器中可以包含多个对象,每个 ...
- java Vamei快速教程01
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Java是完全面向对象的语言.Java通过虚拟机的运行机制,实现“跨平台”的理念. ...
- java Vamei快速教程10 接口的继承和抽象类
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在实施接口中,我们利用interface语法,将interface从类定义中独立出 ...
- java Vamei快速教程20 GUI
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! GUI(Graphical User Interface)提供了图形化的界面,允许 ...
- java Vamei快速教程17 多线程
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 多线程 多线程(multiple thread)是计算机实现多任务并行处理的一种方 ...
- java Vamei快速教程22 内存管理和垃圾回收
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 整个教程中已经不时的出现一些内存管理和垃圾回收的相关知识.这里进行一个小小的总结. ...
随机推荐
- sublime text 3安装及使用
Sublime Text 3中文版是一款跨平台代码编辑器(Code Editor)软件.Sublime Text 3既可以编写代码还可以编辑文本,是程序员必不可少的工具,相比之前的版本Sublime ...
- ASP.NET MVC 小牛之旅3:Routing——网址路由
网址路由(Routing)在ASP.NET MVC中有两个主要用途,一个用途是匹配通过浏览器传来的HTTP请求,另一个用途则是响应适当的网址给浏览器. 3.1匹配通过浏览器传来的HTTP请求 首先我们 ...
- 【leetcode 3. 无重复字符的最长子串】解题报告
思路:滑动窗口的思想 方法一:滑动窗口 int lengthOfLongestSubstring(string s) { /* 控制一个滑动窗口,窗口内的字符都是不重复的,通过set可以做到判断字符是 ...
- CodeForces 106C 【DP】
题意: n g dough m种商品? 每种有ai stuffing, 拿bi stuffing + ci dough -> di tugriks rest c0 dough -> d0 ...
- bzoj2502: 清理雪道(有源汇有上下界最小流)
传送门 别说话,自己看,我不会->这里 我这里用的建图方法是先跑一次最大流,连上$(t,s,inf)$之后再跑一遍,然后答案就是之前连的那条边的反向边的流量 据说还有种方法是连上$(t,s,in ...
- 面试d090305知识点准备01
1.1 类成员访问[jL1] 权限 1.2 写个双线程,计算50内的奇偶数 1.3 打印等腰三角形 1.4 运算符优先级 括号,非正负和自增减(右到左),乘除加减,等于不等于,逻辑与和或,然后 ...
- 修改Gradle本地仓库
问题描述 Gradle 默认的本地仓库为 C:\Users\用户名\.gradle,不想让其一直下载东西占用 C 盘资源. 解决方法 新建环境变量名:GRADLE_USER_HOME,变量值为:D:\ ...
- 解决Eclipse导入Gradle项目时在 Building gradle project info 一直卡住
问题描述 在使用 Eclipse 导入 Gradle 项目时一直卡住,不能导入项目 问题解决 解决办法主要有两种:一是直接下载 gradle 离线包,二是修改项目的 ..\gradle\wrapp ...
- Win10家庭版打不开gpedit.msc
本文来源 : https://www.ithome.com/html/win10/324926.htm win10家庭版是不自带这个功能的 首先我们打开记事本,并输入以下内容(注意空格): @echo ...
- ACM-ICPC 2018 南京赛区网络预赛 B. The writing on the wall
题目链接:https://nanti.jisuanke.com/t/30991 2000ms 262144K Feeling hungry, a cute hamster decides to o ...