前情提要
# 教程1:花费一分钟,跟着做,傻瓜式入门Typescript
类
可以理解为创建对象的模型
语法:
- 使用
class 类名{}来定义类,类名以大写字母开头 - 通过
new 类名()生成一个实例对象
实例属性
class Person {
// public修饰的属性为实例属性(默认修饰符,可省略)
// 定义类的实例对象属性,通过实例对象操作
public name: string = 'lemon'
public age:number = 17
}
let lemon = new Person()
lemon.name // 获取实例对象属性name
lemon.age = 18 // 修改实例对象属性age
静态属性
class FemalePerson {
// static开头的属性为静态属性(类属性), 只能通过类去获取
static gender: string = '女'
}
let lemon = new FemalePerson()
FemalePerson.gender // 通过类名获取静态属性
实例方法或静态方法中的this
class Person {
public introduce () {
// 实例方法里面的this指向该实例对象
console.log(this)
}
static sayHi () {
// 静态方法里面的this指向这个类
console.log(this)
}
}
let lemon = new Person()
lemon.introduce() // 调用实例对象方法
Person.sayHi() // 调用静态方法
构造函数
- 构造函数会在对象创建时被调用
- 构造函数的this指向实例对象
class Person {
public name: string
public age:number
// 构造函数会在对象创建时被调用
constructor(name: string, age: number) {
console.log(this) // 构造函数的this指向实例对象
this.name = name
this.age = age
}
}
let lemon = new Person('lemon', 17)
lemon.name // 获取实例对象的name属性值
当实例属性与构造函数形参名一致时,可以简写成:
class Person {
constructor(public name: string, public age: number) {
console.log(this)
this.name = name
this.age = age
}
}
继承
语法: class 子类名 extends 父类{}
使用继承后,子类将拥有父类的所有属性及方法
class Animal {
static name = '动物'
public sayHi () {
console.log('动物在叫')
}
}
class Dog extends Animal {
// 子类在父类的基础上扩展方法
public eat () {
console.log('吃骨头')
}
}
let wangcai = new Dog()
Dog.name // 打印: '动物'
wangcai.sayHi() // 继承父类的方法,打印: '动物在叫'
wangcai.eat() // 打印: '吃骨头'
方法重写
class Animal {
public sayHi () {
console.log('动物在叫')
}
}
class Dog extends Animal {
// 子类重新定义父类已存在的方法,称为方法重写
public sayHi () {
console.log('汪汪汪')
}
}
let wangcai = new Dog()
wangcai.sayHi() // 继承父类的方法,打印: '汪汪汪'
super关键字
使用super关键字继承父类的实例属性
class Animal {
constructor (public name: string) {
this.name = name
}
}
// 错误写法:
class Dog extends Animal {
// 试想:这里是不是也属于方法重写呢? 那么是不是Animal的实例属性name就被覆盖了呢?
// 所以这里是不允许这么去书写的
constructor (public age: number) {
this.age = age
}
}
// 正确写法:
class Dog extends Animal {
constructor (public name: string, public age: number) {
// 调用 super()执行父类的构造函数,从而实现继承父类的实例属性
super(name)
this.age = age
}
}
其他修饰符
readonly
class FemalePerson {
// readonly开头的属性为只读实例属性,表示只能获取,不能修改
readonly name: string = 'lemon'
}
let lemon = new FemalePerson()
lemon.name = 'laoxie' // 报错,该属性只读,不可修改
public VS private VS protected
-
public 修饰的属性可以在任意位置获取或修改
-
private 私有属性,只能在类内部进行获取或修改
- 通过在类中添加方法,使得私有属性能被获取或修改
class Animal {
constructor(private name: string) {
this.name = name;
}
}
class Dog extends Animal {
constructor(public name: string) {
super(name);
console.log(this.name); // 报错:Property 'name' is private and only accessible within class 'Animal'
}
}
通过getter&setter使用私有属性
class FemalePerson {
private _age: number
constructor (age: number) {
this._age = age
}
set age (val: number) {
if (val >= 0) {
this._age = val
}
}
get age () {
return this._age
}
}
let lemon = new FemalePerson(18)
lemon.age // 打印: 18
lemon.age = -20 // 不执行修改
lemon.age = 20 // 成功修改
- protected 受保护的属性,只能在类中或其子类中获取或修改
(介于public与private之间)
class Animal {
constructor(protected name: string) {
this.name = name;
}
}
class Dog extends Animal {
constructor(public name: string) {
super(name);
console.log(this.name); // 可以获取
}
}
抽象类
语法: abstract class 类名{}
- 抽象类不能用来创建对象
- 抽象类是专门用来被继承的类
abstract class Animal {
constructor (public name: string) {
this.name = name
}
// 抽象方法用abstract修饰开头,没有方法体
// 抽象方法只能定义在抽象类中,子类必须对抽象方法重写
abstract sayHi(): void
}
类与接口
类实现接口
有时候不同类之间可以有一些共有的特性,这时候就可以把特性提取成接口(interfaces),用 implements 关键字来实现。
interface Alarm {
alert(): void;
}
class SecurityDoor implements Alarm {
alert() {
console.log('SecurityDoor alert');
}
}
class SecurityCar implements Alarm {
alert() {
console.log('Car alert');
}
}
一个类可以实现多个接口:
interface Alarm {
alert(): void;
}
interface Light {
lightOn(): void;
lightOff(): void;
}
// Car 实现了 Alarm 和 Light 接口,既能报警,也能开关车灯
class Car implements Alarm, Light {
alert() {
console.log('Car alert');
}
lightOn() {
console.log('Car light on');
}
lightOff() {
console.log('Car light off');
}
}
接口继承接口
接口与接口之间可以是继承关系:
interface Alarm {
alert(): void;
}
// LightableAlarm 继承了 Alarm,除了拥有 alert 方法之外,还拥有两个新方法 lightOn 和 lightOff。
interface LightableAlarm extends Alarm {
lightOn(): void;
lightOff(): void;
}
接口继承类
class Point {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
interface Point3d extends Point {
z: number;
}
扩展
当我们在声明class Greeter时,除了创建一个名为Greeter的类之外,同时也创建了一个变量类型Greeter
class Greeter {
greet() {
return "Hello, world"
}
}
let greeter: Greeter = new Greeter("world") // Greeter类的实例对象的类型是Greeter
console.log(greeter.greet());
辛勤的前端园丁,立志于把每个知识点嚼碎了喂你嘴里!
下篇文章:函数与泛型,马不停蹄整理中...