1、封装

封装是指,一种将抽象性函式接口的实例细节部份包装、隐藏起来的方法。封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。要访问该类的代码和数据,必须通过严格的接口控制,通过该类提供的方法来实现对隐藏信息的操作和访问。

  • 封装好处

  • 只能通过规定的方法访问数据。

  • 隐藏类的实例细节,方便修改和实现。

  • 实现封装

  • 修改属性的可见性,在属性的前面添加访问控制修饰符。

  • 对每个值属性提供对外的公共方法访问,如创建 getter/setter(取值和赋值) 方法,用于对私有属性的访问。

  • 在 getter/setter 方法里加入属性的控制语句,例如我们可以加一个判断语句,对于非法输入给予否定。

    • 注意不要编写返回引用可变对象的访问器方法。如果需要返回一个可变对象的引用,应该首先对它进行克隆(clone)。对象克隆是指存放在另一个位置上的对象副本。更多参见:详解 Java clone 方法

2、包

为了避免类重名带来的问题,Java 提供了包机制,用于区别类名的命名空间。

  • 包的作用

  • 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。
  • 包采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。
  • 包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。
  • 定义语法

package 包名

3、访问修饰符

访问(控制)修饰符可以用来修饰属性和方法的访问范围。

  • 可以在任何另外一个类中,使用public类创建对象。
  • 如果一个类不加 public 修饰,则称这样的类为友好类,在同一个包中的其他类可以使用友好类创建对象。
  • 不能使用 protected 和 private 修饰类。

4、this 关键字

this关键字代表当前对象。当我们封装对象属性的时候,经常会使用this关键字。

举例来说,在Eclipse中可以自动帮我们定义私有属性的getter和setter方法:

当系统帮我们创建好了getter和setter方法后,我们会发现系统创建的方法中参数名和我们的属性名一样。为了解决成员变量和局部变量之间发生的同名的冲突,我们在属性名前面添加了this关键字。

public void setAge(int age) {
this.age = age;
}
  • 注一:this 关键字不能出现在类方法中。
  • 注二:如果构造器的第一个语句形如this(...),这个构造器将调用同一个类的另一个构造器。

5、内部类

可以将一个类的定义放在另一个类的定义内部,这就是内部类。而包含内部类的类被称为外部类。

  • 主要作用

  1. 内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。

  2. 内部类的方法可以直接访问外部类的所有数据,包括私有的数据

  3. 内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便。

  4. 内部类允许继承多个非接口类型。

  5. 内部类的类体中不可以声明类变量和类方法。

    注:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。所以内部类的成员变量/方法名可以和外部类的相同

  • 详细分类

  1. 成员内部类

相当于所在外部类的一个成员变量,可以使用任意访问修饰符。内部类里可以直接访问外部类的方法和属性。如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,可以使用 this 关键字。定义成员内部类后必须使用外部类对象来创建内部类对象,即:

  内部类 对象名 = 外部类对象.new 内部类();

所以成员内部类不能含有static的变量和方法,因为成员内部类需要先创建了外部类,才能创建它自己的。

2. 静态内部类

静态内部类是 static 修饰的内部类,通常被称为嵌套类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问。如果外部类的静态成员与内部类的成员名称相同,可通过类名.静态成员访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不相同,则可通过成员名直接调用外部类的静态成员。嵌套类和普通的内部类还有一个区别:普通内部类不能有static数据和static属性,也不能包含嵌套类,但嵌套类可以。而嵌套类不能声明为private,一般声明为public,方便调用。创建静态内部类的对象时不需要外部类的对象可以直接创建:

  内部类 对象名 = new 内部类();
  1. 局部内部类

局部内部类,是指内部类定义在方法和作用域内。局部内部类也像别的类一样进行编译,但只是作用域不同而已。不能使用public或private访问说明符进行声明。局部类的方法只能引用定义为final的局部变量。

  1. 匿名内部类
  • 当使用类创建对象时,程序允许把类体与对象的创建组合在一起。也就是说。类创建对象时,除了构造方法还有类体,此类体被认为是该类的一个子类去掉类声明后的类体,称为匿名类。匿名类就是一个子类,由于无名可用,不能用来声明对象,但是却可以直接用匿名类创建对象
  • 使用匿名类时,必然是在某个类中直接用匿名类创建对象,因此匿名类一定是内部类。因为没有名字,不能重用,通常用来简化代码。使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口。匿名内部类是不能加访问修饰符的。当所在的方法的形参需要在内部类里面使用时,该形参必须为final。要注意的是,new 匿名类,这个类是要先定义的。
  • 尽管匿名类创建的对象没有经过类声明步骤,但匿名类对象的引用必须传递给一个匹配的参数,匿名类的主要用途就是向方法的参数传值。
//假设f(B x)是一个方法
void f(B x) {
//x调用B中的方法
}
//其中参数是B类对象,那么在调用方法f时可以向其参数x传递一个匿名对象,如
f (new B() {
//匿名类的类体
}
);
  • 此外还有一种和接口相关的匿名类。类似的,Java 允许直接用接口名和一个类体创建一个匿名对象。如果某个方法的参数是接口类型,那么可以使用接口名和类体组合创建一个匿名对象传递给方法的参数,类体必须要实现接口中的全部方法。

参考资料

  • 实验楼:Java编程语言(新版)
  • Java核心技术 卷Ⅰ基础知识 原书第8版
  • Java2实用教程 (第三版)_ 耿祥义,张跃平

Java 封装(内部类)的更多相关文章

  1. JAVA基础——内部类详解

    JAVA内部类详解 在我的另一篇java三大特性的封装中讲到java内部类的简单概要,这里将详细深入了解java内部类的使用和应用. 我们知道内部类可分为以下几种: 成员内部类 静态内部类 方法内部类 ...

  2. 第30节:Java基础-内部类

    内部类 // 外部类 class Demo{ private int num = 3; // 定义内部类 class Int{ void show(){ System.out.println(&quo ...

  3. java中内部类的积累

    放在一个类的内部的类我们就叫内部类. 二. 作用 1.内部类可以很好的实现隐藏 一般的非内部类,是不允许有 private 与protected权限的,但内部类可以 2.内部类拥有外围类的所有元素的访 ...

  4. java中内部类的讲解

    java中有一个内部类的概念,由于之前一直比较忙,没有单独拿出时间总结一下,今天我就把内部类的相关知识进行一下汇总,如果有不足之处,欢迎批评指正. 1)java内部类的概念.       在一个类的的 ...

  5. 小白学Java:内部类

    目录 小白学Java:内部类 内部类的分类 成员内部类 局部内部类 静态内部类 匿名内部类 内部类的继承 内部类有啥用 小白学Java:内部类 内部类是封装的一种形式,是定义在类或接口中的类. 内部类 ...

  6. Java学习--内部类(一)

    Java学习--内部类(一) 一. 内部类的定义和特点 class Outer{ privite int num = 5; class Inner{ public void Display(){ Sy ...

  7. Java的内部类

    Java的内部类 首先我们来了解一下什么是内部类? 内部类是指在一个外部类的内部再定义一个类.内部类可以是静态static的,也可用public,default,protected和private修饰 ...

  8. 【原创】中文分词系统 ICTCLAS2015 的JAVA封装和多线程执行(附代码)

    本文针对的问题是 ICTCLAS2015 的多线程分词,为了实现多线程做了简单的JAVA封装.如果有需要可以自行进一步封装其它接口. 首先ICTCLAS2015的传送门(http://ictclas. ...

  9. java使用内部类的好处及其初始化

    java使用内部类的原因 每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响          java内部类初始化 ForeCatal ...

  10. java封装的方法

    java封装是由Java是面向对象程序设计语言的性质决定的,面向对象程序设计语言的三大特性之一就是封装.封装其实就是包装的意思,从专业的角度来看,就是把对象的所有组成部分组合在一起,保护私有属性. 如 ...

随机推荐

  1. HTML5 的拖放(实例:两个div之间拖放图片)

    重点解释: 首先,为了使元素(如本图片)可拖动,把 draggable 属性设置为 true : dataTransfer.setData() 方法设置被拖数据的数据类型和值: ondragover ...

  2. nextval 遍历ResultSet,行列要从1开始

    nextval nextval与序列关联,表示下一个,如:创建里一个序列seq_1:#序列一般表示第几行,起标识作用create sequence seq_1 increment by 1 start ...

  3. Linux下一个最简单的不依赖第三库的的C程序(2)

    一个最简单的C程序,如下: main.c: int main() { char *str = "Hello World"; ; } 在64位平台上编译一个32位的程序,如下:(32 ...

  4. Java集成groovy之GroovyShell、GroovyScriptEngine、GroovyClassLoader

    GroovyClassLoader 用 Groovy 的 GroovyClassLoader ,动态地加载一个脚本并执行它的行为.GroovyClassLoader是一个定制的类装载器,负责解释加载J ...

  5. Gradle修改缓存路径 和 Gradle修改Maven仓库地址

    Gradle修改缓存路径 修改gradle启动脚本进入gradle安装的bin目录,使用文本编辑器打开gradle.bat文件,在如图的位置添加以下语句 set GRADLE_OPTS="- ...

  6. Thymeleaf学习记录(5)--运算及表单

    Thymeleaf文本及预算: 字面 文本文字:'one text','Another one!',... 号码文字:0,34,3.0,12.3,... 布尔文字:true,false 空字面: nu ...

  7. java 自定义 LRU(最近最少使用)策略 实现 缓存机制

    1. java提供了一个简单的方式实现LRU:  LinkedHashMap   2. 自定义实现 LRU至少需要两个主要操作: 添加(add)和搜索(search) public class LRU ...

  8. JS原生带小白点轮播图

    咱们刚刚说了js原生轮播图,现在给他加上可以随着一起走动的小圆点吧! css代码: *{ margin:0px; padding: 0px; } ul{ width: 2500px; height: ...

  9. Grunt入门学习之(1) -- 环境安装

    Grunt入门学习(1) - 环境安装 这周根据项目需要,在项目的基础上分模块开发了一个小的项目板块,但是在规范组织每个模块的代码和其依赖性时比较麻烦,需要一个项目板块的构建工具.各个模块都包括其对应 ...

  10. Python爬虫教程-08-post介绍(百度翻译)(下)

    Python爬虫教程-08-post介绍(下) 为了更多的设置请求信息,单纯的通过urlopen已经不太能满足需求,此时需要使用request.Request类 构造Request 实例 req = ...