首页 > 解决方案 > OOP:方法返回新实例,孩子应该返回什么?

问题描述

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

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

而我的子类A

class B extends A {
}

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

标签: typescriptoop

解决方案


这里没有单一的最佳实践。这取决于map您希望它具有什么和语义。

对于通常称为 的操作,需要特别考虑的一个数据点map,例如 Array 上的那个(以及 to 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

覆盖 Array 的默认行为的示例(同样,在 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(即使用方法覆盖)。

正确的。


推荐阅读