六、封装
6.1 封装的概念
封装是面向对象程序三大特性之一,封装就是将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。
简单来说,就像生活中我们常用的手机,有充电口,有关机和音量键,这些都是对外公开的接口,但是具体里面是怎么构成的我们不知道,也不需知道,只需要使用其功能即可。
6.2 访问限定符
访问权限就是来控制类、方法、字段使用的权限大小。
private | default | protected | public | |
---|---|---|---|---|
同一包中的同一类 | √ | √ | √ | √ |
同一包中的不同类 | √ | √ | √ | |
不同包中的子类 | √ | √ | ||
不同包中的非子类 | √ |
注:default权限是指什么都不写时的默认权限
public class Test {
private int a;
int b;
protected int c;
public int d;
private void fuc1() {
//...
}
void fuc2() {
//...
}
protected void fuc3() {
//...
}
public void fuc() {
//...
}
}
要注意的是,类只能被default权限或者publi权限修饰,一个包中只能有一个public类。
6.3 什么是包
包就是为了更好的管理类,把多个类收集在一起成为一组,成为软件包。类似于文件夹,一个文件夹里面有多个文件夹(包),文件夹里面有其他的内容(类)。
将类进行封装到不同的包中的一个重要作用是在一个工程中能够允许在不同包中含有相同名称的类。
6.3.1 导入包中的类
Java中提供了很多现成的类供我们使用,如Date类,可以使用java.util.Date导入java.util这个包中的Date类。
java.util.Date date = new java.util.Date();
但这样导入有点麻烦吗,我们可以通过import语句导入包
import java.util.Date;
public class Test {
public static void main(String[] args) {
Date date1 = new Date();
}
}
当然也可以使用 import java.util.*; 但是不建议这样写,容易出现冲突,更建议使用了哪个类就导入指定的类名。
如上图所示,在这两个包中都有一个叫Date的类,但是他们并不一样,导入两个类的包,是无法识别到底使用那个包中的类。解决方法如下代码所示。
import java.util.Date;
public class Test {
public static void main(String[] args) {
Date date1 = new Date();
java.sql.Date date = new java.sql.Date(2);
}
}
可以使用import static导入包中静态的方法和字段
import static java.lang.Math.*;
public class Test {
public static void main(String[] args) {
double x = 3;
double y = 4;
//double result = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
double result = sqrt(pow(x,2)+pow(y,3));
}
}
sqrt和pow都是静态方法
6.3.2 自定义包
创建包
基本规则 在文件的最上方加上一个 package 语句指定该代码在哪个包中.
包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式(例如 com.csdn.www).
包名要和代码路径相匹配. 例如创建 com.csdn.www 的包, 那么会存在一个对应的路径 com/csdn/www来存储 代码. 如果一个类没有 package 语句, 则该类被放到一个默认包中.
6.3.3 包的权限举例
Demo类是default权限的类,只能在同一个包中被访问,而Test类是在src包中,与Demo不在一个包中,所以在实例化Demo时会报错,就是因为访问权限的问题。
七、 static成员
7.1static 修饰成员变量
static修饰的成员变量称为静态成员变量,其特点是不属于某个具体的对象,是所有对象所共享的,是类的属性,既可以用对象访问,也可以通过类名访问(推荐),类变量储存在方法区,生命周期伴随类的一生。
public class Test {
public static int a;
public int b;
public int c;
public static void main(String[] args) {
Test.a = 10;
System.out.println(a);
Test test = new Test();
test.b = 2;
test.c = 3;
test.a = 5;
System.out.println(test.b +" " +test.c + " " +test.a);
}
}
上述代码可以表明:静态成员变量不依赖于对象,属于类。
7.2 static修饰成员方法
public class Test {
public static int a;
public int b;
public int c;
public static void fuc(){
System.out.println("静态变量:" + a);
fuc0();
Test test = new Test();
System.out.println("非静态变量:" + test.b + " " + test.c);
}
public static void fuc0() {
System.out.println("静态方法");
}
public void fuc1() {
System.out.println("静态变量:" + a);
Test test = new Test();
System.out.println("非静态变量:" + test.b + " " + test.c);
}
public static void main(String[] args) {
Test.fuc();
System.out.println("------------");
Test test = new Test();
test.fuc1();
}
}
上述代码可知:在静态的方法中不能直接使用任何非静态的成员和成员方法,要想使用,就必须通过new对像,然后通过对象的引用访问,但是在非静态方法中,可以直接使用静态的成员变量或成员方法。
7.3 static成员变量初始化
7.3.1 就地初始化
在定义时直接给出初始值。
public class Test {
public static int a = 10;
}
7.3.2 静态代码块初始化
public class Test {
public static int a;
//静态代码块
static {
a = 10;
}
}
八、代码块
8.1 代码块的分类
代码块就是使用{}定义的一段代码称为代码块,分为四种:
- 普通代码块
- 构造块
- 静态块
- 同步代码块(后续讲)
8.2 普通代码块
public class Test {
//直接使用{}
{
int a = 10;
}
}
8.3 构造代码块
构造代码块也叫实例代码块,一般用于初始化实例成员变量。
public class Test {
private int a;
private int b;
public int c;
{
this.a = 10;
this.b = 20;
this.c = 5;
}
public void show() {
System.out.println(this.a + " " + this.b + " " + this.c);
}
public static void main(String[] args) {
Test test = new Test();
test.show();
}
}
8.4 静态代码块
静态代码不管生成多少个对象,都只会执行一次;静态成员变量时类的属性,因此在JVM加载类的时候就会开辟空间并初始化;如果一个类中包含多个静态代码块,在编译时,编译器会按照定义的先后顺序依次进行;而示例代码块只有在创建对象时才会执行。
如下案例证实:
public class Test {
private int a;
private int b;
public static int c;
public Test() {
System.out.println("构造函数");
System.out.println("---------");
}
static{
c = 20;
System.out.println("静态代码块");
System.out.println("---------");
}
{
this.a = 10;
this.b = 5;
System.out.println("实例化代码块");
System.out.println("---------");
}
public static void main(String[] args) {
Test test = new Test();
System.out.println(test.a + " " + test.b + " " + c);
}
}