我正在尝试通过以父类型作为参数来初始化父类来创建子类,我想知道如何做到这一点。
例如,说我有以下入门代码:
class Animal{ constructor(settings){ //parent value this.name = settings.name; } //parent function sayName(){ console.log(`My name is ${this.name}.`); } } class Frog extends Animal{ constructor(settings){ super(settings); //child-specific value this.isTreeFrog = settings.isTreeFrog; } //child function livesInTheForest(){ return this.isTreeFrog; } } class Rabbit extends Animal{ [...] } class Whale extends Animal{ [...] }
我想写:
let barry = new Animal({ animalType: "frog", name: "Barry", isTreeFrog: false })
(而不是
let barry = new Frog({name: "Barry", isTreeFrog: false})
)
并且让barry
变成青蛙,这意味着我可以这样写:
barry.sayName() //should print 'My name is Barry' console.log(barry.livesInTheForest()) //should print 'false'
我尝试过的
我尝试了两种不同的方法来实现这一目标,但是两者都有些棘手,不能完全实现我想要的目标。
[首先涉及到在Animal类中有一个值来存储孩子。例如,在Animal
的构造函数中,我可能会有这样的内容:
if(settings.animalType === "frog"){ this.animal = new Frog(settings); }else [...] //other animal types
这有两个主要问题:
barry.animal.livesInTheForest()
,这会导致不一致,因为在没有.animal
的情况下可以调用父函数。Frog
)不能再是子类,否则我将得到太多的递归,因为它一直试图用super()进行调用。我也想到了第二种方法,它的工作方式如下:
在父级(Animal
)构造函数中:
//make sure this isn't being called from the child class if(settings.animalType !== null){ if(settings.animalType === "frog"){ //set settings.animal null to avoid too much recursion //this means that I can't set this.animalType though, so I can't access barry.animalType settings.animalType = null; //Is this something I can do?! this = new Frog(settings); } else [...] //other animal types }
这有效(我认为),但是我现在无法将
this.animalType
设置为settings.animalType
,这意味着我无法写barry.animalType
并获得frog
。另外,这对我来说似乎真的很棘手,我不禁想到必须有更好的方法来做到这一点。
[我正在尝试做的事,我试图通过启动一个以子类型作为参数的父类来创建子(子)类,我想知道如何做到这一点。例如,说我有...
class Animal {
static create (settings) {
return new this.subClasses[settings.type](settings)
}
}
class Rabbit extends Animal {}
class Frog extends Animal {}
class Whale extends Animal {}
Animal.subClasses = { frog: Frog, rabbit: Rabbit, whale: Whale }
const animals = ['frog', 'rabbit', 'whale'].map((type) => Animal.create({ type }))
console.log({ animals })