前文回顾
在类和对象(一)中,介绍了面向对象和面向过程的区别,还介绍了类的定义、使用及类是如何实例化的,再引出了this引用和几种构造方法,最后是对象的打印
接下来将要介绍
1.包(package)
1.1为什么使用包
在前文提到一般一个文件当中只定义一个类,随着我们代码的编写,类会越来越多,看起来就不太方便,所以我们需要一个目录,将一些有关联关系的类,放到同一个目录下。
Java 中就把这样的目录叫做 “包”
不是所有的目录称做“包”,是只包含 .java 代码的目录才可以叫做包
包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式
在同一个工程中允许存在相同名称的类,只要处在不同的包中即可
1.2包的创建及使用
包名一般采用纯小写字母表示
当我们将某个类放到包中的时候,IDEA 会自动在类最上方添加一个 package 语句,用来声明当前这个类属于哪个包
如果没有自动生成需要手动添加,否则会编译失败
选择包后右键,在 Open in 中选择 Explorer 就可以打开我们的文件目录
这个文件夹就是我们刚刚所创建包
包里可以可以继续创建包
如果包里只有另一个包时,包名会被简化成下列形式
使用包时有一个约定俗称的规矩:
每个程序的包名都是要唯一的,使用 公司/组织 的 域名 的 倒序形式 来表示
当我们希望导入其他包时,就需要使用 import 语句
语法格式:import 包名
像使用输入方法和随机方法时都导入了对应的包
import java.util.Random;
import java.util.Scanner;
2.封装【重点】
2.1封装的定义
广义:把细节隐藏起来,创建方法,就是把方法实现的细节隐藏起来,创建类,把累的实现细节藏起来,实现网络协议,也是把下层的网络协议隐藏起来
狭义:专门指类这一种情况,把类的实现细节隐藏起来
像我们生活中的主机,用户只需要摁开机键就可以启动电脑,不需要知道主机内部是怎么启动的
接下来我们要实现的封装,就是类中的方法和属性,只能在类内部使用,外部感知不到
2.2 private / public 的区别
private 修饰的属性/方法,就是只能在类的内部使用(封装起来了)
public 修饰的属性/方法,在类的外部仍然可以使用(没有封装)
也不是所有的属性/方法都要进行封装,需要留有一部分内容给外面使用,这取决于实际的代码场景。区分方式为
用户是否应该进行这样的操作?
如果需要就 public , 不需要就 private
例如:给电脑插上显示器 => public 给电脑更换CPU => private
2.3封装后的使用
这里我们可以看到,我们将 Student 类中的 name 设为了 private ,在 Test 类中我们就没有办法进行调用
解决方法也很简单,我们在 Student 类中写一个 public 方法,再在 Test 的类中调用,如下图
这里的 name 没有初始化,所以是 null 。
这样就是做出了对代码的灵活性做出了限制,让使用者不能随心所欲的使用
当我们操作一台计算机,也不是直接操作cpu,而是通过 鼠标/键盘 这样的设备给整个计算机发号施令,让操作系统去指挥一些硬件进行工作
当我们需要往里传值时
通过 setter 方法设置参数,通过 getter 方法获取参数
这里同样可以通过 IDEA 自带的方式快速设置
3. static成员
3.1 static的定义
在前文我们定义了一个 Student 类,里面有成员变量 name ,Gender,每个对象中都会包含一份(称之为实例变量),现在希望有一个变量用来表示学生上课的教室,这个教室的属性并不需要每个对象都存储一份,而是让所有学生来共享,我们就需要用到 static 来修饰
在Java中,被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对 象,是所有对象所共享的。
3.2 static 修饰类
这里通过 static 修饰了变量 classroom
在 Test 类中实例并改变参数最后打印
通过运行结果就可以看到 s1 的赋值已经被 s2 覆盖了,这就是 static 修饰的静态成员
注意的 classroom 作为类属性,应该通过 类名 . 去访问,在Java中,使用 对象 . 的方式也能使用,主要还是编译器比较智能,可以通过 s1 和 s2 的类型去找到 Student 类,从而完成 Student.m 的操作
【静态成员变量特性】
- 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
- 既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问
- 类变量存储在方法区当中
- .生命周期伴随类的一生(即:随类的加载而创建,随类的卸载而销毁),不加 static 的属性是伴随对象的一生
3.3 static 修饰方法
这个时候表示方法就和类相关,和实例无关了
static 修饰属性,决定属性存储的位置
static 修饰方法,不影响方法存储的位置(都在方法区,和类在一起)
没有 static 就要通过 实例名.方法名 的方式来调用.
此时方法内部也可以使用 实例属性和其他的实例方法
有 static 就得通过 类名.方法名 的方式来调用( 实例名.方法名 也能有效,但是不推荐)
此时方法内部,不能使用实例属性,也不能使用其他的实例方法
3.3.1 static 调用属性
代码实例
public int n = 10;//实例属性
//实例属性,在实例化后可以使用的属性,在面向对象编
//程中,当我们创建一个类的实例时,实例会自动获得类中定义的实例属性。
static public int m = 20;//类属性
//类属性是指属于类本身,而不是类的实例的属性。类属
//性在类的声明中定义,且在所有该类的实例之间共享。通过访问类而不是实例来使用类属性。
这里先创建好两个属性,再写方法进行调用
可以看到被 static 修饰的方法调用不了实例属性 n
报错:不能从静态上下文引用非静态字段 'n'
因为这里程序不知道这里的 n 是哪个实例的,所有可以修改一下
这里注意一点,静态方法中是没有 this 的
this 指向当前实例,而静态方法中就没有实例这样的概念
报错:不能从静态上下文引用 'object.Test.this'
3.3.2 static 调用方法
3.4小结
上述内容中最核心的一点是
static 修饰的方法,里面没有 this !!!
使用 实例属性/实例方法 本质上都是 this ,只是大部分都可以省略
有 this ,则四个都可以用(实例属性/实例方法/类属性/类方法)
无 this ,只可以使用 static 修饰的 类属性/类方法
3.4 main 方法
当生成 main 方法时可以看到,它也是被 static 修饰的
调用 main 方法,就需要通过 类名.main 的方式来调用,这个过程 JVM 会自动完成
4.代码块
就是 { }
4.1 普通代码块
//定义在方法的中代码块
定义方法{ }
if { }
while { }
for { }
//主要作用就是限定了局部变量的范围
4.2 构造代码块
构造块:定义在类中的代码块(不加修饰符)。也叫:实例代码块,构造代码块一般用于初始化实例成员变量
{
}
- 执行时机在 new 对象的时候,在构造方法之前
- 可以访问 实例属性/方法,类属性/方法
4.3 静态代码块
在构造代码块前加上 static 定义的代码块称为静态代码块,一般用于初始化静态成员变量
static {
}
- 执行时机在类加载的时候,且只执行一次
- 不能访问 实例属性/方法
- 由于静态的成员可以就地初始化,所有一般不用专门写静态代码块来初始化静态变量
- 静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
- 如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)
代码示例:
小试牛刀
1.下列哪个说法是正确的?
A.在静态的成员方法当中,可以使用非静态成员变量
B.在静态的成员方法中,可以使用 this 关键字
C.在非静态的成员方法中,可以使用静态成员变量
D.静态的成员方法和静态的成员变量,属于对象也就是在每个对象中都包含