Typescript Class(1)
类
类是函数的一个语法糖,比ES5通过原型链实现继承更加清晰和方便
类中有三个成员:greeting属性、构造函数、greet方法
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
let greeter = new Greeter("world");
继承
我们通过继承,对现有的类进行扩展 一个Animal类(基类)中有一个move方法,使用Dog(子类)在继承Animal的基础上,新增了一个dark方法
class Animal {
move(distanceInMeters: number = 0) {
console.log(`Animal moved ${distanceInMeters}m.`);
}
}
class Dog extends Animal {
bark() {
console.log('Woof! Woof!');
}
}
const dog = new Dog();
dog.bark();
dog.move(10);
dog.bark();
以下是一段更复发的代码 注意super,通过继承父类的子类自身是没有this的 子类所使用的this是通过获取父类的构造函数塑造的,得到父类实例的属性和方法以后,进行加工,加上自己的属性和方法 构造函数中super必须在使用this前使用
class Animal {
name: string;
constructor(theName: string) { this.name = theName; }
move(distanceInMeters: number = 0) {
console.log(`${this.name} moved ${distanceInMeters}m.`);
}
}
class Snake extends Animal {
constructor(name: string) { super(name); }
move(distanceInMeters = 5) {
console.log("Slithering...");
super.move(distanceInMeters);
}
}
class Horse extends Animal {
constructor(name: string) { super(name); }
move(distanceInMeters = 45) {
console.log("Galloping...");
super.move(distanceInMeters);
}
}
let sam = new Snake("Sammy the Python");
let tom: Animal = new Horse("Tommy the Palomino");
sam.move();
tom.move(34);
public private protected
默认情况下,ts默认设置为public,这样可以随意访问类中的成员
// 默认或设置为public
class Animal {
public name: string;
public constructor(theName: string) { this.name = theName; }
public move(distanceInMeters: number) {
console.log(`${this.name} moved ${distanceInMeters}m.`);
}
}
// private protected 属性
class Person {
protected name: string
private age: number = 10
constructor(strName: string) {
this.name = strName
}
public getAge() {
return this.age
}
public getName() {
return this.name
}
}
const example = new Person('aaa')
console.log(example.name)
console.log(example.age)
// Property 'name' is protected and only accessible within class 'Person' and its subclasses.ts(2445)
// Property 'age' is private and only accessible within class 'Person'.ts(2341)
console.log(example.getName())
console.log(example.getAge())
// private protected constructor
class Person2 {
protected name: string
private age: number = 10
private constructor(strName: string) {
this.name = strName
}
public getAge() {
return this.age
}
public getName() {
return this.name
}
}
const example = new Person2('aaa')
// Constructor of class 'Person2' is private and only accessible within the class declaration.ts(2673)
// Constructor of class 'Person2' is protected and only accessible within the class declaration.ts(2674)
// extends
// 继承
class Person {
protected name: string
private age: number = 10
constructor(strName: string) {
this.name = strName
}
public getAge() {
return this.age
}
public getName() {
return this.name
}
}
class Jack extends Person {
constructor(name: string) {
super(name)
}
getJackName() {
super.getName
}
getJackAge() {
console.log(this.name)
console.log(this.age)
// Property 'age' is private and only accessible within class 'Person'.ts(2341)
}
}
const example = new Jack('aaa')
console.log(example.name)
// Property 'name' is protected and only accessible within class 'Person' and its subclasses.ts(2445)
实现接口
接口能够描述JavaScript中对象拥有的各种各样的外形。 除了描述带有属性的普通对象外,接口也可以描述函数类型。
// 索引签名
// 数字索引签名的返回值类型必须是字符串索引签名返回值的子类型
class Animal {
name: string = 'name';
}
class Dog extends Animal {
breed: string = 'breed';
}
// 错误:使用数值型的字符串索引,有时会得到完全不同的Animal!
interface NotOkay {
[x: number]: Animal;
// Numeric index type 'Animal' is not assignable to string index type 'Dog'.ts(2413)
[x: string]: Dog;
}
interface NotOkay {
[x: number]: Dog;
[x: string]: Animal;
}
接口强制类的实现
interface ClockInterface {
currentTime: Date;
setTime(d: Date);
}
class Clock implements ClockInterface {
currentTime: Date;
setTime(d: Date) {
this.currentTime = d;
}
constructor(h: number, m: number) { }
}
上面例子接口约束了类的属性和方法,那么构造函数该如何约束? 接口描述了类的公共部分,而不是公共和私有两部分
类是具有两个类型的:静态部分的类型和实例的类型
// 使用构造器签名定义一个接口,再使用类去实现该接口
interface ClockConstructor {
new (hour: number, minute: number);
// Construct signature, which lacks return-type annotation, implicitly has an 'any' return type.ts(7013)
}
class Clock implements ClockConstructor {
// Class 'Clock' incorrectly implements interface 'ClockConstructor'.
// Type 'Clock' provides no match for the signature 'new (hour: number, minute: number): any'.ts(2420)
currentTime: Date;
constructor(h: number, m: number) { }
}
interface ClockConstructor {
new (hour: number, minute: number): any;
}
class Clock implements ClockConstructor {
currentTime: Date = new Date();
constructor(h: number, m: number) { }
}
发生错误的原因? 当一个类实现了一个接口时,只对其实例部分进行类型检查。 constructor存在于类的静态部分,所以不在检查的范围内。 如何对构造函数签名进行检测?
interface ClockInterface {
tick(): any;
}
interface ClockConstructor {
new (hour: number, minute: number): ClockInterface;
}
// 检查是否满足构造函数签名(有这么个构造函数可以去验证)
function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
return new ctor(hour, minute);
}
class DigitalClock implements ClockInterface {
constructor(h: number, m: number) { }
tick() {
console.log("beep beep");
}
}
class AnalogClock implements ClockInterface {
constructor(h: number, m: number) { }
tick() {
console.log("tick tock");
}
}
let digital = createClock(DigitalClock, 12, 17);
let analog = createClock(AnalogClock, 7, 32);
今天的文章Typescript-Class(1)分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/19317.html