你好!今天我们来仔细看看面向对象编程(OOP)的另一个原则——继承。同时,我们将研究类之间其他类型的关系——组合和聚合。这个主题并不困难:您在之前的讲座中已经多次遇到过继承及其示例。今天主要是巩固一下知识,仔细看看继承机制,再过一遍例子:)所以,我们走吧!
Java中的继承及其好处
您可能还记得,继承是一种允许您基于现有(父)类描述新类的机制。在这种情况下,新类借用了父类的属性和功能。让我们记住之前讲座中继承的例子:public class Car {
private String model;
private int maxSpeed;
private int yearOfManufacture;
public Car(String model, int maxSpeed, int yearOfManufacture) {
this.model = model;
this.maxSpeed = maxSpeed;
this.yearOfManufacture = yearOfManufacture;
}
public void gas() {
//...gas
}
public void brake() {
//...brake
}
}
public class Truck extends Car {
public Truck(String model, int maxSpeed, int yearOfManufacture) {
super(model, maxSpeed, yearOfManufacture);
}
}
public class Sedan extends Car {
public Sedan(String model, int maxSpeed, int yearOfManufacture) {
super(model, maxSpeed, yearOfManufacture);
}
}
我们有一个特定的程序来处理各种类型的汽车。即使您不是汽车爱好者,您也可能知道世界上有很多类型的相同汽车:)因此,我们将汽车的一般属性分离到一个共同的父类中 - Car
。无论类型如何,所有汽车都有什么共同点?任何汽车都有制造年份、型号名称和最高速度。我们将这些属性放入字段model
, maxSpeed
,中yearOfManufacture
。至于行为,任何汽车都可以加速和制动:)我们在方法gas()
和中定义这种行为brake()
。这给我们带来什么好处呢?首先,减少代码量。当然,我们可以不用父类。但由于每辆车都必须能够加速和制动,因此我们必须gas()
在brake()
class Truck
、 class Sedan
、 class F1Car
、 classSportcar
以及所有其他类别的汽车中创建方法。想象一下在这种情况下我们将编写多少额外的代码。不要忘记 model、maxSpeed 和yearOfManufacture 字段:如果我们放弃父类,我们将在每个机器类中创建它们! 当我们有几十个机器类时,重复代码的数量将变得非常严重。将公共字段和方法(也称为“状态”和“行为”)移至父类中将使我们节省大量时间和空间。如果某种类型具有仅该类型独有的属性或方法,并且其他类型的机器不存在,那么这并不重要。它们始终可以在后代类中创建,与所有其他类分开。
public class F1Car extends Car {
public void pitStop() {
//...only racing cars make pit stops
}
public static void main(String[] args) {
F1Car formula1Car = new F1Car();
formula1Car.gas();
formula1Car.pitStop();
formula1Car.brake();
}
}
以一级方程式赛车为例。与他们的“亲戚”不同,他们有一种独特的行为——时不时地停下来。这并不困扰我们。我们已经描述了父类中的一般行为Car
,我们可以在类中添加子类的特定行为。 这也适用于字段:如果子类具有独特的属性,我们可以在其中平静地声明这些字段而不必担心:)重用代码的能力是继承的主要优点。 对于程序员来说,不要编写不必要的代码非常重要。在工作中你会不止一次遇到这种情况。请记住一件非常重要的事情:Java 中没有多重继承。每个类仅继承自一个类。我们将在以后的讲座中更详细地讨论其原因,但现在请记住。顺便说一下,这就是 Java 与其他一些 OOP 语言的区别。例如,C++ 具有多重继承。通过继承,一切都或多或少变得清晰了——让我们继续前进。
组合和聚合
类和对象可以相互关联。继承描述了“is”(或英语“IS A”)关系。狮子座是一种动物。这种关系可以很容易地使用继承来表达,其中Animal
类是父类,Lion
类是子类。然而,并不是世界上所有的关系都是这样描述的。例如,键盘肯定以某种方式连接到计算机,但它不是计算机。手以某种方式与人联系在一起,但它们不是人。在这些情况下,它基于不同类型的关系:不是“是”,而是“是一部分”(“HAS A”)。手不是人,但却是人的一部分。键盘不是计算机,但它是计算机的一部分。HAS 关系可以使用组合和聚合机制在代码中进行描述。它们之间的区别在于这些联系的“严格性”。让我们举一个简单的例子:我们有我们的Car
——一辆车。每辆车都有发动机。此外,每节车厢内都有乘客。Engine engine
字段和之间的根本区别是什么Passenger [] passengers
?如果汽车内有乘客А
,并不意味着车内不能B
载人C
。一辆车可容纳多名乘客。此外,如果所有乘客都离开车内,车仍会安静地运行。Car
舱位等级和乘客量之间的关系Passenger [] passengers
不太严格。这就是所谓的聚合。关于这个主题有一篇很好的文章:类(对象)之间的关系。它提供了聚合的另一个很好的例子。假设我们有一个班级Student
代表一个学生,还有一个班级StudentsGroup
(一组学生)。学生可以是物理俱乐部、星球大战学生粉丝俱乐部或 KVN 团队的成员。 组合是一种更严格的沟通类型。当使用组合时,一个对象不仅是某个对象的一部分,而且不能属于同一类型的另一个对象。最简单的例子是汽车发动机。发动机是汽车的一部分,但不能是另一辆车的一部分。Car
正如您所看到的,它们的连接比和的连接严格得多Passengers
。
GO TO FULL VERSION