【JAVA基础】—— 类与对象
【Java基础】类与对象核心详解:从基础语法到进阶用法
Java 作为经典的面向对象编程语言(OOP),其核心思想是通过“类”和“对象”抽象现实世界的事物,实现代码的模块化、可复用性和可维护性。本文从类与对象的基础概念出发,逐步讲解构造方法、对象创建、源文件规范、包与导入语句,并延伸至进阶用法,覆盖从入门到实际开发的核心知识点。
1. Java类与对象:面向对象的核心
1.1 核心概念解析
面向对象编程的核心是将程序拆解为“对象”的集合,对象之间通过方法调用协作完成功能。关键概念如下:
- 对象:现实事物的程序抽象,包含“状态”(属性/变量)和“行为”(方法)。例如:一只小狗是对象,状态(名字、颜色、年龄),行为(跑、叫、吃)。
- 类:对象的“模板/蓝图”,定义了某一类对象共有的属性和行为。例如:
Dog类定义了所有小狗都有的breed(品种)属性和eat()(吃)方法。 - 方法:对象的行为实现,包含具体的业务逻辑,是类的核心功能载体。
- 实例变量:对象的专属状态,每个对象的实例变量值唯一,决定了对象的具体特征。
1.2 类的组成:变量分类
一个类包含变量和方法,其中变量按作用域和生命周期分为三类(补充示例区分,更易理解):
// 类的变量分类示例
public class Dog {
// 1. 类变量(静态变量):属于类,所有对象共享,用static修饰
static String species = "犬科";
// 2. 成员变量(实例变量):属于对象,每个对象独有,定义在类中、方法外
String breed;
int size;
// 方法
void eat() {
// 3. 局部变量:属于方法,仅在方法内有效,方法结束后销毁
int foodAmount = 100;
System.out.println("小狗吃了" + foodAmount + "g食物");
}
}
- 局部变量:方法/构造方法/语句块内定义,无默认值(必须手动初始化),作用域仅限定义区域。
- 成员变量:类内方法外定义,有默认值(如int默认0、String默认null),对象创建时初始化,随对象销毁而销毁。
- 类变量:
static修饰的成员变量,属于类而非对象,所有对象共享,类加载时初始化,随类销毁而销毁。
1.3 类的方法基础
方法是类的“行为”实现,基本结构:修饰符 返回值类型 方法名(参数列表) { 方法体 }。例如:
public class Dog {
// 无返回值、无参数方法
void run() {
System.out.println("小狗在跑");
}
// 有返回值、有参数方法
String getName(String prefix) {
return prefix + "-" + this.breed; // this指代当前对象的成员变量
}
}
2. 构造方法:对象的“初始化器”
构造方法是类的特殊方法,核心作用是创建对象时初始化属性,需遵循以下规则:
- 构造方法名必须与类名完全一致,无返回值类型(连void都不能写);
- 若未显式定义构造方法,Java编译器会自动生成无参默认构造方法;
- 一个类可以定义多个构造方法(构造方法重载),适配不同的初始化场景。
2.1 基础示例
public class Puppy {
// 成员变量
private String name;
private int age;
// 1. 无参构造方法(默认构造方法,若手动定义其他构造方法,需显式声明)
public Puppy() {
this.name = "未知";
this.age = 0;
}
// 2. 单参数构造方法(重载)
public Puppy(String name) {
this.name = name; // this区分成员变量和局部变量
}
// 3. 多参数构造方法(重载)
public Puppy(String name, int age) {
this.name = name;
this.age = age;
}
// getter方法(访问私有成员变量)
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
2.2 核心特性
- 构造方法只能在创建对象时由
new关键字调用,不能手动调用; - 构造方法可通过
this(参数)调用同类的其他构造方法(必须是方法体第一行); - 子类构造方法默认调用父类的无参构造方法(可通过
super(参数)显式调用)。
3. 创建对象:从“模板”到“实例”
对象是类的具体实例,Java中通过new关键字创建对象,分为三步(逻辑上的拆分,代码中可合并):
- 声明:定义对象变量,指定“类类型 + 变量名”;
- 实例化:
new关键字为对象分配内存空间; - 初始化:调用构造方法,初始化对象属性。
3.1 完整示例
public class PuppyTest {
public static void main(String[] args) {
// 1. 声明 + 实例化 + 初始化(无参构造)
Puppy puppy1 = new Puppy();
System.out.println("小狗1:" + puppy1.getName() + ",年龄:" + puppy1.getAge());
// 2. 单参数构造创建对象
Puppy puppy2 = new Puppy("旺财");
System.out.println("小狗2:" + puppy2.getName() + ",年龄:" + puppy2.getAge());
// 3. 多参数构造创建对象
Puppy puppy3 = new Puppy("小白", 2);
System.out.println("小狗3:" + puppy3.getName() + ",年龄:" + puppy3.getAge());
}
}
输出结果:
小狗1:未知,年龄:0
小狗2:旺财,年龄:0
小狗3:小白,年龄:2
4. 访问实例变量和方法:封装与访问控制
对象创建后,可通过对象名.属性/方法访问,但实际开发中推荐封装(private修饰成员变量),通过getter/setter方法访问,保证数据安全性。
4.1 封装示例(优化原有示例)
public class Puppy {
// 私有成员变量(封装):外部无法直接访问
private int age;
private String name;
// 构造器:初始化name
public Puppy(String name) {
this.name = name;
System.out.println("小狗的名字是 : " + name);
}
// setter方法:设置age(可添加校验逻辑)
public void setAge(int age) {
if (age < 0 || age > 20) { // 校验年龄合理性
System.out.println("年龄不合法!");
return;
}
this.age = age;
}
// getter方法:获取age
public int getAge() {
return this.age;
}
// getter方法:获取name
public String getName() {
return this.name;
}
// 主方法测试
public static void main(String[] args) {
// 创建对象
Puppy myPuppy = new Puppy("Tommy");
// 通过setter设置age(带校验)
myPuppy.setAge(-1); // 非法年龄
myPuppy.setAge(2); // 合法年龄
// 通过getter获取age
int age = myPuppy.getAge();
System.out.println("小狗的年龄为 : " + age);
// 获取name
System.out.println("小狗的名字为 : " + myPuppy.getName());
}
}
输出结果:
小狗的名字是 : Tommy
年龄不合法!
小狗的年龄为 : 2
小狗的名字为 : Tommy
4.2 访问规则
public修饰的属性/方法:所有类均可访问;private修饰的属性/方法:仅当前类可访问(核心封装手段);protected修饰的属性/方法:同包类 + 子类可访问;- 默认修饰(无关键字):仅同包类可访问。
5. 源文件声明规则:规范编写Java源文件
Java源文件(.java)的声明需遵循严格规则,否则编译报错,核心规则如下:
5.1 核心规则
- 文件名与public类一致:一个源文件中最多有1个
public类,且文件名必须与该public类名完全一致(大小写敏感);- 示例:
public class HelloWorld必须放在HelloWorld.java文件中; - 若源文件无
public类,文件名可任意(但建议与主类名一致)。
- 示例:
- 包声明优先:若源文件包含
package语句,必须放在文件第一行(注释除外); - 导入语句次之:
import语句需放在package之后、类定义之前; - 多类声明:一个源文件可定义多个非
public类,编译后每个类生成独立的.class文件; - 主类规则:包含
main()方法的类是程序入口,建议声明为public。
5.2 规范示例
// 1. 包声明(可选,必须在第一行)
package com.example.demo;
// 2. 导入语句(可选,在package之后)
import java.util.Scanner;
// 3. public类(最多1个,文件名必须为Puppy.java)
public class Puppy {
public static void main(String[] args) {
System.out.println("程序入口");
}
}
// 4. 非public类(可多个)
class Dog {
String name;
}
6. Java包:代码的“文件夹”管理
包(Package)是Java用于组织和管理类的机制,核心作用是避免类名冲突、控制访问权限、模块化管理代码。
6.1 包的核心作用
- 避免类名冲突:不同包下可定义同名类(如
com.example.Dog和com.test.Dog); - 模块化管理:按功能/业务拆分包(如
controller、service、dao); - 访问控制:
protected/默认修饰的成员仅同包类可访问。
6.2 包的命名规范
- 采用反向域名命名(避免冲突):
com.公司名.项目名.模块名; - 全小写字母,多个单词用
.分隔; - 示例:
com.alibaba.pay、org.springframework.core。
6.3 创建与使用自定义包
6.3.1 定义包(package语句)
// 定义包:com.example.animal
package com.example.animal;
// 该类的完整类名:com.example.animal.Dog
public class Dog {
public void bark() {
System.out.println("小狗叫");
}
}
6.3.2 包的目录结构
包名对应文件系统的目录结构,例如com.example.animal对应的目录:
src/
└── com/
└── example/
└── animal/
└── Dog.java
6.4 常用系统包
Java内置了大量核心包,开发中高频使用:
java.lang:核心类(无需导入,自动生效),如String、Integer、System;java.util:工具类,如ArrayList、HashMap、Scanner;java.io:输入输出类,如File、InputStream;java.net:网络编程类,如URL、Socket;java.sql:数据库操作类,如Connection、Statement。
7. import语句:引入其他包的类
import语句用于在当前类中引入其他包的类,避免编写完整类名(全限定名),简化代码。
7.1 import基础语法
// 1. 导入单个类
import com.example.animal.Dog;
// 2. 导入整个包下的所有类(通配符*)
import com.example.animal.*;
// 3. 导入静态成员(方法/变量)
import static java.lang.System.out;
import static java.lang.Math.PI;
7.2 使用示例
7.2.1 基础导入
package com.example.test;
// 导入com.example.animal包下的Dog类
import com.example.animal.Dog;
public class Test {
public static void main(String[] args) {
Dog dog = new Dog(); // 无需写完整类名
dog.bark();
}
}
7.2.2 静态导入
// 静态导入System.out和Math.PI
import static java.lang.System.out;
import static java.lang.Math.PI;
public class StaticImportTest {
public static void main(String[] args) {
out.println("圆周率:" + PI); // 无需写System.out和Math.PI
}
}
7.3 注意事项
- 无需导入java.lang包:该包是核心包,Java自动导入;
- 避免导入冲突:若两个包有同名类(如
java.util.Date和java.sql.Date),需显式指定完整类名;// 解决Date类冲突 java.util.Date utilDate = new java.util.Date(); java.sql.Date sqlDate = new java.sql.Date(System.currentTimeMillis()); - 通配符*仅导入当前包:不会递归导入子包(如
import com.example.*不会导入com.example.animal.Dog)。
8. 进阶用法与实战配置
8.1 this关键字:指代当前对象
- 区分成员变量和局部变量(如
this.name = name); - 调用当前类的其他构造方法(
this(参数),必须是构造方法第一行); - 调用当前类的方法(
this.method(),可省略,但建议显式写,增强可读性)。
8.2 static关键字深入
- 静态变量:类的所有对象共享,内存中仅一份(如计数统计
static int count); - 静态方法:属于类而非对象,可直接通过
类名.方法名调用(不能访问非静态成员); - 静态代码块:类加载时执行,仅执行一次,用于初始化静态变量:
public class StaticTest { static int count; // 静态代码块 static { count = 10; System.out.println("静态代码块执行,count=" + count); } public static void main(String[] args) { System.out.println(StaticTest.count); // 输出10 } }
8.3 对象的生命周期
- 创建阶段:
new关键字分配内存 + 构造方法初始化; - 使用阶段:对象被引用,调用方法/访问属性;
- 销毁阶段:无引用指向对象,JVM垃圾回收(GC)释放内存(无法手动触发,仅能通过
obj = null解除引用)。
8.4 包的进阶配置(Maven/Gradle)
实际开发中,包结构需配合构建工具(如Maven)规范管理,核心目录结构:
src/
├── main/
│ ├── java/ // 主代码包
│ │ └── com/
│ │ └── example/
│ │ ├── controller/ // 控制器
│ │ ├── service/ // 业务逻辑
│ │ ├── dao/ // 数据访问
│ │ └── model/ // 实体类
│ └── resources/ // 配置文件
└── test/ // 测试代码包
└── java/
└── com/
└── example/
└── service/ // 测试业务逻辑
8.5 访问控制最佳实践
- 成员变量:一律
private,通过getter/setter访问; - 方法:根据需求选择
public(对外提供)、protected(子类访问)、private(内部使用); - 工具类:所有方法声明为
static,构造方法私有化(避免创建对象):public class StringUtils { // 私有化构造方法,禁止创建对象 private StringUtils() {} // 静态工具方法 public static boolean isEmpty(String str) { return str == null || str.length() == 0; } }
总结
- 核心基础:类是模板,对象是实例,构造方法负责初始化,封装是保证数据安全的核心手段;
- 规范要求:源文件需遵循“包→导入→类”的声明顺序,public类名与文件名一致;
- 包与导入:包用于管理类避免冲突,import简化类引用,静态导入可直接使用类的静态成员;
- 进阶技巧:
this/static关键字是高频考点,包结构需配合构建工具规范化,访问控制需遵循“成员私有、方法按需公开”的原则。
掌握类与对象的核心用法,是Java进阶的基础,后续可结合继承、多态、抽象类/接口等知识点,进一步理解面向对象的完整特性。
更多推荐


所有评论(0)