Java 类和对象全面教程
·
这是一个关于 Java 类和对象的全面详细教程,包含关键概念、语法和常见易错点。
Java 类和对象全面教程
1. 类(Class)
- 定义: 类是对象的蓝图或模板。它定义了对象所具有的属性(成员变量)和行为(方法)。
- 作用: 封装数据(属性)和对数据的操作(方法)。
- 语法:
public class ClassName {
// 成员变量(属性)
[访问修饰符] 数据类型 变量名1;
[访问修饰符] 数据类型 变量名2;
...
// 构造方法
[访问修饰符] ClassName([参数列表]) {
// 初始化代码
}
// 成员方法(行为)
[访问修饰符] 返回类型 方法名1([参数列表]) {
// 方法体
}
[访问修饰符] 返回类型 方法名2([参数列表]) {
// 方法体
}
...
}
- 示例:
public class Person {
// 成员变量
private String name; // 私有属性,通常通过公共方法访问
public int age; // 公共属性(直接访问可能不安全,仅为示例)
// 构造方法 (1) - 无参构造
public Person() {
name = "Unknown";
age = 0;
}
// 构造方法 (2) - 带参数构造
public Person(String name, int age) {
this.name = name; // 使用this区分成员变量和局部变量
this.age = age;
}
// 成员方法 - 获取姓名
public String getName() {
return name;
}
// 成员方法 - 设置姓名
public void setName(String newName) {
name = newName; // 通常有验证逻辑
}
// 成员方法 - 自我介绍
public void introduce() {
System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
}
}
2. 对象(Object)
- 定义: 对象是类的一个实例(Instance)。它是根据类定义创建的具体实体。
- 创建对象: 使用
new关键字调用类的构造方法(Constructor)。 - 语法:
ClassName objectName = new ClassName([参数]); // 创建对象并调用构造方法
- 示例:
public class Main {
public static void main(String[] args) {
// 使用无参构造创建对象 person1
Person person1 = new Person();
person1.setName("Alice");
person1.age = 25; // 直接访问公共属性(不推荐)
person1.introduce(); // 输出:Hello, my name is Alice and I am 25 years old.
// 使用带参构造创建对象 person2
Person person2 = new Person("Bob", 30);
person2.introduce(); // 输出:Hello, my name is Bob and I am 30 years old.
// 访问属性 (不推荐直接访问公共属性,此处仅为演示)
System.out.println(person2.age); // 输出:30
// 通过方法访问私有属性
System.out.println(person2.getName()); // 输出:Bob
}
}
3. 成员变量(属性)
- 定义: 类中声明的变量,描述对象的特征或状态。
- 访问修饰符:
private:仅在本类中可见。(推荐用于封装数据)public:对所有类可见。protected:对同一包内的类和所有子类可见。default(无修饰符):仅对同一包内的类可见。
- 命名规范: 通常使用名词,驼峰命名法(如
firstName,accountBalance)。 - 初始化: 可在声明时初始化,或在构造方法中初始化。未初始化时,基本类型有默认值(如
int为0,boolean为false),引用类型为null。
4. 成员方法
- 定义: 类中定义的操作或行为,用于操作成员变量或执行特定任务。
- 语法:
[访问修饰符] 返回类型 方法名(参数列表) { ... } void: 如果方法不返回任何值,返回类型写void。return: 用于返回方法结果(非void方法)或提前退出方法。- 命名规范: 通常使用动词或动词短语,驼峰命名法(如
getName,calculateTotal)。 this关键字: 用于区分成员变量和局部变量(当同名时),或调用当前对象的其他构造方法(只能在构造方法内第一行使用)。
5. 构造方法(Constructor)
- 定义: 一种特殊的方法,在创建对象时自动调用,用于初始化新对象的状态。
- 特点:
- 方法名与类名完全相同。
- 没有返回类型(连
void都没有)。 - 可以重载(多个构造方法,参数列表不同)。
- 默认构造方法: 如果一个类没有显式定义任何构造方法,编译器会自动提供一个无参的默认构造方法(如
public Person() {})。一旦定义了任何构造方法,编译器就不再提供默认构造方法。
6. static 关键字
- 静态成员变量: 属于类本身,所有对象共享同一份副本。用
static修饰。- 访问方式:
ClassName.staticVariable(推荐) 或object.staticVariable(不推荐)。 - 常用于常量(结合
final)、计数器等。
- 访问方式:
- 静态成员方法: 属于类本身,只能直接访问静态成员变量或调用其他静态方法。用
static修饰。- 访问方式:
ClassName.staticMethod()(推荐) 或object.staticMethod()(不推荐)。 - 常用于工具方法(如
Math.sqrt())。
- 访问方式:
- 静态初始化块: 在类加载时执行一次,用于初始化静态变量。语法:
static { ... }。 - 易混淆点: 静态成员属于类,非静态成员(实例成员)属于对象。在静态方法中不能直接访问非静态成员(需要先创建对象)。
7. 封装(Encapsulation)
- 概念: 将数据(属性)和对数据的操作(方法)绑定在一起,并限制对对象内部数据的直接访问。
- 实现: 通常将属性设为
private,并提供public的getter(如getName()) 和setter(如setName()) 方法来访问和修改属性。可以在setter中添加数据验证逻辑。 - 优点: 提高安全性、可维护性、灵活性。
8. 易错点与注意事项
- 忘记
new关键字: 创建对象必须使用new。否则只是声明了一个引用变量(初始值为null),访问其成员会导致NullPointerException。
Person p; // 仅声明,p 是 null
p.introduce(); // 运行时错误: NullPointerException!
- 混淆成员变量和局部变量(不使用
this): 当方法参数或局部变量与成员变量同名时,不使用this会导致成员变量无法正确初始化或访问。
public void setName(String name) {
name = name; // 错误!参数name赋值给参数name自己,成员变量name没变
this.name = name; // 正确!使用this明确指向成员变量
}
- 忽略默认构造方法: 如果定义了带参构造方法但还想使用无参构造,必须显式定义一个无参构造方法,否则
new ClassName()会编译错误。
public class MyClass {
public MyClass(int value) { ... }
// 缺少 public MyClass() { ... }
}
MyClass obj = new MyClass(); // 编译错误:找不到无参构造方法
- 在静态方法中访问非静态成员: 静态方法属于类,在类加载时就存在,此时可能还没有对象实例。因此不能在静态方法中直接使用
this或访问非静态成员变量/方法。
public class Test {
private int count = 0; // 非静态成员变量
public static void printCount() {
System.out.println(count); // 编译错误:无法从静态上下文访问非静态变量count
// 正确做法:通过对象访问
// Test t = new Test();
// System.out.println(t.count);
}
}
- 对对象引用的误解: Java 中对象变量存储的是引用(内存地址),而不是对象本身。多个变量可以引用同一个对象。
Person p1 = new Person("Alice", 25);
Person p2 = p1; // p2 和 p1 指向同一个对象
p2.setName("Bob");
System.out.println(p1.getName()); // 输出 "Bob",因为修改的是同一个对象
==vs.equals():==比较的是两个对象的引用是否相同(内存地址)。.equals()方法(需要正确重写)用于比较两个对象的内容是否相等。对于自定义类,默认的.equals()行为与==相同。
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2); // false,引用不同
System.out.println(s1.equals(s2)); // true,内容相同(String类重写了equals)
- 过度使用
public属性: 直接暴露public属性破坏了封装性。推荐使用private属性 +publicgetter/setter。 - 内存泄漏(间接): 虽然 Java 有垃圾回收(GC),但长时间持有无用对象引用(如全局集合中)会阻止 GC 回收,可能导致内存耗尽。
- 未正确处理对象状态: 确保对象在使用前已被正确初始化(通过构造方法或 setter),避免对象处于无效状态。
- 不理解
static的含义: 错误地认为每个对象都有自己的静态变量副本,或在静态上下文中错误使用this。
总结
类和对象是 Java 面向对象编程的基石。理解类作为蓝图、对象作为实例的概念至关重要。掌握成员变量、方法、构造方法、static 关键字、封装以及常见的易错点,是编写健壮、可维护 Java 代码的基础。通过大量练习和注意细节,可以避免这些常见陷阱。
更多推荐
所有评论(0)