3.类和对象
1.类的结构
1 | [public][abstract|final]class<class_name>[extends<class_name>][implements<interface_name>] { |
提示:上述语法中,中括号“[]”中的部分表示可以省略,竖线“|”表示“或关系”,例如 abstract|final,说明可以使用 abstract 或 final 关键字,但是两个关键字不能同时出现。
上述语法中各关键字的描述如下。
class_name:类的名称。
extends:表示继承其他类。
implements:表示实现某些接口。
property_type:表示成员变量的类型。
property:表示成员变量名称。
function():表示成员方法名称。
1.成员方法的结构 :
成员方法一旦被定义,便可以在程序中多次调用,提高了编程效率。声明成员方法的语法格式如下:
1 | [public|private|protected][static]<void|return_type><method_name>([paramList]) { |
上述代码中一个方法包含 4 部分:方法的返回值、方法名称、方法的参数和方法体。其中 retum_type 是方法返回值的数据类型,数据类型可以是原始的数据类型,即常用的 8 种数据类型,也可以是一个引用数据类型,如一个类、接口和数组等。
paramList 表示参数列表,这些变量都要有自己的数据类型,可以是原始数据类型,也可以是复杂数据类型,一个方法主要依靠参数来传递消息。
2.构造方法的结构:
Java 构造方法有以下特点:
-方法名必须与类名相同
-可以有 0 个、1 个或多个参数
-没有任何返回值,包括 void
-默认返回类型就是对象类型本身
-只能与 new 运算符结合使用
注意:构造方法不能被 static、final、synchronized、abstract 和 native修饰。构造方法用于初始化一个新对象,所以用 static 修饰没有意义。构造方法不能被子类继承,所以用 final 和 abstract 修饰没有意义。多个线程不会同时创建内存地址相同的同一个对象,所以用 synchronized 修饰没有必要
3.成员变量和局部变量
局部变量和成员变量的名字相同,则成员变量被隐藏,得使用关键字this使用成员变量
1.成员变量
Java 的成员变量有两种,分别是全局变量(实例变量)和静态变量(类变量)。
名称 | 修饰 | 访问 | 生命周期 | 作用域 |
---|---|---|---|---|
全局变量(实例变量) | 无 static 修饰 | 对象名.变量名 | 只要对象被当作引用,实例变量就将存在 | 在类内有效 |
静态变量(类变量) | 用 static 修饰 | 类名.变量名或对象名.变量名 | 其生命周期取决于类的生命周期。类被垃圾回收机制彻底回收时才会被销毁 | 该局部变量所在的块作用域中位置之后 |
特性:
- 成员变量创建时有默认值,默认值根据类型而定
- 对成员变量的操作只能放在方法中,方法外不可以对成员变量操作
2.局部变量
局部变量是指在方法或者方法代码块中定义的变量,其作用域是其所在的代码块。可分为以下三种:
- 方法参数变量(形参):在整个方法内有效。
- 方法局部变量(方法内定义): 从定义这个变量开始到方法结束这一段时间内有效。
- 代码块局部变量(代码块内定义):从定义这个变量开始到代码块结束这一段时间内有效。
特性:
- 局部变量的作用域和生存期只在方法内有效,且与其声明的位置有关
- 局部变量无初始值,在使用前必须被初始化值。
2.对象的创建 使用和销毁
1.对象的创建
1. 使用 new 关键字创建对象
这是常用的创建对象的方法,语法格式如下:
1 | 类名 对象名 = new 类名(); |
2. 调用 java.lang.Class 或者 java.lang.reflect.Constuctor 类的 newlnstance() 实例方法
1 | java.lang.Class Class 类对象名称 = java.lang.Class.forName(要实例化的类全称); |
调用 java.lang.Class 类中的 forName() 方法时,需要将要实例化的类的全称(比如 com.mxl.package.Student)作为参数传递过去,然后再调用 java.lang.Class 类对象的 newInstance() 方法创建对象。
3. 调用对象的 clone() 方法
该方法不常用,使用该方法创建对象时,要实例化的类必须继承 java.lang.Cloneable 接口。 调用对象的 clone() 方法创建对象的语法格式如下:
1 | 类名对象名 = (类名)已创建好的类对象名.clone(); |
4. 调用 java.io.ObjectlnputStream 对象的 readObject() 方法
2.对象的使用
每个对象都有自己的属性和行为,这些属性和行为在类中体现为成员变量和成员方法,其中成员变量对应对象的属性,成员方法对应对象的行为。
在 Java 中,要引用对象的属性和行为,需要使用点(.)操作符来访问。语法格式如下:
1 | 对象名.属性(成员变量) // 访问对象的属性 |
3.对象的销毁
对象使用完之后需要对其进行清除。对象的清除是指释放对象占用的内存。在创建对象时,用户必须使用 new 操作符为对象分配内存。不过,在清除对象时,由系统自动进行内存回收,不需要用户额外处理。
Java 语言的内存自动回收称为垃圾回(GarbageCollection)机制,简称 GC。垃圾回收机制是指 JVM 用于释放那些不再使用的对象所占用的内存。一个对象被当作垃圾回收的情况主要如下两种。
1 | 1)对象的引用超过其作用范围。 |
1 | 2)对象被赋值为 null。 |
在 Java 的 Object 类中还提供了一个 protected 类型的 finalize() 方法,因此任何 Java 类都可以覆盖这个方法,在这个方法中进行释放对象所占有的相关资源的操作。
在 Java 虚拟机的堆区,每个对象都可能处于以下三种状态之一。
1)可触及状态:当一个对象被创建后,只要程序中还有引用变量引用它,那么它就始终处于可触及状态。
2)可复活状态:当程序不再有任何引用变量引用该对象时,该对象就进入可复活状态。在这个状态下,垃圾回收器会准备释放它所占用的内存,在释放之前,会调用它及其他处于可复活状态的对象的 finalize() 方法,这些 finalize() 方法有可能使该对象重新转到可触及状态。
3)不可触及状态:当 Java 虚拟机执行完所有可复活对象的 finalize() 方法后,如果这些方法都没有使该对象转到可触及状态,垃圾回收器才会真正回收它占用的内存。
注意:调用 System.gc() 或者 Runtime.gc() 方法也不能保证回收操作一定执行,它只是提高了 Java 垃圾回收器尽快回收垃圾的可能性。
4.匿名对象
匿名对象就是没有明确的给出名字的对象,是对象的一种简写形式。一般匿名对象只使用一次,而且匿名对象只在堆内存中开辟空间,而不存在栈内存的引用。
1 | public class Person { |
3.方法重载(有相同的名字,不同的参数,便产生了重载)
方法重载分为两种重载:
- 构造方法重载
- 方法重载
重载条件:
- ⽅法名称必须相同。
- 参数列表必须不同(个数不同、或类型不同、参数类型排列顺序不同等)。
- ⽅法的返回类型可以相同也可以不相同。
- 仅仅返回类型不同不⾜以成为⽅法的重载。
- 重载是发⽣在编译时的,因为编译器可以根据参数的类型来选择使⽤哪个⽅法。
4.可变参数
当几个方法名称相同,功能相同,参数个数不同时,可以使用可变参数优化
声明可变参数的语法格式如下:
1 | methodName({paramList},paramType…paramName) |
- 在定义了可变参数后,我们可以像操作数组一样操作该参数,即对数组的操作也可以对可变参数操作(可变参数的本质是数组)
- 如果该方法除了可变参数还有其它的参数,可变参数必须放到最后;
- 调用使用了可变参数的方法时,参数可以是0个或任意个,参数之间靠逗号隔开
- 可变参数可以传入一个数组;
- 拥有可变参数的方法可以被重载,在被调用时,如果能匹配到参数定长的方法则优先调用参数定长的方法。
- 一个参数列表只能有一个可变参数
5.包管理
Java 中使用 package 语句定义包,package 语句应该放在源文件的第一行,在每个源文件中只能有一个包定义语句,并且 package 语句适用于所有类型(类、接口、枚举和注释)的文件。定义包语法格式如下:
1 | package 包名; |
包导入:
使用 import 导入单个类的语法格式如下:
1 | import 包名+类名; |
注意:使用星号(*)可能会增加编译时间,特别是引入多个大包时,所以明确的导入你想要用到的类是一个好方法,需要注意的是使用星号对运行时间和类的大小没有影响
当两个包内有重名类时,只能导入其中一个,另一个引用时得写入完整包名,否则会发生冲突、
包的 3 个作用:
- 区分相同名称的类。
- 能够较好地管理大量的类。
- 控制访问范围。