首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java基础(七): 面向过程与面向对象、类与对象、成员变量与局部变量、值传递与引用传递、方法重载与方法重写

Java基础(七): 面向过程与面向对象、类与对象、成员变量与局部变量、值传递与引用传递、方法重载与方法重写

作者头像
Java微观世界
发布2025-07-17 17:34:26
发布2025-07-17 17:34:26
13100
代码可运行
举报
文章被收录于专栏:springbootspringboot
运行总次数:0
代码可运行

Java基础系列文章

Java基础(一):初识Java——发展历程、技术体系与JDK环境搭建

Java基础(二):八种基本数据类型详解

Java基础(三):逻辑运算符详解

Java基础(四):位运算符详解

Java基础(五):流程控制全解析——分支(if/switch)和循环(for/while)的深度指南

Java基础(六):数组全面解析

Java基础(七):面向对象编程核心解析 - POP vs OOP、类与对象、变量作用域及方法特性

一、面向过程 vs 面向对象

1、面向过程的程序设计(Process-Oriented Programming)简称POP

  • 核心:以函数为中心,关注解决问题的步骤(先做什么、后做什么)
  • 数据与操作分离:数据(变量)和操作数据的函数是独立的
  • 典型的语言:C语言
  • 是一种“执行者思维”,适合解决简单问题。扩展能力差、后期维护难度较大

计算矩形面积和周长面向过程写法:

代码语言:javascript
代码运行次数:0
运行
复制
public class ProceduralExample {
    // 数据与函数分离
    public static double calculateArea(double length, double width) {
        return length * width;
    }
    
    public static double calculatePerimeter(double length, double width) {
        return 2 * (length + width);
    }

    public static void main(String[] args) {
        double length = 5.0;
        double width = 3.0;
        // 逐步调用函数
        double area = calculateArea(length, width);
        double perimeter = calculatePerimeter(length, width);
        System.out.println("面积: " + area + ", 周长: " + perimeter);
    }
}

2、面向对象的程序设计(Object-Oriented Programming)简称OOP

  • 核心:以对象为中心,将问题分解为相互交互的实体(对象)
  • 封装:数据(属性)和操作数据的方法绑定在对象中
  • 典型的语言:Java、C#、C++、Python、Ruby和PHP等
  • 是一种“设计者思维”,适合解决复杂问题。代码扩展性强、可维护性高

计算矩形面积和周长面向对象写法:

代码语言:javascript
代码运行次数:0
运行
复制
// 封装数据和操作
class Rectangle {
    private double length;
    private double width;

    public Rectangle(double length, double width) {
        this.length = length;
        this.width = width;
    }

    // 方法绑定到对象
    public double calculateArea() {
        return length * width;
    }

    public double calculatePerimeter() {
        return 2 * (length + width);
    }
}

public class OOPExample {
    public static void main(String[] args) {
        // 创建对象并调用方法
        Rectangle rect = new Rectangle(5.0, 3.0);
        System.out.println("面积: " + rect.calculateArea() + ", 周长: " + rect.calculatePerimeter());
    }
}

二、类(Class)vs 对象(Object)

  在Java中,类(Class)对象(Object)面向对象编程(OOP)的核心概念。它们的关系类似于“蓝图”“根据蓝图建造的具体实物”

1、类(Class)

定义:类是描述一类对象的模板蓝图。它定义了对象的属性(字段)和行为(方法)

组成

  • 字段(Fields):对象的属性(如 String name;
  • 方法(Methods):对象的行为(如 void eat() {...}
  • 构造器(Constructor):创建对象时初始化状态的特殊方法

示例

代码语言:javascript
代码运行次数:0
运行
复制
// 定义一个"Dog"类
public class Dog {
    // 字段(属性)
    String breed;
    int age;
    String color;
    
    // 构造器(初始化对象)
    public Dog(String breed, int age, String color) {
        this.breed = breed;
        this.age = age;
        this.color = color;
    }
    
    // 方法(行为)
    void bark() {
        System.out.println("汪汪!");
    }
    
    void sleep() {
        System.out.println("睡觉中...");
    }
}

2、对象(Object)

定义:对象是类的实例(Instance),是根据类创建的具体实体

特点

  • 每个对象拥有独立的状态(字段的值)和行为(方法的实现)
  • 通过 new 关键字创建对象

示例

代码语言:javascript
代码运行次数:0
运行
复制
public class Main {
    public static void main(String[] args) {
        // 创建Dog类的对象
        Dog myDog = new Dog("拉布拉多", 3, "黄色");
        
        // 访问对象的字段
        System.out.println("品种: " + myDog.breed); // 输出: 拉布拉多
        
        // 调用对象的方法
        myDog.bark(); // 输出: 汪汪!
    }
}

三、成员变量 vs 局部变量

1、成员变量

定义:直接声明在类内部、方法/代码块外部的变量

分类

  1. 实例变量(非 static
  2. 类变量(static,静态变量)

示例

代码语言:javascript
代码运行次数:0
运行
复制
public class Person {
    // 实例变量(属于对象)
    private String name;   // 无static修饰
    
    // 类变量(属于类)
    public static int count; // 有static修饰
}

特点说明:

特性

说明

作用域

整个类(类变量可跨类访问)

生命周期

实例变量:随对象创建而存在,随对象回收而销毁类变量:随类加载而存在,随程序结束而销毁

存储位置

堆内存(实例变量在对象内)、方法区(类变量)

初始化

自动赋予默认值(如 int 默认为 0,引用类型默认为 null)

访问方式

实例变量:对象.变量名类变量:类名.变量名 或 对象.变量名(不推荐)

修饰符

可用 public/private/protected/static/final 等

2、局部变量

定义:声明在方法、构造方法、代码块或形参列表中的变量

分类

  1. 方法局部变量
  2. 代码块局部变量
  3. 参数变量(方法形参)

示例

代码语言:javascript
代码运行次数:0
运行
复制
public void printInfo(int age) { // age是参数(局部变量)
    String message = "Age: ";   // 方法局部变量
    {
        int temp = 10;          // 代码块局部变量(仅在此块内有效)
    }
    System.out.println(message + age);
}

特点说明:

特性

说明

作用域

从声明处开始,到所属代码块结束(如方法/循环/条件体内部)

生命周期

随方法/代码块的执行而创建,执行结束后销毁

存储位置

栈内存

初始化

必须手动初始化(否则编译报错)

访问方式

直接通过变量名(仅在作用域内有效)

修饰符

不可用static/访问修饰符(如 public),但可用 final

四、值传递 vs 引用传递

在 Java 中,所有方法的参数传递都是值传递。这意味着方法内部获得的是参数的副本,而非原始变量本身。理解这一点对于基本数据类型引用类型(对象)的行为至关重要。

1、基本数据类型(值传递)

传递的是值的副本,方法内修改参数不影响原始变量

示例:

代码语言:javascript
代码运行次数:0
运行
复制
void modify(int x) {
    x = 20;  // 修改的是副本
}

public static void main(String[] args) {
    int a = 10;
    modify(a);
    System.out.println(a);  // 输出 10(原始值未变)
}

2、引用类型(传递引用地址的值)

  • 传递的是对象地址的副本,方法内通过该地址修改对象属性会影响原始对象,但重新赋值引用不影响原始引用
  • 关键点:
    • 修改对象属性:影响原始对象(因副本和原始引用指向同一对象
    • 重定向引用:不影响原始引用(修改的是副本地址

示例1:修改对象属性(原始对象被改变

代码语言:javascript
代码运行次数:0
运行
复制
class Person {
    String name;
    Person(String name) { this.name = name; }
}

void changeName(Person p) {
    p.name = "Bob";  // 修改副本指向的对象属性
}

public static void main(String[] args) {
    Person person = new Person("Alice");
    changeName(person);
    System.out.println(person.name);  // 输出 "Bob"(原始对象被修改)
}

示例2:重定向引用(原始引用不变

代码语言:javascript
代码运行次数:0
运行
复制
void createNewPerson(Person p) {
    p = new Person("Bob");  // 副本指向新对象,原始引用不变
}

public static void main(String[] args) {
    Person person = new Person("Alice");
    createNewPerson(person);
    System.out.println(person.name);  // 输出 "Alice"(原始引用未变)
}

注意⚠️:Java 只有值传递!对于引用类型,传递的是引用的值(即对象地址的副本),而非引用本身(即不是引用传递)

五、方法重载 vs 方法重写

1、方法重载(Overloading)

  • 定义:在同一个类中,多个方法使用相同的方法名参数列表不同(参数类型、个数或顺序不同)
  • 核心特点:
    1. 相同类中:所有重载方法必须在同一个类(或父子类中也可重载)
    2. 方法名相同:必须使用完全相同的名称
    3. 参数列表不同
      • 参数类型不同(如 int vs String)
      • 参数个数不同(如 method() vs method(int a))
      • 参数顺序不同(如 method(int a, String b) vs method(String b, int a))
    4. 与以下无关
      • 返回类型(可不同)
      • 访问修饰符(可不同)
      • 抛出的异常(可不同)

示例:

代码语言:javascript
代码运行次数:0
运行
复制
class Calculator {
    // 重载add方法
    public int add(int a, int b) {
        return a + b;
    }
    
    public double add(int a, double b) { // 参数类型不同
        return a + b;
    }
    
    public int add(int a, int b, int c) { // 参数个数不同
        return a + b + c;
    }
    
    public double add(double a, int b) { // 参数顺序不同
        return a + b;
    }

    // public double add(int a, int b) { // 只有返回值类型不同,编译失败
    //     return a + b;
    // }
}

调用原理:编译器在编译时根据参数类型数量决定调用哪个方法(静态绑定)

代码语言:javascript
代码运行次数:0
运行
复制
Calculator calc = new Calculator();
calc.add(2, 3);       // 调用 int add(int, int)
calc.add(2.5, 3.7);   // 调用 double add(double, double)
calc.add("He", "llo"); // 调用 String add(String, String)

2、方法重写(Overriding)

定义:子类重新定义从父类继承的方法,提供特定实现

目的:实现运行时多态,允许子类定制父类行为

核心特点:

方法名称一致,参数类型、个数、顺序完全一致

返回类型:可以相同,也可以是父类返回类型的 子类型

访问权限:子类方法访问修饰符大于等于不能比父类被重写方法修饰符

代码语言:javascript
代码运行次数:0
运行
复制
// 子类对象必须能够替代父类对象使用
// 假设父类的方法是 public,那么用户通过父类引用应该可以调用该方法:
class Parent {
    public void show() {
        System.out.println("Parent");
    }
}

class Child extends Parent {
    // 错误写法:降低访问权限
    protected void show() {
        System.out.println("Child");
    }
}

// 在这种情况下:
Parent p = new Child();
p.show(); // 编译器会找 Parent 的 public show()
// ⚠️但如果 Child 中的 show() 是 protected,Java 编译器就无法访问这个方法

异常限制:子类方法抛出的异常小于等于父类抛出异常

代码语言:javascript
代码运行次数:0
运行
复制
// 假设父类方法声明会抛出某个异常,那么你就可以在使用父类引用时,写出对应的异常处理代码
// 如果子类重写方法却抛出了更多或更广泛的异常
// 父类引用将无法预见这些额外的异常,程序可能在运行时出现无法捕获的错误
class Parent {
    public void work() throws IOException {
        // ...
    }
}

class Child extends Parent {
    @Override
    public void work() throws Exception { // ❌ 错误!Exception 比 IOException 范围大
        // ...
    }
}
// ⚠️违反了任何使用父类的地方都应该能透明地替换成子类

只能重写实例方法,不能重写 static、final、private 方法

  • static 方法属于类,不是实例,叫做方法隐藏(不是重写)
  • final 方法不能被重写
  • private 方法在子类中不可见,也不能被重写

示例:

代码语言:javascript
代码运行次数:0
运行
复制
class Animal {
    public void makeSound() {
        System.out.println("Animal makes sound");
    }
}

class Dog extends Animal {
    @Override // 注解确保正确重写
    public void makeSound() { // 重写父类方法
        System.out.println("Dog barks: Woof!");
    }
}

调用原理:JVM在运行时根据对象实际类型决定调用哪个方法(动态绑定)

代码语言:javascript
代码运行次数:0
运行
复制
Animal myDog = new Dog(); // 向上转型
myDog.makeSound(); // 输出 "Dog barks: Woof!"
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-07-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、面向过程 vs 面向对象
    • 1、面向过程的程序设计(Process-Oriented Programming)简称POP
    • 2、面向对象的程序设计(Object-Oriented Programming)简称OOP
  • 二、类(Class)vs 对象(Object)
    • 1、类(Class)
    • 2、对象(Object)
  • 三、成员变量 vs 局部变量
    • 1、成员变量
    • 2、局部变量
  • 四、值传递 vs 引用传递
    • 1、基本数据类型(值传递)
    • 2、引用类型(传递引用地址的值)
  • 五、方法重载 vs 方法重写
    • 1、方法重载(Overloading)
    • 2、方法重写(Overriding)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档