JS
在 ES6
中引入了“类”(class
) 的概念 ,在 TS
中,这部分完全可以直接拿过来使用,不过稍有变化。
定义类
class Chinese {
// 声明属性
name: string
sex: string
// 注意:构造函数无返回值,所以不能像普通函数那样在返回值注解部分编写类型注解
constructor(name: string, sex: string) {
// 属性要先声明后使用
this.name = name;
this.sex = sex
}
// 一般方法的声明
say(word: string): void {
console.log(this.name, word);
}
}
// 获取实例
let c1 = new Chinese('如花', '男')
console.log(c1);
c1.say('帅哥')
class Chinese {
// 声明属性
name: string
sex: string
// 注意:构造函数无返回值,所以不能像普通函数那样在返回值注解部分编写类型注解
constructor(name: string, sex: string) {
this.name = name;
this.sex = sex
}
// 一般方法的声明
say(word: string): void {
console.log(this.name, word);
}
}
// 继承父类
class HeNan extends Chinese {
// 重写父类的方法
say(): void {
super.say('我从子类中调用的啊')
console.log('子类的内容啊');
}
}
let h1 = new HeNan('张思睿', '男')
console.log(h1);
h1.say()
前面的部分,和 ES6
中的 class
的使用基本一样,只是多了类型注解。
// 声明一个类
class Cat {
// 声明属性
name: string
constructor(name: string) {
this.name = name;
}
say(): void {
console.log(this.name);
}
}
// 声明一个类
class Dog {
name: string
constructor(name: string) {
this.name = name;
}
}
let c1 = new Cat('小猫')
let d1 = new Dog('小狗')
// 指定该变量的注解类型为Cat类
let someone: Cat;
someone = c1
//将其它类的实例赋值给someone时会报错(如果Dog类和Cat类结构一样的话,也能编译通过)。
someone = d1
多态就是指多种形态。当存在继承关系的时候,对于同一个父类型的不同子类型的实例而言,它们既属于子类型的,也属于父类型,当调用这些实例的相同方法时,可能会产生不同的行为。
// 声明一个类
class Cat {
// 声明属性
name: string
constructor(name: string) {
this.name = name;
}
say(): void {
console.log(this.name);
}
}
// 定义一个子类
class Tiger extends Cat {
say(): void {
console.log(this.name + '咯咯叫');
}
}
// 定义一个子类
class PetCat extends Cat {
say(): void {
console.log(this.name + '咪咪叫');
}
}
//
let animal: Cat;
let t1: Cat;
let p1: Cat;
animal = new Cat('猫科动物')
animal.say()
// t1既属于Tiger类型的数据,也属于Cat类型的数据
t1 = new Tiger('老虎')
t1.say()
// p1既属于PetCat类型的数据,也属于Cat类型的数据
p1 = new PetCat('小猫咪')
p1.say()
Tiger
的实例,既属于Tiger
类型的数据,也属于Cat
类型的数据,PetCat
的实例,既属于PetCat
类型的数据,也属于Cat
类型的数据。上面的 t1
和 p1
虽然都是 Cat
类型的数据,但是当调用相同的方法时,还是表现出了不同的行为,这就叫多态。
这三个修饰符,主要使用开控制类的属性和方法访问性的,默认所有属性都是使用 public
修饰。
public
:公开的,用来定义可以在任何地方自由的访问成员protected
:受保护的,用来定义可以在本类或者子类中访问的成员private
:私有的,用来定义仅可以在本类内部访问的成员class Cat {
public name: string;
// 定义一个私有属性,仅能在该类中被访问
private girl: string = '如花'
constructor(name: string) {
this.name = name
}
// 定义一个可以在任何位置访问的方法
public say(): void {
console.log('我们说点啥呢');
// 在类的内部访问私有属性
console.log(this.girl);
// 在类的内部访问受保护的成员方法
this.money()
}
// 定义一个受保护的方法,可以在本类中访问,也可以在子类中访问
protected money(): void {
console.log('我们很有钱');
}
}
let c1 = new Cat('小花猫')
// 对于 public 修饰的成员,可以在任何地方使用他们
console.log(c1.name);
c1.say()class Tiger extends Cat {
public run(): void {
// 访问使用protected修饰的成员
this.money()
// 访问使用private修饰的成员(会报错)
console.log(this.girl);
}
}
let t1 = new Tiger('老虎')
t1.run()
可以使用 readonly
关键字将属性设置为只读。 只读属性必须在声明时或构造函数里被初始化
class Cat {
// 设置只读属性
public readonly name: string;
constructor(name: string) {
this.name = name
}
}
let c1 = new Cat('如花')
console.log(c1.name);
// 当修改只读属性的时候,会报错
c1.name = '翠花'
默认情况下,我们要在类中定义成员属性,必须要在类的前面定义属性名,然后在构造函数中通过 this.属性名 = 某个变量
的形式对其进行初始化。其实还是比较麻烦的。我们如果在构造函数的形参上使用 readonly
、public
、protected
、private
等修饰,则无需进行之前那种比较繁琐的操作。
class Cat {
constructor(public name: string, readonly sex: string) {}
}
let c1 = new Cat('如花', '男')
console.log(c1.name);
console.log(c1.sex);
getter
和
这部分和 ES6
中的一样,不在过多说明。
静态属性
这部分和 ES6
中的一样,不在过多说明。