我想知道男人和孩子有什么共同之处,又有什么不同之处。
class Person {
name: string;
age: number;
}
class Child extends Person {}
class Man implements Person {}
我想知道男人和孩子有什么共同之处,又有什么不同之处。
class Person {
name: string;
age: number;
}
class Child extends Person {}
class Man implements Person {}
短的版本
延伸的意思是:
这个新类是一个子类。它从继承中得到好处。它具有其父对象的所有属性和方法。它可以覆盖其中的一些并实现新的,但父内容已经包括在内。
实现方式:
新类可以被视为相同的“形状”,但它不是一个子类。它可以传递给需要Person的任何方法,而不管与Person有不同的父方法。
更多…
在OOP(语言如c#或Java)中,我们会使用
延伸到继承的利润。
... 在大多数基于类的面向对象语言中,继承是一种机制,在这种机制中,一个对象获得父对象的所有属性和行为。继承允许程序员:创建建立在现有类之上的类……
实现将更多地用于多态。
... 多态性是为不同类型的实体提供单一接口……
所以我们的类可以有一个完全不同的继承树:
class Man extends Human ...
但如果我们也宣称人可以伪装成人的类型:
class Man extends Human
implements Person ...
...那么我们可以在任何需要Person的地方使用它。我们只需要实现Person的“接口”(即实现其所有公共内容)。
实现其他类?这真的很酷
Javascript的优点之一是对duck类型的内置支持。
“如果它走路像鸭子,叫起来也像鸭子,那它一定是鸭子。”
所以,在Javascript中,如果两个不同的对象有一个相似的方法(例如render()),它们可以被传递给一个期望它的函数:
function(engine){
engine.render() // any type implementing render() can be passed
}
为了在Typescript中不丢失它,我们可以使用更多的类型化支持来做同样的事情。这就是
class implements class
有它的作用,在有意义的地方。
在面向对象语言如c#中,没有办法做到这一点。
文档应该在这里有所帮助:
Interfaces Extending Classes When an interface type extends a class type it inherits the members of the class but not their implementations. It is as if the interface had declared all of the members of the class without providing an implementation. Interfaces inherit even the private and protected members of a base class. This means that when you create an interface that extends a class with private or protected members, that interface type can only be implemented by that class or a subclass of it. This is useful when you have a large inheritance hierarchy, but want to specify that your code works with only subclasses that have certain properties. The subclasses don’t have to be related besides inheriting from the base class. For example: class Control { private state: any; } interface SelectableControl extends Control { select(): void; } class Button extends Control implements SelectableControl { select() { } } class TextBox extends Control { select() { } } // Error: Property 'state' is missing in type 'Image'. class Image implements SelectableControl { private state: any; select() { } } class Location { }
因此,尽管
Extends意味着它从父节点获取所有信息 在这种情况下,它就像实现一个接口。子对象可以假装它是它的父对象…但是它没有得到任何实现。
你有typescript(和其他一些OO语言)的类和接口。
接口没有实现;它只是这种类型的成员/方法的“契约”。 例如:
interface Point {
x: number;
y: number;
distance(other: Point): number;
}
实现这个Point接口的实例必须有两个number类型的成员:x和y',还有一个方法distance,它接收另一个Pointinstance并返回一个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));
}
}
(操场上的代码)
在您的示例中,您在扩展Person类时将它作为类对待,在实现它时将它作为接口对待。 你的代码:
class Person {
name: string;
age: number;
}
class Child extends Person {}
class Man implements Person {}
它有一个编译错误说:
类“Man”错误地实现了接口“Person”。 属性“name”在类型“Man”中缺失。
这是因为接口缺乏实现。 所以如果你实现了一个类,那么你只需要它的“契约”而不需要实现,所以你需要这样做:
class NoErrorMan implements Person {
name: string;
age: number;
}
(操场上的代码)
底线是,在大多数情况下,您希望扩展另一个类,而不是实现它。
来自@nitzan-tomer的精彩回答!帮了我很多…我扩展了他的演示:
IPoint interface;
Point implements IPoint;
Point3D extends Point;
以及它们在期望IPoint类型的函数中的行为。
因此,到目前为止,我学到的并一直作为经验法则使用的是:如果您正在使用期望泛型类型的类和方法,则使用接口作为期望的类型。并确保父类或基类使用该接口。这样,只要它们实现了接口,您就可以使用其中的所有子类。
这里是扩展演示
接口用形状扩展接口 接口用形状扩展类 类实现接口应该实现接口提供的所有字段 类使用形状实现类 类用所有字段扩展类
扩展对继承的关注,实现对约束的关注,无论是接口还是类。
扩展VS实现
extends:子类(被扩展的)将继承类的所有属性和方法 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)
在这个例子中,我们可以观察到子类继承了Person的所有内容,而man类必须实现Person本身的所有内容。
如果我们要从man类中删除一些东西,例如walk方法,我们将得到以下编译时错误:
类'man'错误地实现了类'Person'。你的意思是 扩展'人'并继承其成员作为子类?财产 在“man”类型中没有“walk”,但在“Person”类型中需要“walk”。