Java是一种纯粹的面向对象编程语言。面向对象编程(OOP)是现代软件开发的核心范式,它支持以下基本概念:
同一操作作用于不同对象,可以产生不同的执行结果
子类继承父类的属性和方法,实现代码复用
隐藏对象的内部实现细节,只暴露必要的接口
提取对象的共同特征,忽略实现细节
本节重点研究对象和类的概念,这是面向对象编程的基础。
在现实世界中,每个具体的实体都是对象;在软件世界中,类是创建对象的模板,对象是类的具体实现。
类是Java程序的基本构建块,用于创建对象的模板。类定义了对象的属性和方法。
一个典型的Java类包含以下部分:
使用class关键字声明类,指定访问修饰符和类名
// 类声明的基本语法
[访问修饰符] class 类名 {
// 类体
}
定义在类内部、方法外部的变量,表示对象的状态
// 成员变量示例
private String name;
private int age;
protected double salary;
定义在类中的函数,表示对象的行为
// 方法示例
public void displayInfo() {
System.out.println("Name: " + name);
}
public int calculateAge() {
return age;
}
下面是一个完整的Dog类的定义:
/**
* Dog类 - 表示狗的类
* 这是一个简单的类定义示例
*/
public class Dog {
// 成员变量(属性) - 表示狗的状态
private String breed; // 品种
private int age; // 年龄
private String color; // 颜色
private String name; // 名字
private boolean isHungry; // 是否饥饿
// 构造方法 - 用于创建对象时初始化
public Dog(String name, String breed, int age, String color) {
this.name = name;
this.breed = breed;
this.age = age;
this.color = color;
this.isHungry = true; // 默认新创建的狗是饥饿的
}
// 方法 - 表示狗的行为
/**
* 狗叫的方法
*/
public void barking() {
System.out.println(name + "正在汪汪叫!");
}
/**
* 表示狗饿了
*/
public void hungry() {
if (isHungry) {
System.out.println(name + "饿了,需要喂食!");
} else {
System.out.println(name + "不饿。");
}
}
/**
* 狗睡觉的方法
*/
public void sleeping() {
System.out.println(name + "正在睡觉...");
isHungry = true; // 睡醒后可能会饿
}
/**
* 喂狗的方法
*/
public void feed() {
isHungry = false;
System.out.println("已经喂了" + name);
}
/**
* 获取狗的详细信息
* @return 狗的详细信息字符串
*/
public String getDogInfo() {
return "名字: " + name +
", 品种: " + breed +
", 年龄: " + age + "岁" +
", 颜色: " + color;
}
/**
* 年龄增长方法
*/
public void growOlder() {
age++;
System.out.println(name + "又长大了一岁,现在" + age + "岁了");
}
}
在类中,可以定义三种类型的变量:
| 变量类型 | 描述 | 生命周期 | 示例 |
|---|---|---|---|
| 局部变量 | 在方法、构造方法或代码块中定义的变量 | 从声明处开始,到所在代码块结束 | int result = 0; |
| 成员变量 (实例变量) |
在类中定义、方法外部的变量,属于对象实例 | 对象创建时创建,对象销毁时销毁 | private String name; |
| 类变量 (静态变量) |
使用static关键字声明的变量,属于类本身 |
类加载时创建,程序结束时销毁 | public static int count = 0; |
对象是类的实例,具有具体的状态和行为。对象在内存中占用空间,可以存储数据并执行操作。
在Java中创建对象需要以下三个步骤:
声明一个引用变量,指定对象类型和名称
// 声明对象
Dog myDog;
使用new关键字创建对象实例
// 实例化对象
myDog = new Dog();
调用构造方法初始化对象状态
// 通常声明、实例化、初始化合并
Dog myDog = new Dog("Buddy", "Golden Retriever", 3, "金色");
使用之前定义的Dog类创建对象:
public class DogTest {
public static void main(String[] args) {
// 创建第一个Dog对象
Dog dog1 = new Dog("Buddy", "Golden Retriever", 3, "金色");
// 创建第二个Dog对象
Dog dog2 = new Dog("Max", "German Shepherd", 5, "黑色");
// 调用对象的方法
System.out.println(dog1.getDogInfo());
dog1.barking();
dog1.hungry();
dog1.feed();
dog1.hungry();
System.out.println("\n-------------------\n");
System.out.println(dog2.getDogInfo());
dog2.sleeping();
dog2.growOlder();
// 每个对象都有自己的状态
System.out.println("\n两只狗是不同的对象:");
System.out.println("dog1的名字: " + dog1.getDogInfo().split(",")[0]);
System.out.println("dog2的名字: " + dog2.getDogInfo().split(",")[0]);
}
}
构造方法是一种特殊的方法,用于创建和初始化对象。构造方法名称必须与类名相同,且没有返回类型。
void都没有static、final、abstract修饰没有参数的构造方法,如果没有定义任何构造方法,Java会自动生成
public class Student {
// 如果没有定义构造方法,Java提供:
// public Student() { }
}
带参数的构造方法,用于初始化对象时传入初始值
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
一个类可以有多个构造方法,这称为构造方法重载:
public class Puppy {
private String name;
private int age;
private String breed;
// 默认构造方法
public Puppy() {
this.name = "Unknown";
this.age = 0;
this.breed = "Mixed";
System.out.println("创建了一个匿名小狗");
}
// 只有一个参数的构造方法
public Puppy(String name) {
this.name = name;
this.age = 0;
this.breed = "Mixed";
System.out.println("创建了小狗: " + name);
}
// 有两个参数的构造方法
public Puppy(String name, int age) {
this.name = name;
this.age = age;
this.breed = "Mixed";
System.out.println("创建了小狗: " + name + ", 年龄: " + age);
}
// 有三个参数的构造方法
public Puppy(String name, int age, String breed) {
this.name = name;
this.age = age;
this.breed = breed;
System.out.println("创建了小狗: " + name + ", 品种: " + breed + ", 年龄: " + age);
}
// 获取小狗信息
public String getInfo() {
return "名字: " + name + ", 品种: " + breed + ", 年龄: " + age + "岁";
}
public static void main(String[] args) {
// 使用不同的构造方法创建对象
Puppy puppy1 = new Puppy(); // 调用无参构造方法
Puppy puppy2 = new Puppy("Tommy"); // 调用单参构造方法
Puppy puppy3 = new Puppy("Max", 2); // 调用双参构造方法
Puppy puppy4 = new Puppy("Buddy", 3, "Golden Retriever"); // 调用三参构造方法
System.out.println("\n小狗信息:");
System.out.println(puppy1.getInfo());
System.out.println(puppy2.getInfo());
System.out.println(puppy3.getInfo());
System.out.println(puppy4.getInfo());
}
}
创建对象后,可以通过对象引用访问其成员变量和方法。
// 语法:对象引用.变量名
objectReference.variableName;
// 示例
Dog myDog = new Dog("Buddy", "Golden Retriever", 3, "金色");
String dogName = myDog.name; // 直接访问(如果变量是public)
int dogAge = myDog.getAge(); // 通过getter方法访问(推荐)
// 语法:对象引用.方法名(参数)
objectReference.methodName(parameters);
// 示例
Dog myDog = new Dog("Buddy", "Golden Retriever", 3, "金色");
myDog.barking(); // 调用无参方法
myDog.setAge(4); // 调用带参方法
String info = myDog.getDogInfo(); // 调用返回信息的方法
public class Puppy {
// 成员变量
private String name;
private int puppyAge;
/**
* 构造方法
* @param name 小狗的名字
*/
public Puppy(String name) {
this.name = name;
System.out.println("创建了小狗: " + name);
}
/**
* 设置年龄
* @param age 年龄
*/
public void setAge(int age) {
if (age >= 0 && age <= 20) {
puppyAge = age;
System.out.println(name + "的年龄设置为: " + age);
} else {
System.out.println("无效的年龄: " + age);
}
}
/**
* 获取年龄
* @return 年龄
*/
public int getAge() {
System.out.println(name + "的年龄是: " + puppyAge);
return puppyAge;
}
/**
* 获取小狗信息
* @return 信息字符串
*/
public String getPuppyInfo() {
return "名字: " + name + ", 年龄: " + puppyAge + "岁";
}
public static void main(String[] args) {
// 创建对象
Puppy myPuppy = new Puppy("Tommy");
// 通过setter方法设置年龄
myPuppy.setAge(2);
// 通过getter方法获取年龄
int age = myPuppy.getAge();
// 获取完整信息
String info = myPuppy.getPuppyInfo();
System.out.println("小狗信息: " + info);
// 再次修改年龄
myPuppy.setAge(3);
// 显示更新后的信息
System.out.println("更新后: " + myPuppy.getPuppyInfo());
}
}
Java源文件需要遵循特定的规则和约定,以确保编译器能够正确编译和组织代码。
package语句必须是源文件的第一行(除了注释)import语句必须位于package语句之后,类声明之前// 1. 包声明(可选)
package com.example.animals;
// 2. 导入语句(可选)
import java.util.Date;
import java.util.List;
// 3. 类注释(可选)
/**
* Dog类
* 这是一个示例类,展示源文件结构
* @author YourName
* @version 1.0
*/
// 4. 公共类(只能有一个)
public class Dog {
// 类体...
// 主方法(可选)
public static void main(String[] args) {
System.out.println("Hello Dog!");
}
}
// 5. 非公共类(可以有多个)
class AnimalHelper {
// 辅助类代码...
}
// 另一个非公共类
class DogFood {
// 狗粮类代码...
}
// 错误:一个文件中有两个public类
public class Student {
// ...
}
public class Teacher { // 编译错误!
// ...
}
// 错误:文件名与public类名不匹配
// 文件名:Person.java
public class Employee { // 编译错误!
// 文件名应该是Employee.java
}
包(Package)是Java中用于组织类的一种机制,类似于文件系统的目录结构。
com.example.project)import java.util.ArrayList;
import java.util.Date;
import java.util.*; // 导入util包中的所有类
// 导入静态成员
import static java.lang.Math.PI;
import static java.lang.Math.sqrt;
// 不使用import,直接使用完全限定名
java.util.ArrayList list = new java.util.ArrayList();
下面是一个完整的企业级示例,展示如何使用类和对象创建简单的员工管理系统。
// 包声明
package com.company.model;
/**
* Employee类
* 表示公司员工
*/
public class Employee {
// 成员变量(属性)
private String name;
private int age;
private String designation;
private double salary;
private String department;
private int employeeId;
// 类变量(静态变量)- 用于生成员工ID
private static int nextId = 1000;
/**
* 构造方法1:提供基本信息
* @param name 员工姓名
* @param age 员工年龄
* @param designation 职位
*/
public Employee(String name, int age, String designation) {
this.name = name;
this.age = age;
this.designation = designation;
this.salary = 0.0; // 默认工资
this.department = "未分配"; // 默认部门
this.employeeId = nextId++; // 自动生成ID
}
/**
* 构造方法2:提供完整信息
* @param name 姓名
* @param age 年龄
* @param designation 职位
* @param salary 工资
* @param department 部门
*/
public Employee(String name, int age, String designation,
double salary, String department) {
this(name, age, designation); // 调用另一个构造方法
this.salary = salary;
this.department = department;
}
// Getter和Setter方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age >= 18 && age <= 65) {
this.age = age;
} else {
System.out.println("年龄必须在18-65之间");
}
}
public String getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
if (salary >= 0) {
this.salary = salary;
} else {
System.out.println("工资不能为负数");
}
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public int getEmployeeId() {
return employeeId;
}
// 业务方法
/**
* 给员工加薪
* @param percentage 加薪百分比
*/
public void giveRaise(double percentage) {
if (percentage > 0) {
double increase = salary * percentage / 100;
salary += increase;
System.out.println(name + "获得加薪: $" + increase +
",新工资: $" + salary);
}
}
/**
* 员工庆祝生日,年龄+1
*/
public void celebrateBirthday() {
age++;
System.out.println("祝" + name + "生日快乐!现在" + age + "岁了");
}
/**
* 获取员工信息
* @return 员工信息字符串
*/
public String getEmployeeInfo() {
return String.format(
"ID: %d, 姓名: %s, 年龄: %d, 职位: %s, 部门: %s, 工资: $%.2f",
employeeId, name, age, designation, department, salary
);
}
/**
* 打印员工信息
*/
public void printEmployee() {
System.out.println("员工信息:");
System.out.println(" ID: " + employeeId);
System.out.println(" 姓名: " + name);
System.out.println(" 年龄: " + age);
System.out.println(" 职位: " + designation);
System.out.println(" 部门: " + department);
System.out.println(" 工资: $" + salary);
}
// 类方法(静态方法)
/**
* 获取下一个可用的员工ID
* @return 下一个员工ID
*/
public static int getNextAvailableId() {
return nextId;
}
}
// 包声明
package com.company.test;
// 导入需要的类
import com.company.model.Employee;
/**
* EmployeeTest类
* 测试Employee类的功能
*/
public class EmployeeTest {
public static void main(String[] args) {
System.out.println("=== 员工管理系统测试 ===\n");
// 创建员工对象
Employee emp1 = new Employee("张三", 28, "高级软件工程师", 85000, "技术部");
Employee emp2 = new Employee("李四", 25, "软件工程师", 65000, "技术部");
Employee emp3 = new Employee("王五", 30, "产品经理", 90000, "产品部");
Employee emp4 = new Employee("赵六", 22, "实习生", 30000, "技术部");
// 显示员工信息
System.out.println("1. 初始员工信息:");
emp1.printEmployee();
emp2.printEmployee();
emp3.printEmployee();
emp4.printEmployee();
// 修改员工信息
System.out.println("\n2. 修改员工信息:");
emp1.setSalary(90000); // 给张三加薪
emp2.setDepartment("研发部"); // 调整李四的部门
emp3.giveRaise(10); // 给王五加薪10%
emp4.celebrateBirthday(); // 赵六过生日
// 显示更新后的信息
System.out.println("\n3. 更新后的员工信息:");
System.out.println(emp1.getEmployeeInfo());
System.out.println(emp2.getEmployeeInfo());
System.out.println(emp3.getEmployeeInfo());
System.out.println(emp4.getEmployeeInfo());
// 创建更多员工
System.out.println("\n4. 创建更多员工:");
Employee emp5 = new Employee("孙七", 35, "技术总监");
emp5.setSalary(120000);
emp5.setDepartment("技术部");
Employee emp6 = new Employee("周八", 27, "UI设计师");
emp6.setSalary(55000);
emp6.setDepartment("设计部");
System.out.println(emp5.getEmployeeInfo());
System.out.println(emp6.getEmployeeInfo());
// 显示下一个可用的员工ID
System.out.println("\n5. 系统信息:");
System.out.println("下一个可用的员工ID: " + Employee.getNextAvailableId());
System.out.println("已创建员工总数: " + (Employee.getNextAvailableId() - 1000));
System.out.println("\n=== 测试完成 ===");
}
}
=== 员工管理系统测试 ===
1. 初始员工信息:
员工信息:
ID: 1000
姓名: 张三
年龄: 28
职位: 高级软件工程师
部门: 技术部
工资: $85000.00
员工信息:
ID: 1001
姓名: 李四
年龄: 25
职位: 软件工程师
部门: 技术部
工资: $65000.00
员工信息:
ID: 1002
姓名: 王五
年龄: 30
职位: 产品经理
部门: 产品部
工资: $90000.00
员工信息:
ID: 1003
姓名: 赵六
年龄: 22
职位: 实习生
部门: 技术部
工资: $30000.00
2. 修改员工信息:
王五获得加薪: $9000.0,新工资: $99000.0
祝赵六生日快乐!现在23岁了
3. 更新后的员工信息:
ID: 1000, 姓名: 张三, 年龄: 28, 职位: 高级软件工程师, 部门: 技术部, 工资: $90000.00
ID: 1001, 姓名: 李四, 年龄: 25, 职位: 软件工程师, 部门: 研发部, 工资: $65000.00
ID: 1002, 姓名: 王五, 年龄: 30, 职位: 产品经理, 部门: 产品部, 工资: $99000.00
ID: 1003, 姓名: 赵六, 年龄: 23, 职位: 实习生, 部门: 技术部, 工资: $30000.00
4. 创建更多员工:
ID: 1004, 姓名: 孙七, 年龄: 35, 职位: 技术总监, 部门: 技术部, 工资: $120000.00
ID: 1005, 姓名: 周八, 年龄: 27, 职位: UI设计师, 部门: 设计部, 工资: $55000.00
5. 系统信息:
下一个可用的员工ID: 1006
已创建员工总数: 6
=== 测试完成 ===
Car、StudentcalculateTotal()studentNameMAX_SIZEcom.example.projectnew关键字创建对象