在Java面向对象编程中,继承是核心特性之一,它允许子类继承父类的属性和方法,从而实现代码复用和功能扩展,创建子类是实现继承的关键步骤,掌握其方法和规则对于构建可维护、可扩展的程序至关重要,本文将详细介绍Java中创建子类的具体操作、核心概念及注意事项。

子类的创建语法
创建子类需要使用extends关键字,语法格式为:
class 子类名 extends 父类名 {
// 子类成员变量和方法
}
父类名是已存在的类,子类名是新定义的类,假设有一个Animal父类,定义Dog子类如下:
class Animal {
void eat() {
System.out.println("动物会吃东西");
}
}
class Dog extends Animal {
void bark() {
System.out.println("狗会叫");
}
}
这里Dog继承了Animal,因此Dog对象可以直接调用Animal的eat()方法,同时也可以定义自己的bark()方法,需要注意的是,Java仅支持单继承,即一个子类只能有一个直接父类,但通过多层继承可以实现类的扩展(如Dog extends Animal extends LivingBeing)。
父类与子类的访问权限
子类继承父类时,并非所有父类成员都能被直接访问,具体取决于成员的修饰符:
-
private成员:父类的private成员(变量、方法)无法被子类直接访问,只能通过父类的公共方法间接调用,若Animal中有private String name,子类Dog不能直接访问name,需通过public的getName()方法获取。 -
protected成员:父类的protected成员可以在子类中直接访问,无论子类是否与父类在同一个包中。class Animal { protected void sleep() { System.out.println("动物在睡觉"); } } class Dog extends Animal { void action() { sleep(); // 直接访问父类的protected方法 } } -
public成员:父类的public成员在子类中完全可见,可直接调用。
-
默认修饰符(包私有):若父类成员无修饰符,则仅在同一包内的子类中可访问。
构造器的继承与调用
子类创建对象时,会先调用父类的构造器,再执行子类的构造器,这是由于子类依赖父类的成员变量初始化,需确保父类先完成初始化,默认情况下,子类构造器会隐式调用父类的无参构造器(super());若父类没有无参构造器,子类必须显式调用父类的带参构造器,否则编译报错。
class Animal {
Animal(String name) {
System.out.println("父类构造器,名字:" + name);
}
}
class Dog extends Animal {
Dog() {
super("旺财"); // 显式调用父类带参构造器
System.out.println("子类构造器");
}
}
执行new Dog()时,输出顺序为:
父类构造器,名字:旺财
子类构造器
若子类构造器未显式调用super(),编译器会自动添加super(),此时若父类无无参构造器,则会报错。
方法重写(Override)
子类可以重新定义父类的方法,称为“方法重写”,重写后,子类对象调用该方法时,执行的是子类的实现而非父类的实现,重写需满足以下规则:
- 方法签名一致:子类方法的方法名、参数列表(参数类型、顺序、个数)必须与父类方法完全相同。
- 返回类型兼容:子类方法的返回类型必须与父类方法返回类型相同或是其子类(协变返回类型,如父类返回
Animal,子类可返回Dog)。 - 访问权限不更严格:子类方法的访问权限不能低于父类(如父类
public,子类不能是protected)。 - 异常声明不更宽泛:子类方法抛出的异常必须是父类方法抛出异常的子类或相同,不能抛出新的异常(父类未声明的 checked 异常除外)。
使用@Override注解可以检查是否正确重写,
class Animal {
void move() {
System.out.println("动物在移动");
}
}
class Dog extends Animal {
@Override
void move() {
System.out.println("狗在跑");
}
}
调用Dog对象的move()方法时,输出“狗在跑”。

super关键字的使用
super用于在子类中访问父类的成员(变量、方法、构造器),主要有以下场景:
-
访问父类成员变量:当子类与父类有同名成员变量时,
super.变量名可访问父类变量。class Animal { String name = "动物"; } class Dog extends Animal { String name = "狗"; void printName() { System.out.println(super.name); // 输出“动物” System.out.println(name); // 输出“狗” } } -
调用父类方法:子类可通过
super.方法名()调用父类被重写的方法。class Dog extends Animal { @Override void move() { super.move(); // 调用父类的move() System.out.println("狗在跑"); } } -
调用父类构造器:如前所述,
super(参数列表)用于在子类构造器中调用父类构造器,且必须位于子类构造器的第一行。
final关键字对继承的影响
final修饰符会限制继承:
- final类:用
final修饰的类不能被继承,如String类。 - final方法:用
final修饰的方法不能被重写,子类无法覆盖该方法。 - final变量:用
final修饰的变量是常量,子类无法修改其值。
继承的注意事项与最佳实践
- 遵循“里氏替换原则”:子类应能替换父类使用,因此子类扩展父类时,不能改变父类原有的核心逻辑(如重写方法时不能违背父类的设计意图)。
- 避免滥用继承:若类之间不是“is-a”(是一个)关系(如“汽车”和“引擎”),应优先使用组合而非继承。
- 构造器调用顺序:先父类后子类”,多层继承时,构造器调用顺序从顶级父类到子类依次执行。
- 合理设计父类:父类应提供稳定、清晰的公共接口,避免子类过度依赖父类的实现细节(降低耦合)。
创建Java子类是实现继承的核心操作,需掌握extends语法、访问权限规则、构造器调用机制、方法重写规范以及super和final关键字的使用,合理利用继承可以提升代码复用性,但需注意遵循面向对象设计原则,避免过度继承或破坏类的封装性,通过理解上述概念和规则,开发者能够构建结构清晰、易于维护的Java程序。



















