[改善Java代码]使用静态内部类提高封装性
建议38: 使用静态内部类提高封装性
Java中的嵌套类(Nested Class)分为两种:静态内部类(也叫静态嵌套类,Static Nested Class)和内部类(Inner Class)。内部类我们介绍过很多了,现在来看看静态内部类。什么是静态内部类呢?是内部类,并且是静态(static修饰)的即为静态内部类。只有在是静态内部类的情况下才能把static修复符放在类前,其他任何时候static都是不能修饰类的。
静态内部类的形式很好理解,但是为什么需要静态内部类呢?那是因为静态内部类有两个优点:加强了类的封装性和提高了代码的可读性,我们通过一段代码来解释这两个优点,如下所示:
public class Person {
// 姓名
private String name;
// 家庭
private Home home;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Home getHome() {
return home;
}
public void setHome(Home home) {
this.home = home;
}
// 构造函数设置属性值
public Person(String _name) {
name = _name;
}
public static class Home {
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
// 家庭地址
private String address;
// 家庭电话
private String tel;
public Home(String _address, String _tel) {
address = _address;
tel = _tel;
}
}
}
其中,Person类中定义了一个静态内部类Home,它表示的意思是“人的家庭信息”,由于Home类封装了家庭信息,不用在Person类中再定义homeAddre、homeTel等属性,这就使封装性提高了。同时我们仅仅通过代码就可以分析出Person和Home之间的强关联关系,也就是说语义增强了,可读性提高了。所以在使用时就会非常清楚它要表达的含义:
public class Client {
public static void main(String[] args) {
//定义张三这个人
Person p = new Person("张三");
//设置张三的家庭信息
p.setHome(new Person.Home("上海","021"));
}
}
定义张三这个人,然后通过Person.Home类设置张三的家庭信息,这是不是就和我们真实世界的情形相同了?先登记人的主要信息,然后登记人员的分类信息。可能你又要问了,这和我们一般定义的类有什么区别呢?又有什么吸引人的地方呢?如下所示:
提高封装性。从代码位置上来讲,静态内部类放置在外部类内,其代码层意义就是:静态内部类是外部类的子行为或子属性,两者直接保持着一定的关系,比如在我们的例子中,看到Home类就知道它是Person的Home信息。
提高代码的可读性。相关联的代码放在一起,可读性当然提高了。
形似内部,神似外部。静态内部类虽然存在于外部类内,而且编译后的类文件名也包含外部类(格式是:外部类+$+内部类),但是它可以脱离外部类存在,也就是说我们仍然可以通过new Home()声明一个Home对象,只是需要导入“Person.Home”而已。
解释了这么多,读者可能会觉得外部类和静态内部类之间是组合关系(Composition)了,这是错误的,外部类和静态内部类之间有强关联关系,这仅仅表现在“字面”上,而深层次的抽象意义则依赖于类的设计。
那静态内部类与普通内部类有什么区别呢?问得好,区别如下:
(1)静态内部类不持有外部类的引用
在普通内部类中,我们可以直接访问外部类的属性、方法,即使是private类型也可以访问,这是因为内部类持有一个外部类的引用,可以自由访问。而静态内部类,则只可以访问外部类的静态方法和静态属性(如果是private权限也能访问,这是由其代码位置所决定的),其他则不能访问。
(2)静态内部类不依赖外部类
普通内部类与外部类之间是相互依赖的关系,内部类实例不能脱离外部类实例,也就是说它们会同生同死,一起声明,一起被垃圾回收器回收。而静态内部类是可以独立存在的,即使外部类消亡了,静态内部类还是可以存在的。
(3)普通内部类不能声明static的方法和变量
普通内部类不能声明static的方法和变量,注意这里说的是变量,常量(也就是final static修饰的属性)还是可以的,而静态内部类形似外部类,没有任何限制。
[改善Java代码]使用静态内部类提高封装性的更多相关文章
- [改善Java代码] 提倡异常的封装
JavaAPI提供的异常都是比较低级别的,低级别是指只有开发人员才能看懂的异常.而对于终端用户来说基本上就是天书,与业务无关,是纯计算机语言的描述. 异常封装的三方面的好处: 1)提高系统的友好性 ...
- [改善Java代码]易变业务使用脚本语言编写
建议16: 易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP.Ruby.Groovy.JavaScript等,这些“入侵者”都有一个共同特征:全是同一类语言—脚本语言,它们 ...
- [改善Java代码]在接口中不要存在实现代码
第3章 类.对象及方法 书读得多而不思考,你会觉得自己知道的很多. 书读得多而思考,你会觉得自己不懂的越来越多. —伏尔泰 在面向对象编程(Object-Oriented Programming,O ...
- [改善Java代码]养成良好习惯,显式声明UID
建议11: 养成良好习惯,显式声明UID 我们编写一个实现了Serializable接口(序列化标志接口)的类, Eclipse马上就会给一个黄色警告:需要增加一个Serial Version ID. ...
- [改善Java代码]避免带有变长参数的方法重载
建议4: 避免带有变长参数的方法重载 在项目和系统的开发中,为了提高方法的灵活度和可复用性,我们经常要传递不确定数量的参数到方法中,在Java 5之前常用的设计技巧就是把形参定义成Collection ...
- [改善Java代码]推荐在复杂字符串操作中使用正则表达式
一.分析 字符串的操作,诸如追加.合并.替换.倒序.分隔等,都是在编码过程中经常用到的,而且Java也提供了append.replace.reverse.split等方法来完成这些操作,它们使用起来 ...
- [改善Java代码]减少HashMap中元素的数量
在系统开发中我们经常会使用HashMap作为数据集容器,或者是用缓冲池来处理,一般很稳定,但偶尔也会出现内存溢出的问题(OutOfMemory错误),而且这经常是与HashMap有关的.而且这经常是与 ...
- [改善Java代码]asList方法产生的List对象不可更改
上一个建议之处了asList方法在转换基本类型数组时候存在的问题,在看下asList方法返回的列表有何特殊的地方.看代码: import java.util.Arrays; import java.u ...
- [改善Java代码]Java的泛型是类型擦除的
泛型可以减少强制类型的转换,可规范集合的元素类型,还可以提高代码的安全性和可读性,正是因为有了这些优点,自从Java引入泛型之后,项目的编码规则上便多了一条,优先使用泛型. Java泛型(Generi ...
随机推荐
- Shell中的变量
一.什么是变量 变量在 bash 环境中是非常重要的,简单的说,就是让某一个特定字符串来代表不固定的内容.举例: 那就是:『 y = ax + b 』这东西,在等号左边的(y)就是变量,在等号右边的( ...
- iOS 开发的9个超有用小技巧
http://www.jianshu.com/p/221507eb8590 1.如何快速的查看一段代码的执行时间. 1 2 #define TICK NSDate *startTime = [NS ...
- HDU 4911 Inversion (逆序数 归并排序)
Inversion 题目链接: http://acm.hust.edu.cn/vjudge/contest/121349#problem/A Description bobo has a sequen ...
- Algorithms Part 1-Question 6- 2SUM Median-数和以及中位数问题
本次有两个编程问题,一个是求两个数的和满足一定值的数目,另一个是求中位数. 2SUM问题 问题描述 The goal of this problem is to implement a variant ...
- Lua学习笔记(三):函数和闭包
函数 lua的函数以function关键字开始,后跟函数名称和参数,最后以end结束,我们看一个简单的函数定义: function foo() --do something end function ...
- CLR探索应用程序域世界(上):Windbg SOS剖析揭示域世界
在CLR的世界中,有一系列的令人Amazing的技术和架构.其中,CLR对应用程序在内存中内存分配,执行模型,程序之间的交互等一系列的技术,值得每一个致力于DotNet平台的技术人员深究. 编程人员在 ...
- Node.js:实现知乎(www.zhihu.com)模拟登陆,获取用户关注主题
前一段时间,在瞎看看 Node.js,便研究通过 Node.js 实现知乎模拟登陆.相信,有很多网站有登陆权限设置,如若用户未登陆,将会跳转至首页提醒用户登陆,无法浏览部分页面. 如若是 b/s 架构 ...
- 让div变得大方美观 bootstrap
<div class="panel panel-default "> <div class="panel-heading"> <h ...
- Squid 日志详解
原文地址: http://www.php-oa.com/2008/01/17/squid-log-access-store.html access.log 日志 在squid中access访问日志最为 ...
- 关于C++与Java中虚函数问题的读书笔记
之前一直用C++编程,对虚函数还是一些较为肤浅的理解.可近期由于某些原因搞了下Java,发现有些知识点不熟,于是站在先驱巨人的肩上谈谈C++与Java中虚函数问题. Java中的虚函数 以下是段别人的 ...