Java 基础(七)多态

Java核心知识点完整笔记:包装类、值传递与多态实战

本文为Java面向对象核心知识点学习笔记,从基础的包装类比较、值传递机制,到多态入门示例,最后深入多态核心实战(重载+重写+向上转型),通过完整代码示例拆解每一个执行细节,彻底搞懂Java面向对象的核心逻辑。


一、Java基础核心:包装类与值传递

1. 包装类:== 与 equals 的使用规则

核心区别
  • 基本类型(如int):存储的是值,== 直接比较值是否相等;
  • 包装类型(如Integer):是对象,== 比较内存地址,equals 重写后比较值。
完整代码示例(Main3.java)
java 复制代码
package test;

public class Main3 {
    public static void main(String[] args) {
        int a=10;
        int b=10;
        Integer a1=10;
        Integer b1=10;
        Integer a2 = new Integer(10);
        Integer b2 = new Integer(10);
        
        // 1. 基本类型==:值相等则为true
        System.out.println(a==b);//T
        
        // 2. 包装类自动装箱(-128~127):复用常量池对象,地址相同
        System.out.println(a1==b1);//T
        
        // 3. new创建包装类:强制新建对象,地址不同
        System.out.println(a2==b2);//F
        
        // 4. 包装类与基本类型==:自动拆箱,比较值
        System.out.println(a1==a);//T
        System.out.println(a==a2);//T
        
        // 5. equals比较:自动拆箱,比较值
        System.out.println(a1.equals(a));//T
        
        // 6. 常量池对象 vs new对象:地址不同
        System.out.println(a1==a2);//F
    }
}
核心结论
  • Integer 直接赋值(Integer a1=10):-128~127范围内复用常量池对象,超出则新建;
  • new Integer(10):每次创建新对象,即使值相同,地址也不同;
  • 推荐:包装类比较值统一用equals,避免地址比较的坑。

2. Java的值传递机制

核心定义

Java中只有值传递

  • 基本类型:传递值的副本,方法内修改副本不影响原变量;
  • 引用类型:传递地址的副本,修改副本的指向(如new新对象)不影响原引用,修改对象内容会影响原对象。
完整代码示例(Pig.java)
java 复制代码
package DuoTai;

import java.util.Arrays;

public class Pig {
    static int[] arr = new int[3];
    static int[] brr = new int[3];
    
    public static void main(String[] args) {
        // 1. 基本类型值传递
        int a = 10;
        int b = 15;
        System.out.println("a="+a); // 输出10
        a = IntChange(a, b); // 需接收返回值才能改变原变量
        System.out.println("a="+a); // 输出15

        // 2. 数组(引用类型)值传递
        Pig pig = new Pig();
        arr = pig.IntArrChange(arr,brr);
        System.out.println(Arrays.toString(arr)); // 输出[0, 0, 1]
        System.out.println(Arrays.toString(brr)); // 输出[0, 0, 0]
    }
    
    // 基本类型参数:修改副本,需return返回结果
    public static int IntChange(int a,int b) {
        a = b;
        return a;
    }
    
    // 引用类型参数:修改地址副本不影响原引用,需return返回新地址
    public static int[] IntArrChange(int[] arr,int[] brr) {
        // 重新赋值arr/brr:修改的是地址副本,与原数组无关
        arr = new int[3];
        brr = new int[3];
        
        // 修改新数组的内容
        arr[0] = 1;
        brr[2] = 1;
        
        // 让arr指向brr的新数组地址
        arr = brr;
        return arr;
    }
}
核心结论
  • 基本类型参数:方法内修改不会影响原变量,必须通过return返回结果;
  • 引用类型参数:仅修改参数的指向(如arr = new int[3]),原引用不受影响;修改对象的内容(如arr[0] = 1),原对象会被改变。

二、多态基础入门:向上转型与方法重写

1. 多态的定义

多态核心是「父类引用指向子类对象」(子类向上转型),前提是:

  • 存在继承关系;
  • 子类重写父类方法。

2. 完整代码示例

父类:Animal.java
java 复制代码
package DuoTai;

public class Animal {
    public void eat(){
        System.out.println("吃");
    }
}
子类:Cat.java(重写父类方法)
java 复制代码
package DuoTai;

public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("吃东西");
    }
}
测试类:Main.java
java 复制代码
package DuoTai;
//多态指的是父类引用指向子类对象
//子类的向上转型
public class Main {
    public static void main(String[] args) {
        // 1. 父类对象调用父类方法
        Animal animal = new Animal();
        animal.eat(); // 输出:吃
        
        // 2. 子类对象调用子类方法
        Cat cat = new Cat();
        cat.eat(); // 输出:吃东西
        
        // 3. 多态:父类引用指向子类对象,执行子类重写的方法
        Animal Catanimal = new Cat();
        Catanimal.eat(); // 输出:吃东西
    }
}

3. 核心结论

  • 多态下,父类引用只能调用父类定义的方法,但执行的是子类重写后的逻辑;
  • 子类向上转型是自动的,无需手动转换;
  • 作用:屏蔽不同子类的实现差异,统一通过父类接口调用,提高代码扩展性。

三、多态核心实战:重载+重写+向上转型匹配规则

1. 类继承结构说明

  • 顶层父类:A
  • 子类B:继承A,新增重载方法、重写父类方法
  • 子类CD:继承B
  • 测试类:Test,包含9条核心输出语句

2. 完整类代码

A.java
java 复制代码
public class A {
    // 方法1:参数为D类型
    public String Show(D obj) {
        return "A and D";
    }

    // 方法2:参数为A类型
    public String Show(A obj) {
        return "A and A";
    }
}
B.java(继承A)
java 复制代码
public class B extends A {
    // 自身新增的重载方法:参数为Object类型
    public String Show(Object obj) {
        return "B and B";
    }

    // 重写父类A的Show(A obj)方法
    @Override
    public String Show(A obj) {
        return "B and A";
    }
}
C.java(继承B)
java 复制代码
public class C extends B {
    // 无自定义方法,继承B的所有方法
}
D.java(继承B)
java 复制代码
public class D extends B {
    // 无自定义方法,继承B的所有方法
}
Test.java(测试主类)
java 复制代码
public class Test {
    public static void main(String[] args) {
        // 初始化对象
        A a1 = new A();
        B b = new B();
        C c = new C();
        D d = new D();

        // 多态核心:父类引用A,指向子类对象B
        A a2 = new B();

        // 第一组:A类引用a1(指向A对象)调用
        System.out.println("1---"+a1.Show(b));
        System.out.println("2---"+a1.Show(c));
        System.out.println("3---"+a1.Show(d));

        // 第二组:B类引用b(指向B对象)调用
        System.out.println("4---"+b.Show(b));
        System.out.println("5---"+b.Show(c));
        System.out.println("6---"+b.Show(d));

        // 第三组:A类引用a2(指向B对象,多态)调用
        System.out.println("4---"+a2.Show(b));
        System.out.println("5---"+a2.Show(c));
        System.out.println("6---"+a2.Show(d));
    }
}

3. 完整运行结果

复制代码
1---A and A
2---A and A
3---A and D
4---B and A
5---B and A
6---A and D
4---B and A
5---B and A
6---A and D

4. 核心前置规则

所有执行结果都围绕这3个核心规则:

  1. 编译期:看「引用类型」
    编译器只检查引用变量的类型中是否存在对应的方法签名;方法参数匹配优先级:精准类型 > 直接父类 > 间接父类 > Object,不会跳级匹配。
  2. 运行期:看「实际对象类型」
    JVM执行实际创建的对象中的方法:子类重写了父类方法,优先执行子类逻辑;未重写则执行继承自父类的逻辑。
  3. 重写 vs 重载
    • 重写(Override):父子类中方法名、参数列表、返回值完全一致,子类覆盖父类,是多态的核心;
    • 重载(Overload):同一个类中方法名相同,参数列表不同,编译期就确定调用的方法。

5. 逐行拆解执行过程

第一组:a1调用(A类引用,指向A对象)
  1. a1.Show(b):参数b是B类型,向上转型为A,匹配Show(A obj),执行A类方法,输出1---A and A
  2. a1.Show(c):参数c是C类型,向上转型为A,匹配Show(A obj),输出2---A and A
  3. a1.Show(d):参数d是D类型,精准匹配Show(D obj),输出3---A and D
第二组:b调用(B类引用,指向B对象)
  1. b.Show(b):参数b是B类型,向上转型为A,匹配B重写的Show(A obj),输出4---B and A
  2. b.Show(c):参数c是C类型,向上转型为A,匹配B重写的Show(A obj),输出5---B and A
  3. b.Show(d):参数d是D类型,精准匹配继承自A的Show(D obj)(未重写),输出6---A and D
第三组:a2调用(A类引用,指向B对象,多态核心)
  1. a2.Show(b):编译期匹配A类的Show(A obj),运行期执行B重写的逻辑,输出4---B and A
  2. a2.Show(c):编译期匹配A类的Show(A obj),运行期执行B重写的逻辑,输出5---B and A
  3. a2.Show(d):编译期匹配A类的Show(D obj),运行期执行继承自A的逻辑,输出6---A and D

四、最终完整知识点总结

  1. 包装类 :比较值用equals,注意自动装箱的常量池复用(-128~127);
  2. 值传递:Java只有值传递,基本类型修改副本不影响原变量,引用类型修改对象内容会影响原对象;
  3. 多态基础:父类引用指向子类对象,执行子类重写的方法;
  4. 多态核心口诀编译看左,运行看右------编译期由引用类型决定能调用哪些方法,运行期由实际对象类型决定执行哪个类的逻辑;
  5. 重载匹配:优先精准类型,再向上找最近父类,不会跳级匹配。
相关推荐
不知名的老吴2 小时前
一文读懂:单例模式的经典案例分析
java·开发语言·单例模式
欧米欧2 小时前
C++算法之双指针算法
开发语言·c++
天天进步20152 小时前
Python全栈项目实战:自建高效多媒体处理工具
开发语言·python
yaoxin5211232 小时前
388. Java IO API - 处理事件
java·服务器·数据库
JAVA学习通2 小时前
AI 工作流编排系统的任务拆分、重试与观测:2026年工程实践深度解析
java·人工智能·spring
zzzsde2 小时前
【Linux】线程概念与控制(1)线程基础与分页式存储管理
linux·运维·服务器·开发语言·算法
waterHBO2 小时前
python + fast-wahisper 读取麦克风,实现语音转录,而且是实时转录。
开发语言·python
凤山老林2 小时前
27-Java final 关键字
java·开发语言
少许极端2 小时前
算法奇妙屋(四十九)-贡献法
java·算法·leetcode·贡献法