自学内容网 自学内容网

java继承和多态

一、java继承

1. 定义

继承是指一个类(子类 / 派生类)可以继承另一个类(父类 / 基类)的属性和方法,并并可以在此基础上新增添属性、方法或重写父类方法。

目的:实现代码复用,建立类之间的层级关系。

2. 语法

通过extends关键字实现继承:

// 父类
class Parent {
    String name;
    void printName() {
        System.out.println("Name: " + name);
    }
}

// 子类继承父类
class Child extends Parent {
    int age; // 新增属性
    void printAge() { // 新增方法
        System.out.println("Age: " + age);
    }
    // 重写父类方法(可选)
    @Override
    void printName() {
        System.out.println("Child Name: " + name);
    }
}
3.内存形式:

animal为父类,cat和dog分别为其子类,创建子类对象之前要创建父类对象

4. 核心特性
  • 单继承:Java 中类只能直接继承一个父类(避免多继承的复杂性),但可通过接口实现多继承效果。
  • 传递性:若B继承AC继承B,则C间接继承A的成员。
  • 访问控制:父类的private成员无法被子类继承;protected成员可被子类访问(即使不同包);public成员完全开放。
  • super关键字:子类中通过super调用父类的构造方法、属性或方法(如super.printName())。
5.this的作用

this是一个引用,指向当前对象(即当前正在执行方法的对象实例),主要用于以下场景:

1.区分成员变量和局部变量

当方法的局部变量与类的成员变量同名时,用this明确指代成员变量。

class Person {
    private String name;
    public void setName(String name) {
        this.name = name; // this.name指代成员变量,name指代局部变量
    }
}
2.调用当前类的构造方法

在构造方法中通过this(参数)调用本类的其他构造方法(需放在构造方法第一行)

class Person {
    private String name;
    private int age;
    public Person() {
        this("默认名称", 18); // 调用带参构造方法
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
6.static的作用

思路如下:

static用于修饰类的成员(变量、方法、代码块、内部类),表示该成员属于类本身,而非类的实例(对象),主要作用如下:

1.修饰变量(静态变量 / 类变量)
  • 静态变量属于类,所有对象共享该变量的同一份内存空间。
  • 可通过 “类名。变量名” 直接访问,无需创建对象。
  • class Counter {
        static int count = 0; // 静态变量,所有Counter对象共享
        public Counter() {
            count++;
        }
    }
    // 访问方式
    Counter.count = 5; // 直接通过类名访问
    Counter c1 = new Counter();
    Counter c2 = new Counter();
    System.out.println(Counter.count); // 输出2

2.修饰方法(静态方法 / 类方法)
  • 静态方法属于类,可通过 “类名。方法名” 直接调用,无需创建对象。
  • 静态方法中不能直接访问非静态成员(因为非静态成员属于对象,静态方法调用时可能无对象存在)。
class MathUtil {
    static int add(int a, int b) { // 静态方法
        return a + b;
    }
}
// 调用方式
int result = MathUtil.add(3, 5); // 直接通过类名调用
3.修饰代码块(静态代码块)

静态代码块在类加载时执行一次,常用于初始化静态变量或执行类级别的初始化逻辑。

class Config {
    static {
        System.out.println("类加载时执行,仅一次");
    }
}
7. 构造方法的继承规则
  • 子类构造方法默认会先调用父类的无参构造方法(通过super()实现)。
  • 若父类没有无参构造方法,子类必须在构造方法中显式调用父类的有参构造方法(否则编译报错)。

二、多态(Polymorphism)

1. 定义

多态是指同一行为在不同对象上表现出不同的形态。具体来说,父类引用可以指向子类对象,且调用方法时会根据实际对象类型执行对应子类的实现。目的:解耦代码,提高扩展性(新增子类时无需修改原有代码)。

2. 实现条件
  • 继承:存在父类与子类的继承关系。
  • 重写:子类重写了父类的方法。
  • 向上转型:父类引用指向子类对象(如Parent p = new Child();)。
3. 示例代码
// 父类
class Animal {
    void makeSound() {
        System.out.println("动物发出声音");
    }
}

// 子类1
class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("狗叫:汪汪");
    }
}

// 子类2
class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("猫叫:喵喵");
    }
}

// 测试类
public class Test {
    public static void main(String[] args) {
        Animal animal1 = new Dog(); // 向上转型:父类引用指向Dog对象
        Animal animal2 = new Cat(); // 向上转型:父类引用指向Cat对象
        
        animal1.makeSound(); // 输出"狗叫:汪汪"(实际调用Dog的方法)
        animal2.makeSound(); // 输出"猫叫:喵喵"(实际调用Cat的方法)
    }
}

解析:尽管animal1animal2都是Animal类型的引用,但调用makeSound()时,会根据实际指向的对象(DogCat)执行对应的重写方法,体现了多态。

4. 多态的优势
  • 灵活性:同一方法调用可适配不同对象,无需为每个子类编写单独逻辑。
  • 可扩展性:新增子类(如Bird)并实现makeSound()后,无需修改Test类的代码即可直接使用。
  • 简化代码:通过父类引用统一管理不同子类对象(如集合中存储Animal类型,实际可放DogCat等)。
5. 多态的局限
  • 父类引用只能调用父类中声明的方法(包括子类重写的方法),无法直接调用子类特有的方法(需向下转型,如Dog dog = (Dog) animal1;)。
  • 向下转型有风险:若父类引用指向的实际对象类型与转型目标不符,会抛出ClassCastException(建议先用instanceof判断)。

三、继承与多态的关系

  • 继承是多态的基础:没有继承关系,就无法实现父类引用指向子类对象的多态场景。
  • 多态是继承的延伸:继承解决了代码复用,而多态通过重写和动态绑定,让继承体系更灵活。

总结

  • 继承:通过extends实现类的层级复用,子类可扩展或修改父类功能,核心是 “is-a” 关系(如Dog is an Animal)。
  • 多态:基于继承和重写,允许父类引用适配不同子类对象,核心是 “同一行为的不同实现”,体现了面向对象的 “开闭原则”(对扩展开放,对修改关闭)。

两者结合使用,可大幅提升 Java 代码的复用性、可读性和可维护性。


原文地址:https://blog.csdn.net/2301_79783364/article/details/154315906

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!