【Java专题】类和对象

类(class)可以看作一个模版,系统根据类的定义来创造对象(object/instance)。
类是对一类事物的抽象,定义了该类事物的属性和行为。对象是类的实例化,是具体存在的个体。
面向对象编程的基本原则包括封装、继承和多态,这些原则都是基于类和对象的概念来实现的。

基本结构

  • 属性(field):也称为成员变量,是类中定义的变量,用来描述对象的状态或特征
  • 方法(method):也称为成员方法,是类中定义的函数,用来描述对象的行为或功能
  • 构造器(constructor):是一种特殊的方法,用来初始化对象的属性
  • 内部类(inner class 可选):是定义在另一个类内部的类,可以访问外部类的成员变量和方法

修饰符

访问修饰符

  • public:公共的,任何类都可以访问
  • protected:受保护的,只有同一个包中的类和不同包中的子类可以访问
  • 默认(default):没有修饰符,只有同一个包中的类可以访问
  • private:私有的,只有本类可以访问
访问修饰符 同一类 同一包 子类(不同包) 其他包
public
protected
default
private

其他修饰符

  • static:静态的,属于类而不是对象,可以直接通过类名访问
  • final:最终的,不能被继承或重写
  • abstract:抽象的,不能被实例化,必须由子类来实现
  • synchronized:同步的,用于线程安全的访问控制
  • transient:短暂的,表示该属性不需要被序列化
  • volatile:易变的,表示该属性可能被多个线程同时访问,禁止指令重排序优化

类属性

  • 成员变量:定义在类中方法外的变量,属于对象的属性,每个对象都有自己的成员变量副本
  • 静态变量:定义在类中方法外,并且使用static修饰的变量,属于类的属性,所有对象共享同一个静态变量副本
1
2
3
class MyClass {
[访问修饰符] [static] 数据类型 变量名;
}

类方法

  • 成员方法:定义在类中,并且没有使用static修饰的方法,属于对象的行为,每个对象都有自己的成员方法副本
  • 静态方法:定义在类中,并且使用static修饰的方法,属于类的行为,所有对象共享同一个静态方法副本,可以直接通过类名访问
1
2
3
4
5
class MyClass {
[访问修饰符] [其他修饰符] 返回类型 方法名(参数列表) {
// 方法体
}
}

构造器

构造器是一种特殊的类方法,用于初始化对象的属性(构造之前对象已经创建好了)。
构造器的名称必须与类名相同,并且没有返回类型。
构造器可以有参数,也可以没有参数,如果没有定义任何构造器,Java会提供一个默认的无参构造器。
如果定义了带参数的构造器,Java将不再提供默认的无参构造器,需要手动定义一个无参构造器。

1
2
3
4
5
6
7
8
9
10
class MyClass {
// 无参构造器
public MyClass() {
// 初始化代码
}
// 带参数的构造器
public MyClass(参数列表) {
// 初始化代码
}
}

this 关键字

this是一个引用变量,指向当前对象的实例,可以用来访问当前对象的成员变量和成员方法,常用于区分成员变量和局部变量,以及在构造器中调用其他构造器。
在构造器中调用时必须放在第一行,否则编译错误。
this不能用于静态方法中,因为静态方法属于类而不是对象,没有当前对象的实例。

super 关键字

super是一个引用变量,指向当前对象的父类实例,可以用来访问父类的成员变量和成员方法,常用于子类重写父类方法时调用父类的方法,以及在子类构造器中调用父类的构造器。
在子类构造器中调用父类构造器时必须放在第一行,否则编译错误。
如果子类构造器没有显式调用父类构造器,Java会默认调用父类的无参构造器,如果父类没有无参构造器,则编译错误。
super不能用于静态方法中,因为静态方法属于类而不是对象,没有当前对象的实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class TestClass04 {
public int val = 0;
public void print() {
System.out.println("trigger on print method");
System.out.println(val);
}
public TestClass04(int val) {
this.val = val; // this.val 指当前对象的成员变量 val
}
public TestClass04() {
this(123); // this(参数列表) 调用当前类的其他构造器
this.print(); // this.print() 调用当前对象的成员方法 print()
}
}

代码示例

1
2
3
4
5
6
7
8
package pk.pk2;

public class TestClass03 {
public String i1 = "i1";
protected String i2 = "i2";
String i3 = "i3";
private String i4 = "i4";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package pk.pk1;

import pk.pk2.TestClass03;

public class TestClass01 {
public String i1 = "i1";
protected String i2 = "i2";
String i3 = "i3";
private String i4 = "i4";
static String i5 = "i5";

String name;

void print() {
// 同包 + 同类
System.out.println(i1);
System.out.println(i2);
System.out.println(i3);
System.out.println(i4);
System.out.println("name: " + name);
}

public TestClass01() {
this.name = "default constructor";
}

public TestClass01(String name) {
this.name = name;
}
}

class TestSubClass01 extends TestClass03 {
void print() {
// 跨包 + 子类
System.out.println(i1);
System.out.println(i2);
// System.out.println(i3); // default 访问权限不支持跨包
// System.out.println(i4); // private 访问权限不支持跨包
}
}

class TestClass02 {
public static void main(String[] args) {
// 同包 + 跨类
TestClass01 tc1 = new TestClass01(); // 默认构造函数
System.out.println(tc1.i1); // i1
System.out.println(tc1.i2); // i2
System.out.println(tc1.i3); // i3
// System.out.println(tc1.i4); // 编译错误,i4 是 private 访问权限,无法跨类访问
tc1.print(); // i1 \n i2 \n i3 \n i4 \n name: default constructor
System.out.println(TestClass01.i5); // i5

// 同包 + 跨类
TestClass01 tc2 = new TestClass01("custom constructor"); // 带参构造函数
tc2.print(); // i1 \n i2 \n i3 \n i4 \n name: custom constructor

// 跨包 + 跨类
TestSubClass01 tc3 = new TestSubClass01();
System.out.println(tc3.i1); // i1 只有public允许跨包 + 跨类访问
// System.out.println(tc3.i2); // 编译错误
// System.out.println(tc3.i3); // 编译错误
// System.out.println(tc3.i4); // 编译错误
tc3.print(); // i1 \n i2
}
}

类和对象是面向对象编程的核心概念,类定义了对象的属性和行为,而对象则是类的具体实例。通过类和对象,我们可以更好地组织代码,提高代码的复用性和可维护性。
面向过程编程则是以函数为中心,强调程序的流程和步骤,而面向对象编程则是以对象为中心,强调数据和行为的封装。