TypeScript中'extends'和'implements'之间的区别是什么

dav*_*oem 77 extends implements typescript

我想知道男人孩子有什么共同点,以及他们有什么不同.

class Person {
  name: string;
  age: number;
}
class child extends Person {}
class man implements Person {}
Run Code Online (Sandbox Code Playgroud)

Rad*_*ler 100

精简版

  • extends 手段:

新类是孩子.继承带来好处.它具有所有属性,方法作为其父级.它可以覆盖其中的一些并实现新的,但父内容已经包含在内.

  • implements 手段:

新类可视为同一"形",而这是不是一个孩子.它可以传递给任何需要的方法Person,无论父级是否不同Person

更多 ...

OOP (C#,Java等语言)中我们会使用

extends从继承中获利(见维基).小引用:

大多数基于类的面向对象语言中的继承是一种机制,其中一个对象获取父对象的所有属性和行为.继承允许程序员:创建基于现有类的类...

implements将更多的多态性(见维基).小引用:

... polymorphism是为不同类型的实体提供单一接口...

所以,我们可以拥有真正不同的继承树class Man.

class Man extends Human ...
Run Code Online (Sandbox Code Playgroud)

但如果我们也声明我们可以伪装成另一种类型 - Person:

class Man extends Human 
          implements Person ...
Run Code Online (Sandbox Code Playgroud)

..然后我们可以在任何Person需要的地方使用它.我们只需要履行人员"interface" (即实施所有公共事务).

implement其他课程?这真是很酷的东西

Javascript漂亮的脸(其中一个好处)是Duck打字的内置支持(参见wiki).小引用:

"如果它像鸭子一样走路,它像鸭子一样嘎嘎叫,那它一定是鸭子."

因此,在Javascript中,如果两个不同的对象...将有一个类似的方法(例如render()),它们可以传递给期望它的函数:

function(engine){
  engine.render() // any type implementing render() can be passed
}
Run Code Online (Sandbox Code Playgroud)

为了不丢失它 - 我们可以在Typescript中做同样的事情 - 使用更多类型的支持.那是在哪里

class implements class
Run Code Online (Sandbox Code Playgroud)

有它的作用,它是有道理的

在OOP语言中C#......没办法......

此处的文档应该有所帮助:

接口扩展类

当接口类型扩展类类型时,它继承类的成员但不继承它们的实现.就好像接口已经声明了类的所有成员而没有提供实现.接口甚至继承基类的私有成员和受保护成员.这意味着当您创建一个扩展具有私有或受保护成员的类的接口时,该接口类型只能由该类或其子类实现.

当您具有大型继承层次结构但希望指定您的代码仅使用具有某些属性的子类时,这非常有用.除了继承基类之外,子类不必相关.例如:

class Control {
    private state: any;
}

interface SelectableControl extends Control {
    select(): void;
}

class Button extends Control {
    select() { }
}

class TextBox extends Control {
    select() { }
}

class Image extends Control {
}

class Location {
    select() { }
}
Run Code Online (Sandbox Code Playgroud)

所以,同时

  • extends 意味着 - 它从父母那里得到所有
  • implements在这种情况下几乎就像实现一个接口.子对象可以假装它是父...但它没有得到任何实现

  • 图像的实际错误更清楚。“‘Image’类错误地实现了 SelectableControl 接口。类型具有私有属性‘state’的单独声明。” 说“属性状态丢失”很令人困惑,因为它不是丢失,而是重复。 (2认同)

Nit*_*mer 75

在typescript(和其他一些OO语言)中,您有类和接口.

接口没有实现,它只是这种类型的成员/方法的"契约".
例如:

interface Point {
    x: number;
    y: number;
    distance(other: Point): number;
}
Run Code Online (Sandbox Code Playgroud)

谁实现这个实例Point接口必须有类型号两个成员:xy,和一个方法distance接收另一个Point实例,并返回一个number.
该接口不实现任何这些.

类是实现:

class PointImplementation implements Point {
    public x: number;
    public y: number;

    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }

    public distance(other: Point): number {
        return Math.sqrt(Math.pow(this.x - other.x, 2) + Math.pow(this.y - other.y, 2));
    }
}
Run Code Online (Sandbox Code Playgroud)

(游乐场代码)

在您的示例中,您Person在扩展它时将您的类视为一个类,在实现它时将其视为一个接口.
你的代码:

class Person {
    name: string;
    age: number;
}
class Child  extends Person {}

class Man implements Person {}
Run Code Online (Sandbox Code Playgroud)

有编译错误说:

类'Man'错误地实现了接口'Person'.
"Man"类型中缺少属性"name".

那是因为接口缺乏实现.
所以,如果你implement是一个班级,那么你只需要没有实施的"合同",所以你需要这样做:

class NoErrorMan implements Person {
    name: string;
    age: number;
}
Run Code Online (Sandbox Code Playgroud)

(游乐场代码)

最重要的是,在大多数情况下,你想要的是extend另一个类,而不是implement它.


Wil*_*een 13

扩展 VS 工具

  • extends: 子类(被扩展)将继承类的所有属性和方法。
  • implements: 使用implements关键字的类需要实现该类的所有属性和方法implements

简单来说:

  • extends:在这里您可以从父类中获得所有这些方法/属性,因此您不必自己实现
  • implements:这是班级必须遵守的合同。这个类必须实现至少下列方法/属性

例子:

class Person {
  name: string;
  age: number;

  walk(): void {
    console.log('Walking (person Class)')
  }

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}
class child extends Person { }

// Man has to implements at least all the properties
// and methods of the Person class
class man implements Person {
  name: string;
  age: number

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  walk(): void {
    console.log('Walking (man class)')
  }

}

(new child('Mike', 12)).walk();
// logs: Walking(person Class)

(new man('Tom', 12)).walk();
// logs: Walking(man class)
Run Code Online (Sandbox Code Playgroud)

在示例中,我们可以观察到子类继承了 Person 的所有内容,而 man 类必须实现 Person 本身的所有内容。

如果我们从 man 类中删除一些东西,例如 walk 方法,我们会得到以下编译时错误:

'man' 类错误地实现了 'Person' 类。您的意思是扩展“人”并将其成员作为子类继承吗?'man' 类型中缺少属性 'walk',但类型 'Person' 中需要该属性。(2720)

  • 完美解释 (7认同)

and*_*zep 6

来自@nitzan-tomer 的好答案!帮了我很多......我扩展了他的演示:

IPoint interface;
Point implements IPoint;
Point3D extends Point;
Run Code Online (Sandbox Code Playgroud)

以及它们在期望IPoint类型的函数中的行为方式。

所以到目前为止我所学到的并一直用作拇指规则:如果您使用需要泛型类型的类和方法,请使用接口作为预期类型。并确保父类或基类使用该接口。这样你就可以使用这些子类中的所有子类,只要它们实现了接口。

这里是扩展演示


lei*_* li 6

  1. 界面以形状扩展界面
  2. 接口通过形状扩展类
  3. 实现接口的类应该实现接口提供的所有字段
  4. 类用形状实现类
  5. 类扩展了类的所有字段

extends关注继承并implements关注约束,无论是接口还是类。


Pou*_*ani 6

基本上:

  • extends将获取父类的所有属性和方法。
  • implements将迫使我们实现接口中定义的所有属性和方法。