Java基础--类和对象指南
面向对象编程(oop)是java的灵魂。理解类和对象,就如同掌握了构建java程序的基石。本文将带你从零开始,深入理解类的定义,对象的创建与初始化,再到封装,包,static关键字以及代码块等核心概念。
目录
引言:从“洗衣服”看编程范式的演变
核心观点:代码不仅仅是逻辑的堆砌,更是对现实世界的抽象。
面向过程:关注步骤。放水-->加洗衣粉-->搅拌-->脱水-->。如果中途洗衣机坏了,或者要洗鞋子,整个流程就要重写。代码耦合度极高,扩展和维护非常困难。
面向对象:关注参与者——人,洗衣机,,洗衣粉。人不需要知道洗衣机内部涡轮怎么转,只需要调用washingMachine.start()。这就是解耦,也是软件设计的核心目标之一。
拓展:在现在,这种思想依然适用。每个对象就像是一个独立的微服务,我们通过接口(api)进行交互,不需要关系对方内部是用java还是go写的。面向对象的基本原则——封装,继承,多态——在分布式系统中同样适用。
一.类和对象的定义与初始化
1.1类是什么?对象是什么?
类:是对现实世界实体的抽象描述,相当于一张设计图纸,它规定了给实体有哪些属性(如品牌,尺寸)和哪些功能(如洗衣脱水)。
对象:根据图纸实例化出来的具体东西,真正存在于内存中。
内存视角:定义一个class时,JVM只是在方法区记录了这个类的结构,并没有分配存储数据的空间。当使用new关键字实例化对象时,JVM才会在堆内存中开辟空间存储具体数据。
1.2类的定义格式
class ClassName{
//成员变量(属性)
//成员方法(行为)
}
//洗衣机类示例
class WashMachine {
// 成员变量
public String brand; // 品牌
public String type; // 型号
public double weight; // 重量
public String color; // 颜色
// 成员方法
public void washClothes() {
System.out.println("洗衣功能");
}
public void dryClothes() {
System.out.println("脱水功能");
}
}
命名规范:类名使用大驼峰,方法和变量使用小驼峰。
1.3对象的实例化和访问
使用new关键字创建对象,通过对象引用.成员进行访问。
public class Main{
public static void main(String[] args){
WashMachine wm=new WashMachine();//实例化
wm.brand="海尔";
wm.washClothes(); //调用方法
}
}
二. this引用与构造方法
2.1this关键字:解决“我是谁”
当形参和成员变量名相同时,你需要使用this来区分。this指向当前对象的引用
public void setDay(int year, int month, int day) {
this.year = year; // this.year 是成员变量,右边的 year 是形参
this.month = month;
this.day = day;
}
2.2构造方法:对象的“出生证明”
构造方法是一种特殊的成员方法:
方法名必须和类名相同
没有返回值类型(void也不能写)
创建对象时,由编译器自动调用,且在整个生命周期中只调用一次
public class Date {
public int year, month, day;
// 构造方法
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
}
2.3默认构造器的陷阱
如果用户没有定义任何构造方法,编译器会默认生成一个无参构造方法。
而一旦手动定义了带参数的构造方法,编译器就不会提供默认的无参构造器。
很多框架在通过反射创建对象时,往往依赖无参构造器。如果只写了有参构造器,这些框架就会报错——可以显式提供一个无参构造方法
2.4构造方法重载
可以定义多个构造方法,参数列表不同
public Date() { ... }
public Date(int year) { ... }
public Date(int year, int month, int day) { ... }
三.封装与包管理
3.1封装:拒绝“裸奔”的数据
封装是面向对象的三大特性之一。它通过private隐藏成员变量,对外提供public的getter//setter方法作为访问接口。
class Student {
private String name;
private int age;
public String getNmae(){
return name ;
}//获取name
public void setNmae(String name){
this.name=name;
}//传入name
public int getAge(){
return age;
}//获取age
public void setAge(int age){
if(age>=0&&age<=100){
this.age=age;
}else{
System.out.println("年龄非法");
}
}
}
封装的核心价值:
控制:在setter中可以加入校验逻辑,防止外部直接给年龄赋值-10这样的非法数据
隐藏:内部实现可以随时修改,只要对外接口不变,调用方就不要改动。
3.2访问限定符:权限的围栏
java提供了四种访问权限(由小到大)
| 修饰符 | private | (default) | protected | public |
| 本类 | ✅ | ✅ | ✅ | ✅ |
| 同包 | ❌ | ✅ | ✅ | ✅ |
| 子类 | ❌ | ❌ | ✅ | ✅ |
| 任意位置 | ❌ | ❌ | ❌ | ✅ |
| 典型场景 |
对象内部的私有状态 (如银行卡密码) |
包级工具类 (仅限内部使用) |
父类留给子类 扩展的钩子方法 |
对外暴露的api接口 |
3.3包(package):代码的“文件管理系统”
概念:包是一种组织类的方式,类似于文件系统的目录。它用于便面类名冲突,控制访问权限,更好的组织代码。
导入包:使用import语句可以简化类的使用。如果发生命名冲突,使用全限定类名(如java.util.Date)。
四.static关键字与代码块
4.1static修饰成员变量(类变量)
当某个属性被所有对象共享时,使用static修饰。例如所有学生所在的教室。
class Student {
private String name;
public static String classRoom = "1-101"; // 静态成员变量
}
特性:
属于类,不属于任何一个对象,所有对象共享一份
存储在方法区,而实例变量存储在堆中——这是它们生命周期不同的根本原因。
可以通过类名.静态变量直接访问,也可以通过实例对象访问
生命周期:随类加载而创建,随类卸载而销毁。
为什么工具类中的方法通常是静态的?
比如Math.sqrt()不需要依赖某个具体的Math对象,它是通用的逻辑,所以设计为静态方法,可以直接通过类名调用。
4.2static修饰成员方法(类方法)
class Student {
private static String classRoom = "1-101";
public static String getClassRoom() {
return classRoom;
}
}
// 调用
Student.getClassRoom();
静态方法的重要限制:
不能访问非静态成员变量
不能调用非静态方法
不能使用this关键字(因为没有当前对象)
4.3代码块
1.普通代码块:定义在方法内部,用于限定变量作用域。
2.实例代码块(构造代码块)
定义在类中,方法外,不加任何修饰符。每次创建对象时都会执行,并且在构造方法之前执行。常用于通用的初始化逻辑。
3.静态代码块:使用static修饰,定义在类中方法外。在类加载时执行一次,常用于初始化成员变量。
class Student{
private static String classRoom;
//静态代码块
static{
classRoom="1";
System.out.println("静态代码块执行");//加载类时执行一次
}
//实例代码块
{
System.out.println("实例代码块执行");//每次实例化对象执行一次
}
public Student(){
System.out.println("构造方法执行");
}
}
当父类和子类都有代码块
顺序:父类静态块——>子类静态块——>父类实例块——>父类构造方法——>子类实例块——>子类构造方法
五.对象的打印——重写toString
直接打印对象引用,输出的是类名@哈希码。如果想打印对象的属性内容,需要重写toString方法
@Override
public String toString() {
return "[" + name + ", " + gender + ", " + age + "]";
}
总结
1.类与对象:类是对象的模板,对象是类的实例,通过new关键字创建。
2.成员变量和成员方法:属性描述状态,方法定义行为。
3.构造方法:与类同名,无返回值,用于初始化对象;一旦自定义构造方法,编译器不再提供默认无参构造。
4.this引用:指向当前对象,用于区分成员变量和局部变量,也是成员方法的隐藏参数。
5.封装:使用private隐藏属性,通过public的getter/setter控制访问,提高安全性和可维护性。
6.包:组织类,防止命名冲突,控制访问权限。
7.static关键字:静态成员属于类级别,所有对象共享;静态方法不能访问非静态成员。
8.代码块:静态代码块(类加载时执行一次),实例代码块(创建对象时执行),普通代码块(方法内局部作用域)
9.对象的打印:重写toString方法可以自定义输出。
更多推荐




所有评论(0)