从基类构造函数创建子类实例

基斯纳

我正在学习Java的OOP。假设我有一个基类Car,它的子类扩展了Car,称为Engine,FuelTank和Wheels。是否可以从Car的基类实例化这些扩展类,以使car的每个实例对每个子类都有自己的实例?

class Car{
      Car(){
          // instance of Engine
          // instance of Wheels
          // instance of FuelTank
      }
 }

class CarPart{}

class Engine extends CarPart{}

class Wheels extends CarPart{}

class FuelTank extends CarPart{}
用户名

您的问题是:

在一个类中,我可以创建其他类的实例吗?

从理论上和技术上,您都可以轻松地获得“是”的答案。但是真正的答案是……“不”。因为,如果您这样做:

  • 你的类紧密耦合,其中被创建的实例(Car)的类从中创建的实例(EngineWheelsFuelTank)。这样,即使可以实施仅采用电力的解决方案,汽车也将始终必须具有燃油箱。
  • 汽车不仅有责任在道路上行驶,而且还具有自行制造汽车零件的责任。这就是“变形金刚”之类的东西。

但是,如果您想正确学习和应用OOP,那么这两种情况都不是“允许的”选择。就像:在正常的游泳比赛中,您可以使用一副脚蹼,但是您将失去资格。

也就是说,紧密联轴器唯一可行的选择松散联轴器:将汽车零件注入(例如通过),例如插入汽车。在OOP中,此过程具有名称依赖项注入(DI)。然后可以轻松地更改或删除汽车零件-依存关系因此,由于仅用电力驱动汽车,因此可以完全卸下油箱。现在,汽车本身仅具有在道路上行驶的责任。而且,即使它仍然依赖于其零件-确实应该,它也不再关心汽车零件的创建过程:它只是应该接收它们-而应该这样做。

我刚刚意识到,我会使用另一种概念方案:Engine不应为CarPart只有将其插入汽车中的事实才能使其成为汽车的一部分。这同样适用于在WheelsFuelTank简而言之,我将以其他方式定义它们:

class Engine {...}
class Wheels {...}
class FuelTank {...}

class CarEngine extends Engine {...}
class CarWheels extends Wheels {...}
class CarFuelTank extends FuelTank {...}

因此,松散耦合将这样应用:

class Car{

    Car(instance of CarEngine, instance of CarWheels, instance of CarFuelTank){
        //...
    }

}

或者,甚至更好地类似于您的代码版本:

class Car {

    Car(instance of Engine, instance of Wheels, instance of FuelTank){
        //...
    }

}

这里有两个很棒的资源,可以更好地理解这里介绍的原理:

祝您项目顺利!


编辑1:

@Ryan Leach诚恳地建议我也向您介绍factory的概念我将尝试以原则方式进行。

汽车需要引擎才能运行。但是谁能生产这款汽车零件呢?好吧:一家发动机工厂。更确切地说是汽车发动机工厂。

就OOP而言,工厂是专门负责一个职责的类:创建其他类的实例(听起来很熟悉吗?)。然后根据其用途将创建的实例用于其他地方。现在,当工厂创建一个或多个不同类类型的对象时,为了准备最终“产品”的创建,它可能也需要收集/产生其他资源。

因此,在组装/制造最终发动机之前,发动机工厂首先需要收集/生产许多发动机零件。同样适用于汽车制造厂:它需要从发动机制造厂接收发动机,从车轮制造厂接收车轮,从燃油箱工厂接收燃油箱。然后生产最终的汽车。

在OOP中,存在三种类型的工厂,例如所谓的工厂模式

  • 简单工厂
  • 工厂方法
  • 抽象工厂

我不会在这里亲自介绍它们,但会尝试将您引向一些(非常)好的网络资源,这些资源易于理解和理解:

PS:

前两个是我的最爱...虽然我还没有看过它们:-)是的,很傻,不是吗?因为它们是相对较新的上载,所以我不知道它们是否存在。但是:我关注了作者的所有其他内容,并用三个词表示:我印象深刻。注意:作者解释了“ Head First设计模式书中介绍的所有模式

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

子类调用基类构造函数,然后在子类Arduino C ++中使用基类的实例方法

如何使用超类的构造函数创建子类的实例

如何使用超类构造函数创建子类的实例?

从基类的构造函数访问子类的属性

在打字稿中的基类构造函数参数中引用子类的实例类型

如何让子类中的构造函数继承构造函数或基类?

使用基类构造函数的子类构造函数的轮廓定义

为特定的构造函数创建实例类

在子类实例化中使用替代超类构造函数

使用基类构造函数初始化子类

基类中删除的构造函数会影响子类吗?

使用CRTP将基类的子类传递给构造函数?

Javascript基类构造函数以子类(重写)属性运行

从基类结构构造子类

子类的构造函数后跟冒号后的基类构造函数是什么意思?

使用不同的构造函数为不同的类创建实例

通过使用不同的构造函数创建类的实例

使用类名称创建实例并调用构造函数

创建对象实例而不调用超类构造函数

创建具有私有构造函数的类模板的实例

从子类构造函数调用实例方法

创建基类中不存在的构造函数

Selenium-从构造函数创建新对象(基类)

Java如何使用超类构造函数设置子类实例变量

为什么允许使用子类的构造函数实例化父类对象?

编译器在调用基类构造函数之前会在子类构造函数中寻找** super **关键字吗?

如何从基类实例中找出子类?

用于将多态基类的子类数组传递到构造函数中的最简单语法

调用基类构造函数与初始化子类中的成员变量