目录
一:封装
1.封装的概念
将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。
举例:对于电脑这样一个复杂的设备,提供给用户的就只是:开关机、通过键盘输入,显示器,USB插孔等。但实际上:电脑真正工作的却是CPU、显卡、内存等一些硬件元件。因此计算机厂商在出厂时,在外部套上壳子,将内部实现细节隐藏起来,仅仅对外提供开关机、鼠标以及键盘插孔等,让用户可以与计算机进行交互即可。
2.访问限制符
Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用。
Java中提供了四种访问限定符:
private | default | protected | public | |
---|---|---|---|---|
同一包中的同一类 | √ | √ | √ | √ |
同一包中的不同类 | √ | √ | √ | |
不同包中的子类 | √ | √ | ||
不同包中的非子类 | √ |
默认default访问权限
protected主要用在继承中
当修饰类时:访问权限只能用public或者默认
同一包的不同类:证明private的私有
不同包的非子类:color(default)无法使用
注意: 一般情况下成员变量设置为private,成员方法设置为public 。
3.封装扩展之包
3.1:包的概念
在面向对象体系中,提出了一个软件包的概念,即:为了更好的管理类,把多个类收集在一起成为一组,称为软件包。
包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式,比如:一个包中的类不想被其他包中的类使用。
包还有一个重要的作用:在同一个工程中允许存在相同名称的类,只要处在不同的包中即可。
3.2:导入包中的类
1.可以使用现成的类,例如Date类。java.util.Date是类的途径
2.也可以使用 import语句导入包
如果需要使用 java.util 中的其他类, 可以使用 import java.util.*
表示util包中所有的类都可以在当前类中直接使用,虽然使用起来非常方便,但可能会产生冲突。
解决方法:将Date类的完整路径具体化,采用包中类使用方式一。
3.静态导包:
3.3:自定义包
在文件的最上方加上一个 package 语句指定该代码在哪个包中。
包名需要尽量指定成唯一的名字。
包名要和代码路径相匹配。
如果一个类没有 package 语句, 则该类被放到一个默认包中。
3.4:常见的包
1. java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
2. java.lang.reflect:java 反射编程包;
3. java.net:进行网络编程开发包。
4. java.sql:进行数据库开发的支持包。
5. java.util:是java提供的工具程序包。
6. java.io:I/O编程开发包。
二:static关键字
- 想要在类中加一个字段,这个字段与具体的对象没有关系,它是和当前类有关系,它是属于这个类的,是类的属性。将该字段用static修饰即可
- 被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的。
证明:
- 注意:
1:静态成员变量可以通过对象访问,更推荐通过类(类名.静态成员变量)直接访问。
2:静态成员变量随着类的加载而创建,随着类的卸载而销毁。
3:JDK7及以前,HotSpot(Java虚拟机)中存储在方法区,JDK8及之后,类变量存储在Java堆中
- 注意:Student类JVM将类加载(静态成员变量开始创建)到其内部之后,类其实也是也个对象(类里有啥包含啥);当类被卸载时,静态成员变量才会被销毁(垃圾回收器)。与Student s = new Student()里new了一个Student的对象不同,这里的对象包含name,gender,age
三:static修饰成员方法
- static修饰的成员方法称为静态成员方法
- 静态方法特性:
1. 不属于某个具体的对象,是类方法。
2. 可以通过对象调用,也可以通过类名.静态方法名(...)方式调用,更推荐使用后者。
3. 静态方法没有隐藏的this引用参数,因此不能在静态方法中访问任何非静态成员变量(实例变量)。
4. 静态方法中不能调用任何非静态方法(实例方法),因为非静态方法有this参数,在静态方法中调用时候无法传递this引用 。
- 注意:在实例方法中可以访问静态成员
四:static成员变量初始化
静态成员变量的初始化分为两种:就地初始化 和 静态代码块初始化。
注意:静态成员变量一般不会放在构造方法中来初始化,构造方法中初始化的是与对象相关的实例属性
五:代码块
1:代码块概念与分类
使用{}定义的就是代码块。
2:分类:
- 普通代码块:直接使用{}定义
- 构造块(实例代码块):定义在类中的代码块(不加修饰符),一般用于初始化实例成员变量
在创建对象时实例代码块会执行,每创建一个对象,实例代码块就执行一次。
当创建对象时会调用构造方法
在创建对象时,先执行实例代码块,再执行构造方法。
实例代码块中的内容,编译器在编译代码时,会将实例代码块中的内容拷贝到构造方法中--而且是在构造方法第一条语句前。
编译期间编译器会将就地初始化内容拷贝到构造方法中。
- 静态代码块
使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量。
无论创建多少个对象,静态代码块只执行一次。并且是在创建对象之前进行调用的。
静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的。
如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次合并,最终放在生成的<clinit>方法中,该方法在类加载时调用,并且只调用一次。
多个实例代码块最终也会按照定义的先后次序合并成一份并将其拷贝到每个构造方法中。
- 同步代码块
六:内部类
1:概念
当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类。在 Java 中,可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。内部类也是封装的一种体现。
public class OutClass{
class InnerClass{
}
}
OutClass是外部类,InnerClass是内部类。
同一个.java的源文件中可以存在多个类,如果一个源文件里面有两个类,那么只能有一个public。
注意:内部类和外部类共用同一个java源文件,但是经过编译之后,内部类会形成单独的字节码文件
2:分类
成员内部类里分为:
- 普通内部类:被static修饰的成员内部类
- 静态内部类:未被static修饰的成员内部类
普通内部类注意:
1. 外部类中的任何成员都可以被在普通内部类方法中直接访问。
2. 普通内部类所处的成员与外部类成员位置相同,因此也受public、private等访问限定符的约束。
3. 在内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名称.this.同名成员 来访问。
4. 普通内部类对象必须在先有外部类对象前提下才能创建(使用时先构造外部类的对象,再通过外部类的对象访问内部类)。
//外部类对象 ti
TestInnerClass ti = new TestInnerClass();
//借助ti创建内部类对象
InnerClass ic = ti.new InnerClass();
5. 普通内部类的非静态方法中包含了一个指向外部类对象的引用。
使用外部类成员变量时,实际上内部类此处会再增加一个引用类型的变量,是编译器增加:this$数字-------指向外部类对象。
6. 外部类中,不能直接访问内部类中的成员,如果要访问必须先要实例化内部类的对象,通过:对象.成员变量 来访问
静态内部类注意:
1. 在内部类中只能访问外部类中的静态成员
2. 创建内部类对象时,不需要先创建外部类对象
3. 成员内部类,经过编译之后会生成独立的字节码文件,命名格式为:外部类名称$内部类名称
- 局部内部类
该内部类只能在该方法中使用,其他位置都使用不了
注意:
1.不能被访问限制符限制---public
2.不能在局部内部类中定义静态成员
3.编译器也有自己独立的字节码文件,命名格式:外部类名字$x内部类名字.class,x是一个整数。