OOP:方法返回新实例,子级应该返回什么?

时间:2018-11-13 14:50:47

标签: typescript oop

我正在使用打字稿。我有一个带有方法的类,该方法返回该类的新实例。

class A {
  map (args) {
    return new A(/* change something*/);
  }
}

我继承了A的子类。

class B extends A {
}

我的问题是:在OOP中是否有最佳实践说明map中的B函数应该返回B?还是开发者选择返回AB(即使用方法覆盖)。

1 个答案:

答案 0 :(得分:1)

这里没有最佳实践。这取决于map的功能以及您希望它具有的语义。

要针对流行的map操作,特别考虑一个数据点,例如Array(以及filterslice等)上的数据点:默认情况下, Array中的实现将返回B(您无需进行任何特殊工作)。但是,如果更合理地返回A,则实现可以覆盖该默认行为。

使用Array的默认行为的示例(在JavaScript中,但在TypeScript中的作用相同):

class B extends Array {
}
const b1 = new B("a", "b", "c");
const b2 = b1.map(entry => entry.toUpperCase());
console.log(b2 instanceof Array); // true
console.log(b2 instanceof B);     // true

覆盖数组默认行为的示例(同样,在JS中):

class B extends Array {
    static get [Symbol.species]() {
        return Array;
    }
}
const b1 = new B("a", "b", "c");
const b2 = b1.map(entry => entry.toUpperCase());
console.log(b2 instanceof Array); // true
console.log(b2 instanceof B);     // false

有关其工作原理的更多信息:Symbol.species

Promise对产生新承诺(或映射或集合)的操作执行相同的操作(以及MapSet),因此您可以说存在一些标准库支持以从类似操作中返回B的想法。

  

还是开发人员选择返回A或B(即方法被覆盖)。

正确。