Skip to content

Java方法高级特性与面向对象入门

目录


一、方法核心注意事项

1.1 方法执行五大原则

原则说明示例
不调用不执行方法定义后必须显式调用才会执行method() 才会执行
执行顺序与调用顺序一致与定义顺序无关先调用的先执行
void与return不能共存void表示无返回值,不能return结果void方法中return; 可以,return 值; 不行
方法签名必须完全匹配方法名、参数个数、类型、顺序都要一致sum(int, int)sum(int, int, int)
单一返回值一个方法只能有一个返回值不能连续写多个return(if-else除外)

1.2 方法调用方式总结

java
// 1. 无参无返回值 -> 直接调用
public static void method01() {
    System.out.println("执行方法");
}
method01();

// 2. 有参无返回值 -> 直接调用传参
public static void method02(int a, int b) {
    System.out.println(a + b);
}
method02(10, 20);

// 3. 无参有返回值 -> 打印调用或赋值调用
public static int method03() {
    return 100;
}
System.out.println(method03());  // 打印调用
int result = method03();          // 赋值调用

// 4. 有参有返回值 -> 打印调用或赋值调用
public static int method04(int a, int b) {
    return a + b;
}
System.out.println(method04(10, 20));
int sum = method04(10, 20);

1.3 方法内存执行过程

方法压栈弹栈

关键概念:

  • 压栈:方法被调用时,进入栈内存
  • 弹栈:方法执行完毕,从栈内存中清除

二、方法参数传递机制

2.1 基本类型参数传递

核心原则:传递的是数据值的副本

java
public class Demo {
    public static void main(String[] args) {
        int a = 10;
        method(a);
        System.out.println(a);  // 输出:10(值未改变)
    }
    
    public static void method(int a) {
        a = 20;  // 修改的是副本,不影响原变量
    }
}

基本类型参数传递

2.2 引用类型参数传递

核心原则:传递的是地址值

java
public class Demo {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        method(arr);
        System.out.println(arr[0]);  // 输出:100(值已改变)
    }
    
    public static void method(int[] arr) {
        arr[0] = 100;  // 通过地址修改了原数组
    }
}

引用类型参数传递

2.3 对比总结

类型传递内容形参修改是否影响实参原因
基本类型数据值副本❌ 不影响修改的是副本
引用类型地址值✅ 影响指向同一内存空间

三、方法重载(Overload)

3.1 重载定义

同一个类中,方法名相同,参数列表不同的方法

3.2 参数列表不同的三种情况

java
public class Demo {
    // 1. 参数个数不同
    public static void sum(int a, int b) { }
    public static void sum(int a, int b, int c) { }
    
    // 2. 参数类型不同
    public static void sum(int a, int b) { }
    public static void sum(double a, double b) { }
    
    // 3. 参数类型顺序不同
    public static void sum(int a, double b) { }
    public static void sum(double a, int b) { }
}

3.3 与重载无关的因素

因素是否影响重载说明
参数名❌ 无关sum(int a)sum(int b) 是同一个方法
返回值类型❌ 无关不能仅通过返回值区分方法
修饰符❌ 无关与public/static等无关

3.4 重载识别练习

java
public static void open(){}                          // ✅ 方法1
public static void open(int a){}                     // ✅ 方法2 - 参数个数不同
static void open(int a,int b){}                      // ✅ 方法3 - 参数个数不同
public static void open(double a,int b){}            // ✅ 方法4 - 参数类型不同
public static void open(int a,double b){}            // ✅ 方法5 - 参数类型顺序不同
public void open(int i,double d){}                   // ❌ 与方法5冲突(参数名无关)
public static void OPEN(){}                          // ✅ 方法名不同,不是重载
public static void open(int i,int j){}               // ❌ 与方法3冲突(参数名无关)

重载示例

3.5 重载使用场景

功能相同,但实现细节不同时使用重载

java
// 示例:求和方法
public static int sum(int a, int b) {
    return a + b;
}

public static int sum(int a, int b, int c) {
    return a + b + c;
}

public static int sum(int a, int b, int c, int d) {
    return a + b + c + d;
}

重载使用场景


四、可变参数

4.1 定义格式

java
数据类型... 变量名

4.2 核心特点

特点说明
本质是数组可变参数在方法内部作为数组使用
只能有一个参数列表中只能有一个可变参数
必须放最后可变参数必须放在参数列表的最后

4.3 基本使用

java
public class Demo {
    public static void main(String[] args) {
        sum(1, 2, 3, 4);      // 输出:10
        sum(1, 2, 3);         // 输出:6
        sum(1, 2);            // 输出:3
    }
    
    public static void sum(int... arr) {
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        System.out.println(sum);
    }
}

可变参数

4.4 实战案例

案例一:字符串拼接

java
public static String concat(String... arr) {
    String str = "";
    for (int i = 0; i < arr.length; i++) {
        str += arr[i];
    }
    return str;
}

// 调用
String result = concat("张无忌", "周芷若", "赵敏");
// 结果:张无忌周芷若赵敏

案例二:带分隔符的字符串拼接

java
public static String concat(String separator, String... arr) {
    String str = "";
    for (int i = 0; i < arr.length; i++) {
        if (i == arr.length - 1) {
            str += arr[i];
        } else {
            str += arr[i] + separator;
        }
    }
    return str;
}

// 调用
String result = concat("-", "张三", "李四", "王五");
// 结果:张三-李四-王五

五、递归

5.1 递归定义

方法内部调用方法本身

5.2 递归两大注意事项

注意事项说明后果
必须有出口递归必须有终止条件无出口会导致栈内存溢出
递归次数不能太多即使有出口,递归层次太深也会溢出栈内存溢出

5.3 错误示例:无出口递归

java
public static void method() {
    method();  // 无限递归,导致栈溢出
}

递归栈溢出

5.4 经典案例

案例一:输出3到1

java
public static void method(int n) {
    if (n == 0) {
        return;  // 递归出口
    }
    System.out.println(n);
    n--;
    method(n);  // 递归调用
}

// 调用
method(3);  // 输出:3 2 1

递归输出

案例二:求阶乘

java
public static int factorial(int n) {
    if (n == 1) {
        return 1;  // 递归出口
    }
    return n * factorial(n - 1);
}

// 调用
int result = factorial(5);  // 5! = 120

递推公式: n! = n * (n-1)!

阶乘递归

案例三:斐波那契数列

问题描述: 一对兔子从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假设兔子都不死,问每个月的兔子对数为多少?

数列规律: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55...

斐波那契数列

java
public static int fib(int n) {
    if (n == 1 || n == 2) {
        return 1;  // 递归出口
    }
    return fib(n - 1) + fib(n - 2);
}

// 调用
int result = fib(12);  // 第12个月有144对兔子

递推公式: fib(n) = fib(n-1) + fib(n-2)


六、类与对象

6.1 面向对象三大特征

特征说明
封装隐藏实现细节,暴露公共访问方式
继承子类继承父类的属性和行为
多态同一行为具有多个不同表现形式

6.2 面向对象思想

核心目的:减少代码量,提高复用性

使用方式:

  1. new对象调用new Scanner(System.in).next()
  2. 类名直接调用Math.random()(静态成员)

6.3 类的分类

类型说明示例
测试类包含main方法的类public class Test
逻辑类专门处理业务逻辑public class UserService
实体类描述一类事物public class Person

6.4 实体类的组成

成员变量(属性)

定义位置: 类中方法外

作用范围: 整个类

默认值:

数据类型默认值
整数类型(byte, short, int, long)0
浮点类型(float, double)0.0
字符类型(char)'\u0000'
布尔类型(boolean)false
引用类型null

成员方法(行为)

定义格式: 去掉static关键字的方法

java
public void eat() {
    System.out.println("吃饭");
}

6.5 实体类示例

示例一:Person类

java
public class Person {
    // 属性(成员变量)
    String name;  // 默认值:null
    int age;      // 默认值:0
    
    // 行为(成员方法)
    public void eat() {
        System.out.println("吃饭");
    }
    
    public void drink() {
        System.out.println("喝水");
    }
    
    public void sleep() {
        System.out.println("睡觉");
    }
}

示例二:Phone类

java
public class Phone {
    // 属性
    String brand;   // 品牌
    int price;      // 价格
    String color;   // 颜色
    
    // 行为
    public void call(String name) {
        System.out.println("给" + name + "打电话");
    }
    
    public String sendMessage(String name, String message) {
        return "给" + name + "发短信,内容是:" + message;
    }
}

6.6 对象的使用

使用步骤

  1. 导包import 包名.类名;(同包可省略)
  2. 创建对象类名 对象名 = new 类名();
  3. 调用成员对象名.成员名

使用示例

java
public class Demo {
    public static void main(String[] args) {
        // 创建Person对象
        Person p1 = new Person();
        
        // 访问属性
        System.out.println(p1.name);  // null
        System.out.println(p1.age);   // 0
        
        // 给属性赋值
        p1.name = "张三";
        p1.age = 18;
        
        // 调用方法
        p1.eat();
        p1.drink();
        p1.sleep();
        
        // 创建Phone对象
        Phone phone = new Phone();
        phone.brand = "华为";
        phone.price = 8888;
        phone.color = "白色";
        
        phone.call("李四");
        String result = phone.sendMessage("王五", "你好");
        System.out.println(result);
    }
}

6.7 对象内存图

对象内存图

内存说明:

  • 栈内存:存储局部变量和方法调用
  • 堆内存:存储对象实例

七、常见面试题

7.1 方法相关面试题

⭐ 题目1:方法重载的条件是什么?

答案: 方法重载需要满足以下条件:

  1. 在同一个类中
  2. 方法名相同
  3. 参数列表不同(参数个数、参数类型、参数类型顺序)

与重载无关的因素:

  • 参数名
  • 返回值类型
  • 修饰符

⭐⭐ 题目2:基本类型和引用类型作为参数传递有什么区别?

答案:

类型传递内容形参修改是否影响实参
基本类型数据值副本❌ 不影响
引用类型地址值✅ 影响(修改同一对象)

示例:

java
// 基本类型
int a = 10;
method(a);  // 传递的是10的副本
System.out.println(a);  // 仍然是10

// 引用类型
int[] arr = {1, 2, 3};
method(arr);  // 传递的是数组地址
System.out.println(arr[0]);  // 可能已被修改

⭐⭐ 题目3:可变参数有哪些特点?

答案:

  1. 格式:数据类型... 变量名
  2. 本质是数组
  3. 参数列表中只能有一个可变参数
  4. 可变参数必须放在参数列表的最后

示例:

java
// 正确
public static void sum(int a, int... arr) { }

// 错误:可变参数不在最后
public static void sum(int... arr, int a) { }

// 错误:多个可变参数
public static void sum(int... arr1, int... arr2) { }

⭐⭐⭐ 题目4:递归的注意事项有哪些?什么情况下会出现栈内存溢出?

答案:

注意事项:

  1. 递归必须有出口(终止条件)
  2. 递归次数不能太多

栈内存溢出的情况:

  1. 无出口的无限递归
  2. 递归层次太深(即使有出口)

示例:

java
// 无出口 -> 栈溢出
public static void method() {
    method();
}

// 递归太深 -> 栈溢出
public static void method(int n) {
    if (n == 1) return;
    method(n - 1);
}
method(Integer.MAX_VALUE);  // 层次太深

7.2 面向对象相关面试题

⭐ 题目5:面向对象的三大特征是什么?

答案:

  1. 封装:隐藏实现细节,提供公共访问方式
  2. 继承:子类继承父类的属性和行为,实现代码复用
  3. 多态:同一行为具有多个不同表现形式

⭐ 题目6:类和对象的关系是什么?

答案:

  • :一类事物的抽象表示形式,是模板
  • 对象:一类事物的具体体现,是实例

关系: 类是对象的模板,对象是类的实例


⭐⭐ 题目7:成员变量和局部变量有什么区别?

答案:

对比项成员变量局部变量
定义位置类中方法外方法内或方法参数
作用范围整个类当前方法
默认值有默认值无默认值,必须初始化
内存位置堆内存栈内存

⭐⭐ 题目8:成员变量的默认值分别是什么?

答案:

数据类型默认值
byte, short, int, long0
float, double0.0
char'\u0000'
booleanfalse
引用类型(类、数组、接口)null

八、经典练习题

8.1 方法练习题

练习1:判断奇偶性(基础)

需求: 键盘录入一个整数,判断奇偶性,返回"偶数"或"奇数"

java
public static String checkOddEven(int num) {
    if (num % 2 == 0) {
        return "偶数";
    } else {
        return "奇数";
    }
}

练习2:求1-100的和(基础)

需求: 计算1到100的和并返回

java
public static int sum() {
    int sum = 0;
    for (int i = 1; i <= 100; i++) {
        sum += i;
    }
    return sum;  // 5050
}

练习3:不定次数打印(基础)

需求: 传入一个整数n,打印n次指定内容

java
public static void print(int n) {
    for (int i = 0; i < n; i++) {
        System.out.println("Hello Java!");
    }
}

练习4:遍历数组(进阶)

需求: 将数组传递到方法中遍历输出

java
public static void printArray(int[] arr) {
    System.out.print("[");
    for (int i = 0; i < arr.length; i++) {
        if (i == arr.length - 1) {
            System.out.print(arr[i] + "]");
        } else {
            System.out.print(arr[i] + ", ");
        }
    }
}

练习5:求数组最大值(进阶)

需求: 获取数组最大值并返回

java
public static int getMax(int[] arr) {
    int max = arr[0];
    for (int i = 1; i < arr.length; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    return max;
}

练习6:数组作为返回值(进阶)

需求: 传入两个整数,返回它们的和与差

java
public static int[] calculate(int a, int b) {
    int sum = a + b;
    int sub = a - b;
    int[] result = {sum, sub};
    return result;
}

8.2 递归练习题

练习7:用递归输出n到1

java
public static void printN(int n) {
    if (n == 0) {
        return;
    }
    System.out.println(n);
    printN(n - 1);
}

练习8:用递归求n的阶乘

java
public static int factorial(int n) {
    if (n == 1) {
        return 1;
    }
    return n * factorial(n - 1);
}

练习9:斐波那契数列第n项

java
public static int fibonacci(int n) {
    if (n == 1 || n == 2) {
        return 1;
    }
    return fibonacci(n - 1) + fibonacci(n - 2);
}

8.3 面向对象练习题

练习10:定义学生类

需求: 定义一个学生类,包含姓名、年龄、成绩属性,以及学习、考试方法

java
public class Student {
    String name;
    int age;
    double score;
    
    public void study() {
        System.out.println(name + "正在学习");
    }
    
    public void exam() {
        System.out.println(name + "正在考试,成绩是:" + score);
    }
}

// 测试
Student s = new Student();
s.name = "张三";
s.age = 18;
s.score = 95.5;
s.study();
s.exam();

九、学习建议

9.1 方法学习建议

  1. 理解方法的作用:方法是功能模块,一个方法只做一件事
  2. 掌握参数传递:区分基本类型和引用类型的传递机制
  3. 灵活使用重载:功能相似但参数不同时使用重载
  4. 谨慎使用递归:必须有出口,层次不能太深

9.2 面向对象学习建议

  1. 理解类与对象的关系:类是模板,对象是实例
  2. 掌握实体类的定义:属性(成员变量)+ 行为(成员方法)
  3. 熟悉对象的使用:创建对象、访问属性、调用方法
  4. 理解内存模型:栈内存与堆内存的区别

9.3 面试准备重点

知识点重要程度复习建议
方法重载⭐⭐⭐记住三个条件,能判断是否构成重载
参数传递⭐⭐⭐理解值传递的本质,能画内存图
可变参数⭐⭐记住格式和三个特点
递归⭐⭐理解出口的重要性,能写简单递归
面向对象三大特征⭐⭐⭐能说出并简单解释
成员变量默认值⭐⭐记住各类型的默认值

9.4 下一章预告

[基于课程进度补充] 下一章将学习:

  • 封装的深入理解
  • 构造方法
  • this关键字
  • 标准类制作

知识图谱

Java方法与面向对象
├── 方法高级特性
│   ├── 参数传递机制
│   │   ├── 基本类型:值传递
│   │   └── 引用类型:地址传递
│   ├── 方法重载
│   │   ├── 参数个数不同
│   │   ├── 参数类型不同
│   │   └── 参数顺序不同
│   ├── 可变参数
│   │   ├── 格式:数据类型... 变量名
│   │   ├── 本质是数组
│   │   └── 必须放最后
│   └── 递归
│       ├── 必须有出口
│       └── 层次不能太深
└── 面向对象入门
    ├── 三大特征
    │   ├── 封装
    │   ├── 继承
    │   └── 多态
    ├── 类
    │   ├── 成员变量(属性)
    │   └── 成员方法(行为)
    └── 对象
        ├── 创建:new 类名()
        └── 使用:对象名.成员名