当前位置: 首页 > ops >正文

【六. Java面向对象编程入门指南】

6. java面向对象基础

6.1 设计对象并使用

6.1.1 类与对象的本质理解

  • 类的本质:类是对现实事物的模板化抽象。好比 “图纸”

  • 对象的本质:对象是类的具体实例。好比根据图纸造出的 “真实汽车”

6.1.2 类的定义细节

  • 成员变量的默认值规则

    数据类型默认值示例(未赋值时)
    整数类型(如 int)0int age; → 0
    浮点类型(如 double)0.0double price; → 0.0
    字符类型(char)‘\u0000’(空字符)char gender; → 空字符
    布尔类型(boolean)falseboolean isStudent; → false
    引用类型(如 String)nullString name; → null
  • 成员方法的注意事项:

    • 无需static修饰:因为成员方法属于对象层面的行为,依赖具体对象调用

    • 可直接访问成员变量:成员方法内部可直接使用成员变量名,无需 “对象名.” 前缀(本质是通过this隐式调用)

6.1.3 对象的创建与使用深度解析

  • 创建对象的底层逻辑:

    • 分配堆内存:new 类名()会在堆内存中开辟一块空间,存储对象的属性值和方法引用

    • 初始化属性:成员变量按默认值初始化(如int为 0,Stringnull

    • 返回对象地址:将堆内存地址赋值给栈中的引用变量(如Phone p = ...中的p

  • 访问成员的底层逻辑

    • 访问属性:对象名.属性名 → 通过引用变量找到堆内存中的对象,直接操作属性值例子: p.brand = "小米" → 找到p指向的对象,修改其brand属性为 “小米”

    • 调用方法:对象名.方法名() → 通过引用变量找到对象,根据方法引用找到方法区中的代码执行例子:p.call() → 执行方法区中Phone类call()方法逻辑

  • 例子:

      public class Car {  // 成员变量(属性)  String color;   // 颜色,默认null  int speed;      // 速度,默认0  boolean isStart; // 是否启动,默认false  // 成员方法(行为)  public void start() { // 启动车  isStart = true;  System.out.println("汽车已启动,当前速度:" + speed);  }  public void accelerate(int addSpeed) { // 加速  if (!isStart) { // 未启动时无法加速  System.out.println("请先启动汽车!");  return;  }  speed += addSpeed;  System.out.println("加速后速度:" + speed + "km/h");  }  }  // 使用对象  public class CarDemo {  public static void main(String[] args) {  // 1. 创建对象  Car c = new Car();  // 2. 访问属性(直接操作,未封装时)  System.out.println("初始颜色:" + c.color); // 输出:null  c.color = "红色"; // 赋值  System.out.println("修改后颜色:" + c.color); // 输出:红色  // 3. 调用方法  c.start(); // 输出:汽车已启动,当前速度:0  c.accelerate(50); // 输出:加速后速度:50km/h  c.accelerate(-20); // 合法,速度减为30km/h  }  }  

6.2 封装

6.2.1 为什么需要封装?

  • 场景举例:若直接暴露成员变量(如public int age;),外部代码可能赋值非法数据(如年龄 - 5 岁),导致逻辑错误

  • 封装的优势:

    • 数据安全:通过setter方法添加校验逻辑,防止非法数据

    • 结构清晰:外部只需通过固定方法操作数据,无需关心内部实现

    • 可维护性:修改内部逻辑时(如调整年龄范围),只需修改setter,不影响外部调用

6.2.2 private关键字的深度用法

私有化成员变量的步骤:

  1. 声明时加private

    private String name; // 私有化姓名,外部不可直接访问

  2. 提供publicgetter/setter方法:

  * `getter`方法:用于读取属性值,命名规则`getXxx()`(布尔类型用`isXxx()`)public String getName() { // 获取姓名  return name;  }  
  • setter方法:用于设置属性值,可添加校验逻辑,命名规则setXxx(参数)
        public void setAge(int age) { // 设置年龄  if (age < 0 || age > 150) { // 年龄必须在0-150之间  System.out.println("年龄非法!请重新设置。");  return; // 终止方法,不赋值  }  this.age = age; // 合法时赋值  }  

封装 vs 不封装的对比:

场景未封装(public 成员变量)封装(private+getter/setter)
赋值年龄 - 5 岁直接赋值成功,逻辑错误setAge(-5)触发校验,拒绝赋值
代码维护(修改年龄范围)需修改所有赋值代码只需修改setAge方法的校验逻辑
外部调用复杂度直接操作属性,耦合度高通过固定方法操作,结构清晰

6.2.3 封装的最佳实践

  • 所有成员变量必须私有化:除非有特殊需求(如工具类的静态变量),否则绝不使用public修饰成员变量

  • setter方法必填校验逻辑:根据业务规则对输入数据进行合法性检查(如年龄、邮箱格式、密码长度等)

  • getter方法保持简单:通常仅返回属性值,不添加复杂逻辑(复杂逻辑应封装到其他业务方法中)

6.3 this关键字

6.3.1 this的三大作用

  1. 区分同名变量:当方法参数与成员变量同名时,用this明确指代成员变量
      public void setName(String name) {  this.name = name; // this.name是成员变量,name是方法参数  }  
  1. 调用成员方法:在成员方法内部,可通过this.方法名()调用本类的其他成员方法(通常可省略this.
      public void study() {  System.out.println("开始学习...");  this.doHomework(); // 调用本类的doHomework方法  }  public void doHomework() {  System.out.println("正在写作业...");  }  
  1. 调用构造方法:在构造方法中,用this(参数)调用本类的其他构造方法(必须位于构造方法第一行)
      public class Student {  private String name;  private int age;  // 无参构造调用有参构造(初始化默认值)  public Student() {  this("匿名学生", 0); // 调用Student(String, int)构造  }  // 有参构造  public Student(String name, int age) {  this.name = name;  this.age = age;  }  }  

6.3.2 this的本质:当前对象的引用

  • 当对象stu调用方法setName("张三")时,方法内部的this就代表stu对象

  • 栈内存:stu --> 堆地址0x123  堆内存(对象):  
    Student {  name: null,  age: 0,  setName(String name) {  this.name = name; // this指向stu对象,即给stu的name赋值  }  
    }  
    

6.4 构造方法

6.4.1 构造方法的核心特性

  1. 名称必须与类名完全一致(包括大小写):
      public class Dog {  public Dog() { // 构造方法名必须是Dog  }  }  
  1. 没有返回值类型(连void也不能写):
      public Dog() { // 正确  }  public void Dog() { // 错误!这是普通方法,不是构造方法  }  
  1. 创建对象时必须调用:每次使用new关键字创建对象时,必然会执行一个构造方法(默认无参或自定义构造)

6.4.2 默认构造方法与自定义构造的关系

  • 默认构造的生成条件:当类中没有任何构造方法时,系统自动生成无参构造(public 类名() {})。

  • 自定义构造的影响:一旦定义了任意构造方法(无参或有参),系统不再生成默认无参构造

      public class Cat {  // 自定义有参构造  public Cat(String name) {  }  // 此时系统不会生成无参构造,以下代码会报错!  // Cat c = new Cat(); // 错误:无法找到无参构造  }  
  • 推荐做法:无论是否需要,都手动添加无参构造,避免后续扩展时因缺少构造方法报错

6.4.3 构造方法的重载规则

  • 重载条件:构造方法名相同,参数列表不同(参数个数、类型、顺序不同),与返回值无关(构造无返回值)
      public class Person {  public Person() {} // 无参构造  public Person(String name) {} // 1个参数(String)  public Person(int age) {} // 1个参数(int),与上一个构成重载(类型不同)  public Person(String name, int age) {} // 2个参数  }  
  • 禁止重载的情况:参数列表完全相同,即使方法体不同,也无法构成重载(编译报错)

6.5 标准JavaBean

6.5.1 JavaBean 的完整规范

  1. 成员变量:全部private修饰,禁止外部直接访问
      private String name;  private int age;  
  1. 构造方法:提供无参构造和全参构造
      public Student() { //无参构造}  public Student(String name, int age) {  // 全参构造 this.name = name;  this.age = age;  }  
  1. getter/setter方法:为每个成员变量提供对应方法
      public String getName() { return name; }  public void setName(String name) {this.name = name;}  
  1. 可选:实现Serializable接口(用于对象序列化,如网络传输、持久化存储)

6.5.2 快速生成 JavaBean 的技巧(IDE 工具)

  • IDEA 操作:

    • 在类中按Alt+Insert

    • 选择Constructor/Getter and Setter

    • 勾选需要的成员变量

    • 生成代码

6.6 对象内存图

6.6.1 单个对象的内存分布(以Student类为例)

栈内存:s --> 堆地址0x100  
堆内存:  
Student {  name: "李四",  // 通过setName赋值  age: 20,       // 通过setAge赋值  show(): 方法引用 --> 方法区中的show()代码  
}  
方法区:  
Student类的成员方法(show()等)存储在此  

6.6.2 多个对象的内存关系

栈内存:s1 --> 0x100,s2 --> 0x200  
堆内存:  
0x100: Student { name: "A", age: 18 }  
0x200: Student { name: "B", age: 20 }  
方法区:  
Student类的成员方法(show()等)被所有对象共享  

6.7 成员变量与局部变量的区别

对比维度成员变量局部变量
定义位置类中方法外方法内或方法参数
内存位置堆内存(属于对象)栈内存(属于方法栈帧)
生命周期随对象创建而存在,随对象销毁而消失随方法调用而存在,随方法结束而消失
默认值有默认值(如int为 0,String为null)无默认值,必须先赋值后使用
作用域整个类范围内可见仅限方法内或代码块内可见
    public class Demo {  int memberVar = 10; // 成员变量,默认值10  public void method() {  int localVar = 20; // 局部变量,无默认值,必须赋值  System.out.println(memberVar); // 正确,成员变量可在方法内访问  // System.out.println(localVar2); 错误,未定义  }  }
http://www.xdnf.cn/news/10252.html

相关文章:

  • HackMyVM-Ephemeral3
  • js数据类型有哪些?它们有什么区别?
  • 吴恩达MCP课程(3):mcp_chatbot
  • NW994NX734美光固态闪存NX737NX740
  • SpringBoot如何实现一个自定义Starter?
  • python创建args命令行分析
  • Halcon
  • 从gitee仓库中恢复IDEA项目某一版本
  • Java基础 Day26
  • NumPy 数组计算:广播机制
  • langchain学习 01
  • enumiax:IAX 协议用户名枚举器!全参数详细教程!Kali Linux教程!
  • Vue 核心技术与实战day06
  • Java并发编程实战 Day 2:线程安全与synchronized关键字
  • JS逆向案例—喜马拉雅xm-sign详情页爬取
  • 【xmb】内部文档148344597
  • HomeKit 基本理解
  • JavaSwing之--为组件添加背景
  • 记忆胶囊应用源码纯开源
  • Linux命令之ausearch命令
  • TDengine 集群运行监控
  • Java中的ConcurrentHashMap的使用与原理
  • C语言 — 动态内存管理
  • 杨辉三角系数
  • 嵌入式学习笔记 - STM32 HAL库以及标准库内核以及外设头文件区别问题
  • 【android bluetooth 协议分析 03】【蓝牙扫描详解 1】【扫描关键函数 btif_dm_search_devices_evt 分析】
  • proteus新建工程
  • Python实现P-PSO优化算法优化BP神经网络分类模型项目实战
  • tomcat yum安装
  • 360浏览器设置主题