public class Test {
public static void main(String[] args) {
// 普通对象创建
Cat cat = new Cat();
cat.run(); // 调用子类重写后的方法
cat.name = "小猫";
cat.eat();
cat.fly();
// 多态的体现:父类的引用指向子类对象
Animal animalCat = new Cat(); // 多态
animalCat.run(); // 实际调用子类重写的方法
animalCat.eat(); // 实际调用子类重写的方法
// animalCat.fly(); // 编译错误:父类引用不能调用子类特有方法
}
}
3.2 方法重写(Override)
public class Cat extends Animal {
// 方法重写:子类与父类方法名相同,参数相同,返回值相同
@Override
public void run() {
System.out.println("猫会轻盈地跑");
}
// 子类特有方法
public void fly() {
System.out.println("猫不会飞,但这是子类特有方法");
}
}
重写规则:方法名、参数列表、返回值类型必须相同访问权限不能比父类更严格当子类对象调用方法时,默认调用重写后的方法四、深入多态:方法调用的奥秘4.1 复杂多态场景分析
package com.gcby.hhh;
public class A {
public String show(B obj) {
return "A and B";
}
public String show(A obj) {
return "A and A";
}
}
public class B extends A {
public String show(Object obj) {
return "B and B";
}
@Override
public String show(A obj) {
return "B and A";
}
}
public class C extends B {}
public class D extends B {}
4.2 多态方法调用测试
public class Test {
public static void main(String[] args) {
A a1 = new A();
A a2 = new B(); // 多态:父类引用指向子类对象
B b = new B();
C c = new C();
D d = new D();
// 测试用例分析
System.out.println("1---" + a1.show(b)); // A and B
System.out.println("2---" + a1.show(c)); // A and B
System.out.println("3---" + a1.show(d)); // A and B
System.out.println("4---" + a2.show(b)); // B and A
System.out.println("5---" + a2.show(c)); // B and A
System.out.println("6---" + a2.show(d)); // A and B
System.out.println("7---" + b.show(b)); // B and A
System.out.println("8---" + b.show(c)); // B and A
System.out.println("9---" + b.show(d)); // B and B
}
}
4.3 多态方法调用解析调用规则总结:创建对象看前面:决定可用方法范围方法匹配看参数:寻找最匹配的方法签名向上转型机制:当找不到完全匹配时,向父类转型寻找详细解析:第7行 b.show(b):入参类型为B,当前对象b(类型为B)的可用方法:show(Object)、show(A)、show(B)没有完全匹配的show(B),考虑向上转型:B的父类是A匹配到show(A obj),输出"B and A"第8行 b.show(c):入参类型为C,可用方法中没有show(C)向上转型:C→B→A,匹配到show(A obj),输出"B and A"第9行 b.show(d):入参类型为D,可用方法中有show(Object obj)(因为D继承自B,而B继承自A,最终继承Object)直接匹配show(Object obj),输出"B and B"五、内存模型深度解析5.1 对象内存布局Animal对象内存布局:
name color age sex
0x2 0x3 0x4 0x5
Cat对象内存布局(继承Animal):
name color age sex [特有字段]
0x2 0x3 0x4 0x5
方法表:
Animal: run0() eat0()
Cat: run0() eat0() fly0()
5.2 多态的内存实现
引用变量:animalCat 0xbc
实际对象:Cat对象 0xac
方法调用过程:
1. animalCat.run() → 查找Cat类的方法表
2. 找到重写的run()方法
3. 执行子类实现
六、接口(Interface)的补充虽然本文主要讨论三大特性,但接口作为Java面向对象的重要组成部分,值得简要提及:接口定义行为规范:只定义方法签名,不提供实现实现多继承:类可以实现多个接口解耦合:分离定义与实现,提高代码灵活性七、实践建议7.1 继承使用原则优先使用组合而非继承遵循里氏替换原则避免过深的继承层次7.2 多态应用场景框架设计插件架构算法策略模式7.3 封装最佳实践成员变量尽量私有提供公共的getter/setter方法方法按需设置访问权限结语面向对象的三大特性——封装、继承、多态,构成了Java编程的基石。通过本文的详细解析,相信你对这些概念有了更深入的理解。记住,理论知识需要通过实际项目来巩固,多编码、多思考、多总结,才能真正掌握面向对象编程的精髓。