Java类和对象知识点
类(Class)
类的概念
-
类的定义是什么:
类是面向对象的编程的基本概念,类本身不是具体的事物,而是一类事物的抽象描述。 -
类是对象的模板
-
`//类的定义(抽象)
-
class student{
-
public String name;
-
public int age;
-
}
-
//对象的创建(具体)
-
Student student1 = new Student();//实例化第一个学生对象
-
Student studnet2 = new Student();//实例化第二个学生对象`
-
类的抽象性
类只是概念,不占用具体的内存空间;类是抽象的,对象是具体的,对象是类的实例化,是真实存在的。
由类生成对象的过程叫做实例化。
类的定义
- class关键字
class是Java定义类的关键字,必须用小写的class,表示接下来要定义一个类 - 类名命名规则
- 只能包含字母、数字、下划线(_)和美元符号($),不能以数字开头,不能使用Java关键字,区分大小写
- 类的结构
- `class Student{}//学生类
- class BankAccount{}//银行账户类`
类的组成
- 成员变量(属性/字段)
定义在类中的,方法外的变量叫做成员变量,例如
class Cat{public String name;//成员变量public int age; //成员变量public void run(){System.out.println(name+"跑的快");}}
public static void main(String[] args){Cat cat = new cat();//实例化一个cat的对象cat.name = "大黄";cat.age = 1;System.out.println(cat.name);System.out.println(cat.age);int a;System.out.println(a);//这个地方会报错,局部变量使用的时候需要初始化。
}
cat.name和cat.age属于成员变量,会有一个默认值,遵循的原则:
- 引用类型,默认为null
- 基本数据类型,默认为对应的0值
通过对象的引用,可以访问对象的成员变量,也可以访问对象的成员方法。
- 成员方法
- 构造方法
根据这个图片可以更好的理解,右边的对象也是堆区,对象的引用可以参考上图直观 的理解。通过new关键词可以实例化多个对象,也就是在栈区开辟多个空间
对象(Object)
对象的概念
- 什么是对象
类的实例,根据类模板创建出来的具体实体,真实存在且占用内存空间,包含具体的属性和执行方法。
对象与类的关系:
// 类的定义(抽象的模板)
class Student {String name;int age;public void study() {System.out.println("学生在学习");}
}// 对象的创建(具体的实例)
Student zhang = new Student(); // zhang是一个具体的学生对象
Student li = new Student(); // li是另一个具体的学生对象
对象的具体性:
Student stu1 = new Student();
stu1.name = "张三";
stu1.age = 20;Student stu2 = new Student();
stu2.name = "李四";
stu2.age = 19;// stu1和stu2是两个不同的对象,有各自的属性值
对象的唯一性:
每个对象在内存都有唯一的地址,可以理解为指针,但是Java里面没有指针的概念。
Student stu1 = new Student();//
Student stu2 = new Student();//
//stu1和stu2是2个不同的对象,虽然属性值相同,但是地址都是唯一且不同的。
对象的唯一性:
对象之间相互独立,修改一个对象的值不影响其它对象。
对象的使用
对象的方法也可以叫行为,就是对象能够执行的操作。
public class Car {// 属性(每个车对象都有自己的值)String brand; // 品牌String color; // 颜色double price; // 价格// 方法(所有车对象共享相同的行为)public void start() {System.out.println(brand + "汽车启动了");}public void stop() {System.out.println(brand + "汽车停止了");}
}// 创建对象并使用,下面的过程就叫做对象的创建和使用
Car myCar = new Car();
myCar.brand = "丰田";
myCar.color = "红色";
myCar.price = 200000;
myCar.start(); // 调用对象的方法
对象在内存种存储:
Student stu = new Student();
内存的管理
栈内存:存储对象引用变量stu
堆内存:存储对象的实际数据(属性值)
方法区:存储类的信息和方法代码
对象的生命周期
通过new关键字进行创建、引用变量访问对象的属性和方法,没有引用指向对象的时候,JVM的垃圾回收器会自动回收。
Student stu = new Student();//创建对象
stu.name = "李四"; //使用对象
stu.study() //调用方法
stu.null; //接触引用,自动回收
成员变量
成员变量是定义在类中、方法外的变量,描述对象或类的属性特征。
实例变量
-
定义方式
-
`public class Student {
// 实例变量的定义
String name; // 姓名
int age; // 年龄
double score; // 成绩
boolean isActive; // 是否活跃public void showInfo() {
// 在方法中可以直接使用实例变量
System.out.println(“姓名:” + name + “,年龄:” + age);
}
}` -
默认初始化
-
实际变量如果没有显示初始化,系统会自动赋予初始值。
-
// 常见类型的默认值 byte byteVar; // 默认值:0 short shortVar; // 默认值:0 int intVar; // 默认值:0 long longVar; // 默认值:0L float floatVar; // 默认值:0.0f double doubleVar; // 默认值:0.0 char charVar; // 默认值:'\u0000'(空字符) boolean boolVar; // 默认值:false String stringVar; // 默认值:null int[] arrayVar; // 默认值:null
-
生命周期
实际变量的生命周期和对象的生命周期相同
public class LifeCycleDemo {private String name = "小王"; //实际变量pubilc static void main(String[] args){//创建对象时,实际变量会被系统分配内存且初始化LifeCycleDemo obj = new LifeCycleDemo();System.out.println(obj.name); //访问实例变量// 对象在使用过程中,实例变量一直存在obj.name = "小张";//对象引用设为null,实际变量随对象一起等待系统垃圾回收obj.name = null; //这个地方的实例变量也不能再访问}
}
类变量(static)
用static修饰的变量属于类本身,不属于某个具体的对象,有静态变量(类变量)、静态方法。
- static关键字
public class Counter {private static int count = 0; // 类变量(静态变量)private String name; // 实例变量public Counter(String name) {this.name = name;count++; // 每创建一个对象,类变量count增加1}public static int getCount() {return count; // 静态方法访问静态变量}
}
- 共享性
类变量被所有对象共享的时候,只有一份内存空间,简单来说就是存储在方法区,共用一块区域。
public class ShareDemo {public static String schoolName = "西瓜大学"; // 类变量,所有学生共享private String studentName; // 实例变量,每个学生独有public ShareDemo(String studentName) {this.studentName = studentName;}public static void main(String[] args) {ShareDemo stu1 = new ShareDemo("张三");ShareDemo stu2 = new ShareDemo("李四");System.out.println(stu1.schoolName); System.out.println(stu2.schoolName); // 修改类变量,所有对象都受影响ShareDemo.schoolName = "菠萝大学";System.out.println(stu1.schoolName); System.out.println(stu2.schoolName); }
}
- 访问方式
public class Student{public static int publicStatic = 15;public static int privateStatic = 16;publict static void main(String[] args){//方式1:类名访问System.out.println(Student.publicStatic);//方式2:通过对象访问Studentt stu = new Student();System.out.println(stu.publicStatic); //编译器会报错,不建议用第2种方式访问//访问私有静态成员变量,只能在一个类的内部访问System.out.println(privateStatic);}}
访问修饰符
- private(私有)只能在当前类内部使用
public class PrivateDemo {private String secret = "这是私有变量"; // 私有实例变量private static int count = 0; // 私有类变量public void showSecret() {System.out.println(secret); // 类内部可以访问}public static void showCount() {System.out.println(count); // 类内部可以访问}
}class TestPrivate {public static void main(String[] args) {PrivateDemo demo = new PrivateDemo();// System.out.println(demo.secret); // 错误!外部无法访问私有变量demo.showSecret(); // 正确!通过公共方法访问}
}
- public(公共)
可以被任何类访问,权限最高
public class PublicDemo {public String publicName = "公共变量"; // 公共实例变量public static int publicCount = 0; // 公共类变量
}class TestPublic {public static void main(String[] args) {PublicDemo demo = new PublicDemo();System.out.println(demo.publicName); // 外部可以直接访问,System.out.println(PublicDemo.publicCount); // 外部可以直接访问,静态成员变量建议用类名访问}
}
- protected(受保护)
可以被同一包中的类和子类访问
// 文件1:Parent.java
package com.example;
public class Parent {protected String protectedVar = "受保护的变量";protected static int protectedCount = 0;
}// 文件2:Child.java(同一包)
package com.example;
public class Child extends Parent {public void accessProtected() {System.out.println(protectedVar); // 子类可以访问System.out.println(protectedCount); // 子类可以访问}
}// 文件3:SamePackage.java(同一包)
package com.example;
public class SamePackage {public void test() {Parent p = new Parent();System.out.println(p.protectedVar); // 同包可以访问}
}
- 默认(包访问)
只能被同一包中的类访问
// 文件1:PackageDemo.java
package com.example;
public class PackageDemo {String packageVar = "包访问变量"; // 默认访问权限static int packageCount = 0; // 默认访问权限
}// 文件2:SamePackageTest.java(同一包)
package com.example;
public class SamePackageTest {public static void main(String[] args) {PackageDemo demo = new PackageDemo();System.out.println(demo.packageVar); // 同包可以访问System.out.println(PackageDemo.packageCount); // 同包可以访问}
}// 文件3:DifferentPackageTest.java(不同包)
package com.other;
import com.example.PackageDemo;
public class DifferentPackageTest {public static void main(String[] args) {PackageDemo demo = new PackageDemo();// System.out.println(demo.packageVar); // 错误!不同包无法访问}
}
成员方法
实例方法
- 方法定义语法
public class Student {private String name;private int age;private double score;// 1. 无参数无返回值的方法public void study() {System.out.println(name + "正在学习");}// 2. 有参数无返回值的方法public void setName(String name) {this.name = name;}// 3. 无参数有返回值的方法public String getName() {return name;}// 4. 有参数有返回值的方法public double calculateAverage(double score1, double score2, double score3) {return (score1 + score2 + score3) / 3.0;}// 5. 多个参数的方法public void updateInfo(String newName, int newAge, double newScore) {this.name = newName;this.age = newAge;this.score = newScore;}// 6. 返回对象类型的方法public Student createCopy() {Student copy = new Student();copy.name = this.name;copy.age = this.age;copy.score = this.score;return copy;}
}
- 方法调用
class Student{private String name;private int age;public void study(){System.out.println(name+"正在学习");
}public void setName(String name){this.name = name;
}public String getName(){return name;
}// 支持链式调用的方法public Student setAge(int age){this.age = age;return this
-
参数传递
基本类型参数传递 -
`public class PrimitivePass {
public void changeValue(int x) {
x = 100; // 只改变参数x的值,不影响外部变量
System.out.println("方法内部 x = " + x);
}public static void main(String[] args) {
PrimitivePass demo = new PrimitivePass();
int num = 10;System.out.println("调用前 num = " + num); // 输出:10demo.changeValue(num); // 输出:方法内部 x = 100System.out.println("调用后 num = " + num); // 输出:10(没有改变)// 基本类型参数传递是值传递,方法内部的修改不影响外部变量
}
}`
引用类型参数传递
public class ReferencePass {public void changeObject(Student student) {student.setName("方法内修改"); // 修改对象的属性System.out.println("方法内部:" + student.getName());}public void changeReference(Student student) {student = new Student(); // 创建新对象并赋值给参数student.setName("新对象");System.out.println("方法内部新对象:" + student.getName());}public static void main(String[] args) {ReferencePass demo = new ReferencePass();Student stu = new Student();stu.setName("原始名字");System.out.println("调用前:" + stu.getName()); // 输出:原始名字// 测试修改对象属性demo.changeObject(stu);System.out.println("调用changeObject后:" + stu.getName()); // 输出:方法内修改// 测试修改引用本身demo.changeReference(stu);System.out.println("调用changeReference后:" + stu.getName()); // 输出:方法内修改// 1. 传递的是引用的副本,可以通过引用修改对象属性// 2. 在方法内部修改引用本身不会影响外部引用}
}class Student {private String name;public void setName(String name) {this.name = name;}public String getName() {return name;}
}
静态方法(static)
-
static关键字
静态方法使用static关键字修饰,属于类本身而不属于任何具体对象;静态方法可以访问静态变量。 -
类名直接调用
静态方法可以通过类名直接调用,无需创建对象。 -
使用限制
public class StaticLimitations {private String instanceVar = "实例变量";private static String staticVar = "静态变量";// 静态方法的限制public static void staticMethod() {// 1. 不能直接访问实例变量// System.out.println(instanceVar); // 错误!// 2. 不能直接调用实例方法// instanceMethod(); // 错误!// 3. 不能使用this关键字// this.staticVar = "新值"; // 错误!// 4. 只能访问静态变量System.out.println(staticVar); // 正确// 5. 只能直接调用其他静态方法anotherStaticMethod(); // 正确// 6. 如果要访问实例成员,必须通过对象StaticLimitations obj = new StaticLimitations();System.out.println(obj.instanceVar); // 正确obj.instanceMethod(); // 正确}public static void anotherStaticMethod() {System.out.println("另一个静态方法");}public void instanceMethod() {System.out.println("实例方法");// 实例方法可以访问静态成员System.out.println(staticVar); // 正确staticMethod(); // 正确}
}
方法重载
- 重载条件
方法重载允许在同一个类中定义多个同名但参数不同的方法,
参数列表不同,返回值类型不同(仅这个条件不能构成重载)
public int getValue() {return 10;}public String getValue() { // 编译错误!return "10";}
构造方法
构造方法是一种特殊的方法,用于创建和初始化对象。
构造方法特点
public class Student{private String name;private int age;private String studentId;//构造方法特点;//1.方法名和类名完全相同//2.没有返回值类型声明(void也没有)//3.创建对象的时候自动调用public Student(){ //无参构造System.out.println("创建Student对象 ");this.name = "未知";this.age = "0";this.studentId = "000000";}public Student(String name){System.out.println("创建学生:" + name);this.name = name;this.age = 18; // 默认年龄this.studentId = "000000";}
}
this关键字
this代表对象的引用,是一个隐式的对象引用,指向当前正在执行方法的对象或当前正在被创建的对象(在构造方法种)
this的主要用法:
区分成员变量和局部变量
public class Student {private String name; // 成员变量private int age; // 成员变量public void setName(String name) { // 参数namethis.name = name; // this.name指向成员变量,name指向参数}public void setAge(int age) { // 参数agethis.age = age; // this.age指向成员变量,age指向参数}// 如果不用this会怎样?public void setNameWrong(String name) {name = name; // 这样写是错误的!参数赋值给参数,成员变量没有改变}
}
this使用的注意事项:
静态方法种不能使用this
public class Student{private String name;public static void staticMethod(){//this.name = "张三"; 此处报错,静态方法中不能使用this//静态方法属于类,不属于具体的对象}
}
封装(Encapsulation)
将数据和操作数据的方式绑定在一起,通过接口访问内部的相关的相关细节,对外隐藏内部实现的具体的细节。可以理解为封装好的电脑,通过外部的一些命令,调用内部的一些数据和操作。
封装概念
- 隐藏内部实现
将内部的具体细节隐藏,只暴露必要的接口
public class Student {// 私有数据private String studentId;private String name;private int age;private double[] scores;private int scoreCount;public Student(String studentId, String name, int age) {this.studentId = studentId;this.name = name;this.age = age;this.scores = new double[10]; // 最多10门成绩this.scoreCount = 0;}//公共接口,获取平均分public double getAverageScore(){if(scoreCount==0) return -;double sum = 0;for(int i =0; i<scoreCount;+++){sum +=scores[i]}return sum/scoreCount;}
}
实现方式
公共的gettet方法
public class Product {private String productId;private String name;private double price;private int stock;private String category;private boolean isActive;// Getter方法:提供对私有属性的读访问public String getProductId() {return productId;}public String getName() {return name;}public double getPrice() {return price;}public int getStock() {return stock;}public String getCategory() {return category;}public boolean isActive() { // boolean类型的getter通常以is开头return isActive;}// 计算属性的getterpublic double getTotalValue() {return price * stock;}// 格式化输出的getterpublic String getFormattedPrice() {return String.format("¥%.2f", price);}// 状态查询的getterpublic String getStockStatus() {if (stock <= 0) {return "缺货";} else if (stock < 10) {return "库存不足";} else {return "库存充足";}}
}
公共的setter方法
public class Employee {private String employeeId;private String name;private double salary;private String department;private int age;private String email;// Setter方法:提供对私有属性的写访问,包含验证逻辑public void setEmployeeId(String employeeId) {if (employeeId == null || employeeId.trim().isEmpty()) {throw new IllegalArgumentException("员工ID不能为空");}this.employeeId = employeeId.trim().toUpperCase();}public void setName(String name) {if (name == null || name.trim().isEmpty()) {throw new IllegalArgumentException("姓名不能为空");}if (name.length() > 50) {throw new IllegalArgumentException("姓名长度不能超过50个字符");}this.name = name.trim();}public void setSalary(double salary) {if (salary < 0) {throw new IllegalArgumentException("薪资不能为负数");}if (salary > 1000000) {System.out.println("警告:薪资异常高,请确认");}this.salary = salary;}public void setDepartment(String department) {if (department != null) {this.department = department.trim();}}public void setAge(int age) {if (age < 16 || age > 70) {throw new IllegalArgumentException("年龄必须在16-70之间");}this.age = age;}public void setEmail(String email) {if (email != null && !email.trim().isEmpty()) {if (!isValidEmail(email)) {throw new IllegalArgumentException("邮箱格式不正确");}this.email = email.trim().toLowerCase();}}private boolean isValidEmail(String email) {return email.matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$");}// 对应的getter方法public String getEmployeeId() { return employeeId; }public String getName() { return name; }public double getSalary() { return salary; }public String getDepartment() { return department; }public int getAge() { return age; }public String getEmail() { return email; }
}
关键概念
类与对象的关系
- 一对多关系,一个类可以创建多个对象,每个对象都是独立的
- 类是抽象,对象是具体:类定义了对象的属性和行为,但它本身是抽象的概念
- 类是模板,对象是实例
对象引用
- 引用变量:对象变量实际上是引用变量,存储的是对象的内存地址
- null值:表示引用变量不指向任何对象
- 垃圾回收:垃圾回收机制自动回收不再引用的对象。