【Java SE】继承:代码复用与扩展的艺术-CSDN博客文章浏览阅读389次,点赞16次,收藏12次。摘要:继承是面向对象编程的核心特性,允许子类复用父类的属性和方法并扩展新功能。子类通过extends继承父类,可访问父类成员(同名时遵循就近原则),使用super关键字可调用父类同名成员。继承体现了代码复用和层次化设计,子类必须添加特有功能以区别于父类。语法上需注意成员访问优先顺序(子类优先)和super的使用限制(仅非静态方法)。通过继承关系可构建更复杂的类层次结构。https://blog.csdn.net/Boop_wu/article/details/148700233
子类构造对象时,需要先调用父类构造方法,然后执行子类的构造方法
public class Test {
public static void main(String[] args) {
Derived d = new Derived();
}
}
public class Base {
public Base(){
System.out.println("Base()");
}
}
public class Derived extends Base {
public Derived(){
//super();
System.out.println("Derived()");
}
}
在子类构造方法中,并没有写任何关于父类构造的代码,但是在构造子类对象是,先执行父类的构造方法,然后执行子类的构造方法,因为:子类对象中成员是有两部分组成的,父类继承下来的以及新增的部分。在构造对象时,要先调用父类的构造方法,将从父类继承下来的成员构造完整,然后再调用子类的构造方法,将子类自己新增的成员初始化完整。
注意:
相同点:
①都是java中的关键字
②只能在类的非静态方法中使用,用来访问非静态成员方法和字段
③在构造方法中调用,必须是构造方法中的第一条语句,并且不能同时存在
不同点:
①this 是当前对象的引用,当前对象即调用实例方法;super 相当于是子类对象中从父类继承下来部分成员的引用
②在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性
③在构造方法中:this(....)用于调用本类构造方法,super(...)用于调用父类的构造方法,两种调用不能同时在构造方法中出现
④构造方法中一定会存在super(..)调用,用户没有写编译器也会增加,但是this(..)用户不写就没有。
①静态代码块先执行,并且在类加载阶段只执行一次
②当有对象创建时,才会执行实例代码块,再执行构造代码块
①父类静态代码块优先与子类静态代码块执行,并且是最早的
②父类实例代码块和父类构造方法紧接着执行
③子类的实例代码块和子类构造方法紧接着再执行
④第二次实例化对象时,父类和子类的静态代码块都不会再执行
作用:protected
成员可以被同一包内的其他类访问,也可以被不同包中的子类访问。
实例如下:
package d1;
public class B {
private int a;
protected int b;
int c;
public int d;
}
package d1;
public class D extends B{
public void method(){
//super.a = 10;
super.b = 20;
super.c = 30;
super.d = 40;
}
}
package d2;
import d1.B;
public class C extends B {
public void method(){
//super.a = 10;
super.b = 20;
//super.c = 30;
super.d = 40;
}
}
Java通过extends
关键字实现单继承,即一个子类只能直接继承一个父类。继承允许子类复用父类的属性和方法,并可以扩展或修改父类的行为。
class ParentClass {
// 父类成员
}
class ChildClass extends ParentClass {
// 子类成员
}
①单继承
Java不支持多继承(一个子类继承多个父类),但可以通过接口(implements
)实现多重继承的效果。
②多层继承
子类可以进一步被其他类继承,形成继承链。
class Grandparent {}
class Parent extends Grandparent {}
class Child extends Parent {}
③方法重写(Override)
子类可以重写父类的方法,使用@Override
注解确保逻辑正确。
class Parent {
void display() {
System.out.println("Parent method");
}
}
class Child extends Parent {
@Override
void display() {
System.out.println("Child method");
}
}
protected
成员:子类可以访问父类的protected
成员。private
成员:子类无法直接访问父类的private
成员,需通过公有方法间接访问。在Java中,final
关键字用于修饰变量、方法或类,表示不可更改的语义。具体作用取决于修饰的目标:
①基本类型变量:值不可修改。
final int x = 10;
// x = 20; // 编译错误,无法重新赋值
②引用类型变量:引用地址不可变,但对象内部状态可能可变。
final List list = new ArrayList<>();
list.add("A"); // 允许修改对象内容
// list = new ArrayList<>(); // 编译错误,引用不可变
③类成员变量:必须在声明时或构造方法中初始化。
子类不能重写final
方法,但可以继承调用。
class Parent {
final void display() { System.out.println("Parent"); }
}
class Child extends Parent {
// void display() { } // 编译错误,无法重写
}
final
类不能被继承,例如String
类。
final class MyClass { }
// class SubClass extends MyClass { } // 编译错误
final
仅保证引用或基本值不变,但若对象内部状态可变(如final List
),需结合其他机制(如防御性拷贝)实现完整不可变性。
通过合理使用final
,可以增强代码的安全性、清晰性和可维护性。
继承(Inheritance)是面向对象编程中的一种机制,允许一个类(子类)继承另一个类(父类)的属性和方法。子类可以复用父类的代码,同时扩展或修改父类的行为。
组合(Composition)是一种设计模式,通过将一个类的对象作为另一个类的成员变量来实现代码复用。组合强调“拥有”关系,而非“是”关系。
优点:
代码复用性强,子类可以直接使用父类的属性和方法。
支持多态,父类引用可以指向子类对象。
适合表示“is-a”关系(如“Dog is an Animal”)。
缺点:
破坏封装性,子类依赖父类的实现细节。
父类变更可能影响所有子类。
Java不支持多继承,可能限制灵活性。
// 继承示例
class Animal {
void eat() {
System.out.println("Animal is eating");
}
}
class Dog extends Animal {
void bark() {
System.out.println("Dog is barking");
}
}
优点:
灵活性高,可以动态替换成员对象。
降低耦合,类之间通过接口交互。
适合表示“has-a”关系(如“Car has an Engine”)。
缺点:
需要手动实现部分功能,代码量可能增加。
无法直接利用多态特性。
// 组合示例
class Engine {
void start() {
System.out.println("Engine started");
}
}
class Car {
private Engine engine;
Car(Engine engine) {
this.engine = engine;
}
void start() {
engine.start();
}
}
①优先使用组合:
符合“组合优于继承”的设计原则,尤其是当关系为“has-a”时。
需要动态改变行为时(如通过setter方法替换成员对象)。
②使用继承的场景:
关系明确为“is-a”且逻辑高度一致。
需要利用多态或重写父类方法。
总结:继承和组合各有适用场景。组合通常更灵活且易于维护,适合模块化设计;继承适合建立清晰的层级关系和多态需求。实际开发中应结合具体需求选择。