如何在 TypeScript 中扩展多个类?

3
如果我有两个类,是否可以创建一个同时继承它们的第三个类?
abstract class A {
    name
    age
    protected abstract print()
}
        
abstract class B {
    name
    age
}
        
// class C needs to inherit from both of the above classes

class C extends A , B {
}

   
   

1
无法同时扩展两个或多个类。Java不允许多重继承。您可以使用接口。在这种情况下,类c可以实现接口A和B,例如。 - Dacleoz
1
@ABOS TS的多重继承与Java有何相似之处? - VLAZ
1
@VLAZ,我不知道你在这里想证明什么,很明显这个标签是错误添加的。 - daniel wix
1
@danielwix ABOS编辑了您的问题标题,添加了“类似于Java”,从而将您的查询与明显不相关的语言联系起来。此外,这并不是真正的“显然”是一个错误。我们每天都会收到带有奇怪标签混合的问题。是的,很多是错误的,但是没有能力读取问题提问者的思想,我们不知道他们是否添加了标签。当存在疑问时,我更喜欢询问。谁知道,也许您想要在TS中模拟一些Java构造。我们每天也会收到类似的问题。 - VLAZ
使用多重继承的原因 - 可能AB都有一个共同的祖先,因此C不需要从两者都继承。或者C可以直接从A继承。在这里,C成为B的子类型的理由很少。如果确实需要,那么您的示例似乎并不具有代表性。在JS(以及通过绕过一些TS)中,可以将多个祖先插入到原型链中,这有点像多重继承。但是,这也不能“解决”它。这是强制性的。因此,很难在没有真正问题的情况下解决设计问题。 - VLAZ
显示剩余3条评论
1个回答

4

是的,根据要求有几种方法可以做到这一点。 鉴于类AB

class A {
  constructor(public i: number){}
  foo() {
    return 123;
  }
}

class B {
  constructor(public name: string){}
  bar() {
    return "Hello from B!";
  }
}

你可以执行以下任一操作,并使其“只是工作”(对于某些只是工作的价值):
  1. Inherit one class, implement the other as an interface (in TypeScript any class may be treated as an interface):

    class Cv1 extends B implements A { /* implement A-as-interface here */ }
    
  2. Create a type alias for A & B and implement the type alias (e. g. treat both classes as interfaces):

    type AandB = A & B;
    class Cv2 implements AandB {
      constructor(public i: number, public name: string) {}
      foo(...args: []) {
        return A.prototype.foo.apply(this, args);
      }
      bar() {
        return "Cv2 says GOODBYE!";
      }
    }
    
  3. Mix both classes together and inherit from the mixed class:

    // Exercise for the reader: do it without any
    function mixin(a: any, b: any): any {
      // Choice: Should isA apply to either mixin? Should it apply to neither?
      const aNotB = Object.defineProperties(Object.create(a.prototype), Object.getOwnPropertyDescriptors(b.prototype));
      const shadowClass: any = function shadowClass(){}
      shadowClass.prototype = aNotB;
      class mixinImpl extends shadowClass {}
      return mixinImpl;
    }
    
    class Cv3 extends mixin(A, B) { }
    

买家须知

这种技术有其局限性。例如,如果B自己有原型链(例如B extends BPrimeBPrime extends BPrimordial等),那么BPrimeBPrimordial的所有方法和属性都不会被复制(如果你想这样做,可以在类构造时自行遍历原型链)。此外,instanceof将无法与任何implements.assign技术配合使用(例如,使用上述任何一种技术的anInstanceOfC instanceof B都会返回false)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接