TypeScript -- 类
2019-12-04 本文已影响0人
_路明非_
一 ,继承和成员修饰符
注意:类的属性都是实例属性而不是原型属性;方法是原型上的;
类里面的属性都需要有初始值
class Dog {
constructor(name: string){
this.name = name
}
name: string
run() {}
readonly legs: number = 4;
static food: string = 'apple';
}
// 类的继承
class Wang extends Dog {
constructor(name: string, public color: string) {
super(name)
this.color = color
}
// color: string
}
成员修饰符,这是ts对js的一种扩展
public:公有成员,类的默认属性都是public,对所有人都是可见的
private:私有成员,只能在类的本身被调用,而不能被类的实例调用,也不能被子类调用
private contructor 给构造函数设置:这个类既不能实例化也不能被继承
protected: 受保护成员,只能在类和子类中访问,而不能在类的实例中访问
protected contructor:这个类不能被实例化,只能被继承,相当于声明了一个基类
readonly: 只读属性也一定要初始化,跟实例属性是一样的
static:类的静态成员,类的静态成员只能通过类名来调用,而不能通过实例来调用,可以被继
除了类的成员可以添加修饰符之外,构造函数的参数也可以添加修饰符
作用:自动的将参数变成了实例的属性,这样我们就能省略在类中的定义了
二 ,抽象类与多态(TS对JS的扩展)
抽象类:
- 只能被继承而不能被实例化的类
- 抽象类定义用abstract定义
多态:
- 抽象类的好处是抽出共性,有利于代码的复用和扩展,
- 抽象类也可以实现多态,在父类中定义一个抽象方法,
在多个子类中对这个方法有不同的实现,在程序运行的时候,
会根据不同的对象,执行不同的操作,这样就实现了运行时的绑定。
abstract class Animal {
eat() {
console.log('eat')
}
//抽象方法的好处:明确的知道子类有自己的实现,父类就不需要实现了
abstract sleep(): void
}
class Dog extends Animal {
constructor(name: string) {
super()
this.name = name
}
name: string
run() {}
sleep() {
console.log('dog sleep')
}
}
let dog = new Dog('wangwang')
dog.eat();
class Cat extends Animal {
sleep() {
console.log('cat sleep')
}
}
let cat = new Cat();
let animal: Animal[] = [dog, cat]
animal.forEach(i => {
i.sleep() //这个地方就实现了多态
})
this类型(TS特殊类型)
- 方便的实现链式调用
- 在继承的时候this类型也可以表现出多态,this既可以是父类型也可以是子类型
class WorkFlow {
sleep1() {
return this
}
sleep2() {
return this
}
}
new WorkFlow().sleep1().sleep2()// 这样就实现了方法的链式调用
class MyFlow extends WorkFlow {
next() {
return this
}
}
new MyFlow().next().sleep1().next().sleep2() // 多态
三 ,类与接口的关系
类 类型接口
①. 一个接口可以约束类成员有哪些属性以及他们的方法(用implements实现接口)
②. 注意:
a: 类实现接口的时候,必须实现接口中声明的所有属性
b: 接口只能约束类的共有成员
c: 接口也不能约束构造函数
interface Human {
// new (name: string): void 这是不行的
name: string;
eat(): void;
}
class Asian implements Human {
constructor(name: string) {
this.name = name;
}
// private name: string; 这是不行的
name: string;
eat() {}
}
接口的继承
- 接口可以像类一样继承;
- 从接口的继承可以看出,接口的继承可以抽离出可重用的接口,也可以将多个接口合并成一个接口
interface Man extends Human {
run(): void;
}
interface Child {
cry(): void;
}
interface Boy extends Man, Child {
}
let boy: Boy = {
name: '',
run() {},
eat() {},
cry() {}
}
接口继承类
1,这就相当于把类的成员都抽象了出来,也就是只有类的成员接口,而没有具体实现
2,在抽离类的成员的时候,不只是抽离了公共成员,也包括私有成员和受保护成员
class Auto {
state = 1
}
interface AutoInterface extends Auto {
//这样这个接口中就隐含了state属性
}
class AutoC implements AutoInterface {
state = 2
}
class Bus extends Auto implements AutoInterface {
//在这个子类中我们就不必实现 state 属性了
}