Voj*_*ěch 171 typescript
我试图弄清楚如何在TypeScript中正确定义抽象方法:
使用原始继承示例:
class Animal {
constructor(public name) { }
makeSound(input : string) : string;
move(meters) {
alert(this.name + " moved " + meters + "m.");
}
}
class Snake extends Animal {
constructor(name) { super(name); }
makeSound(input : string) : string {
return "sssss"+input;
}
move() {
alert("Slithering...");
super.move(5);
}
}
Run Code Online (Sandbox Code Playgroud)
我想知道如何正确定义方法makeSound,因此它是键入的并且可能被覆盖.
此外,我不知道如何正确定义protected方法 - 它似乎是一个关键字,但没有效果,代码将无法编译.
Fen*_*ton 254
该name物业标记为protected.这是在TypeScript 1.3中添加的,现在已经确立.
该makeSound方法被标记为abstract,类.你不能直接实例化一个Animalnow,因为它是抽象的.这是TypeScript 1.6的一部分,现在正式上线.
abstract class Animal {
constructor(protected name: string) { }
abstract makeSound(input : string) : string;
move(meters) {
alert(this.name + " moved " + meters + "m.");
}
}
class Snake extends Animal {
constructor(name: string) { super(name); }
makeSound(input : string) : string {
return "sssss"+input;
}
move() {
alert("Slithering...");
super.move(5);
}
}
Run Code Online (Sandbox Code Playgroud)
模仿抽象方法的旧方法是在任何人使用它时抛出错误.一旦TypeScript 1.6登陆您的项目,您就不需要再这样做了:
class Animal {
constructor(public name) { }
makeSound(input : string) : string {
throw new Error('This method is abstract');
}
move(meters) {
alert(this.name + " moved " + meters + "m.");
}
}
class Snake extends Animal {
constructor(name) { super(name); }
makeSound(input : string) : string {
return "sssss"+input;
}
move() {
alert("Slithering...");
super.move(5);
}
}
Run Code Online (Sandbox Code Playgroud)
Tid*_*ddo 19
如果你更进一步地回答Erics,你实际上可以创建一个相当不错的抽象类实现,完全支持多态和从基类调用实现方法的能力.让我们从代码开始:
/**
* The interface defines all abstract methods and extends the concrete base class
*/
interface IAnimal extends Animal {
speak() : void;
}
/**
* The abstract base class only defines concrete methods & properties.
*/
class Animal {
private _impl : IAnimal;
public name : string;
/**
* Here comes the clever part: by letting the constructor take an
* implementation of IAnimal as argument Animal cannot be instantiated
* without a valid implementation of the abstract methods.
*/
constructor(impl : IAnimal, name : string) {
this.name = name;
this._impl = impl;
// The `impl` object can be used to delegate functionality to the
// implementation class.
console.log(this.name + " is born!");
this._impl.speak();
}
}
class Dog extends Animal implements IAnimal {
constructor(name : string) {
// The child class simply passes itself to Animal
super(this, name);
}
public speak() {
console.log("bark");
}
}
var dog = new Dog("Bob");
dog.speak(); //logs "bark"
console.log(dog instanceof Dog); //true
console.log(dog instanceof Animal); //true
console.log(dog.name); //"Bob"
Run Code Online (Sandbox Code Playgroud)
由于Animal类需要实现IAnimal它,因此如果Animal没有抽象方法的有效实现,就不可能构造类型的对象.请注意,要使多态性工作,您需要传递实例IAnimal,而不是Animal.例如:
//This works
function letTheIAnimalSpeak(animal: IAnimal) {
console.log(animal.name + " says:");
animal.speak();
}
//This doesn't ("The property 'speak' does not exist on value of type 'Animal')
function letTheAnimalSpeak(animal: Animal) {
console.log(animal.name + " says:");
animal.speak();
}
Run Code Online (Sandbox Code Playgroud)
与Erics答案的主要区别在于"抽象"基类需要接口的实现,因此无法在其自身实例化.
| 归档时间: |
|
| 查看次数: |
114070 次 |
| 最近记录: |