在面向对象编程中,继承是一种重要的概念,它允许我们创建一个新类,从现有的类中继承属性和方法。通过继承,我们可以实现代码的重用和扩展,构建更加灵活和可维护的代码结构。本文将深入探讨继承关系中的代码块执行顺序、protected关键字的应用、继承方式的限制以及final关键字的作用,帮助您更好地理解和应用继承在Java中的特性和规则。
在没有继承关系的时候:
有继承关系时:
// extend01包中
public class B {
private int a;
protected int b;
public int c;
int d;
} // extend01包中
// 同一个包中的子类
public class D extends B{
public void method(){
// super.a = 10; // 编译报错,父类private成员在相同包子类中不可见
super.b = 20; // 父类中protected成员在相同包子类中可以直接访问
super.c = 30; // 父类中public成员在相同包子类中可以直接访问
super.d = 40; // 父类中默认访问权限修饰的成员在相同包子类中可以直接访问
}
} // extend02包中
// 不同包中的子类
public class C extends B {
public void method(){
// super.a = 10; // 编译报错,父类中private成员在不同包子类中不可见
super.b = 20; // 父类中protected修饰的成员在不同包子类中可以直接访问
super.c = 30; // 父类中public修饰的成员在不同包子类中可以直接访问
//super.d = 40; // 父类中默认访问权限修饰的成员在不同包子类中不能直接访问
}
} // extend02包中
// 不同包中的类
public class TestC {
public static void main(String[] args) {
C c = new C();
c.method();
// System.out.println(c.a); // 编译报错,父类中private成员在不同包其他类中不可见
// System.out.println(c.b); // 父类中protected成员在不同包其他类中不能直接访问
System.out.println(c.c); // 父类中public成员在不同包其他类中可以直接访问
// System.out.println(c.d); // 父类中默认访问权限修饰的成员在不同包其他类中不能直接访问
}
}
父类中private成员变量虽然在子类中不能直接访问,但是也继承到子类中了。
一般来说希望类要尽量做到 “封装”, 即隐藏内部实现细节, 只暴露出必要的信息给类的调用者,因此我们在使用的时候应该尽可能的使用 比较严格的访问权限,例如如果一个方法能用 private, 就尽量不要用 public。
简单粗暴的做法: 将所有的字段设为 private, 将所有的方法设为 public。但是这种方式属于是
对访问权限的滥用。 写代码的时候还是要认真思考, 该类提供的字段方法到底给 “谁” 使用(是类内部自己用, 还是类的调用者使用, 还是子类使用)
Java中不支持多继承
我们写的类是现实事物的抽象,一般来说真正在公司中所遇到的项目往往业务比较复杂, 可能会涉及到一系列复杂的概念,都需要我们使用代码来表示, 所以我们真实项目中所写的类也会有很多,类之间的关系也会更加复杂,但是即使如此, 并不希望类之间的继承层次太复杂. 一般不希望出现超过三层的继承关系,如果继承层次太多,就需要考虑对代码进行重构了,如果想从语法上进行限制继承, 就可以使用 final 关键字。
final关键可以用来修饰变量、成员方法以及类:
和继承类似, 组合也是一种表达类之间关系的方式, 也是能够达到代码重用的效果。组合并没有涉及到特殊的语法(诸如 extends 这样的关键字),仅仅是将一个类的实例作为另外一个类的字段。
继承表示对象之间是is-a的关系,比如:狗是动物,猫是动物
组合表示对象之间是has-a的关系,比如:汽车,汽车和其轮胎、发动机、方向盘、车载系统等的关系就应该是组合,因为汽车是有这些部件组成的
组合是一种将多个类组合成一个更大的类的方式。在组合关系中,一个类(容器类)包含另一个类(成员类)的实例作为它的成员变量。通过组合,容器类可以使用成员类的属性和方法,并且可以对成员类进行更多的封装和控制。组合使用成员变量来实现。
class Engine {
void start() {
System.out.println("Engine is starting");
}
}
class Car {
private Engine engine;
Car() {
engine = new Engine();
}
void start() {
engine.start();
System.out.println("Car is starting");
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car();
car.start(); // 输出:Engine is starting,Car is starting
}
}
通过了解了在Java中继承关系中代码块的执行顺序、protected关键字的使用方法、继承方式的限制以及final关键字的作用。掌握这些知识将有助于您设计出更加清晰、灵活和易于维护的类结构,提高代码的可读性和可扩展性。