目录
- // 定义类
- class Person {
- // 公共属性,默认可以不写
- public name: string
- // 构造函数
- constructor(name: string) {
- // 初始化name属性
- this.name = name
- }
- }
- // 实例化类
- const person = new Person('zs')
- console.log(person.name) // zs
在面向对象的编程语言中,有一个重要得特征就是继承。继承就是基于某个类来扩展现有的类。
例如,爸爸在北京有一个四合院,儿子可以继承爸爸的四合院,而且还可以自己去买一栋别墅;最终儿子的房产拥有北京的四合院和一栋别墅。
TypeScript中类的继承需要通过extends来配合super来实现。子类若要继承父类的属性和方法需要执行一次super(),它代表实例化父类的构造函数,super()只能用在子类的构造函数之中,用在其他地方就会报错。
- // 定义一个基类,又称超类
- class Father {
- // 在基类中定义一个name属性
- public name: string
- constructor(name: string) {
- this.name = name
- }
- }
- // 定义一个派生类,又称子类,继承于基类
- class Son extends Father {
- constructor(name: string, public age: number) {
- // 通过 super 调用基类的构造函数
- super(name)
- }
- getInfo(): void {
- console.log(this.name); //ZS
- console.log(this.age); //18
- }
-
- }
- const a = new Son('ZS', 18)
- a.getInfo()
静态属性和静态方法属于类自身,而不属于实例,访问的时候要用类名访问,而不能用实例对象访问。在 TS中定义静态成员与ES6中一样,都是使用static关键字来说明。
- class Hero {
- static count = 0
- constructor(public name: string) {
- // 每创建一个属性 count ++
- ++Hero.count
- }
- }
- const hero1 = new Hero('孙悟空')
- console.log(Hero.count) // 1
- const hero2 = new Hero('哪吒')
- console.log(Hero.count) // 2
- // console.log(hero1.count);不能访问静态成员count
TypeScript定义属性的时候给我们提供了三种修饰符:
public:公有属性,在当前类里面、 子类 、类外面都可以访问。属性如果不加修饰符默认就public。protected:保护类型,在当前类里面、子类里面可以访问 ,在类外部没法访问。private:私有属性,在当前类里面可以访问,子类、类外部都没法访问。- class Person {
- public name: string
- // 约定 私有成员一般采用 _ 开头
- private _age: number
- protected hobby: string
- // 属性初始化
- constructor(name: string, age: number, hobby: string) {
- this.name = name
- this._age = age
- this.hobby = hobby
- }
- sayMy() {
- console.log(this.name, this._age, this.hobby)
- }
- }
-
- // 实例化 Person 类
- const person = new Person('zs', 18, 'coding')
- console.log(person.name) // zs
- // console.log(person._age) // 报错 类外访问私有成员 抛出异常
- // console.log(person.hobby) // 报错 类外访问保护成员 抛出异常
- person.sayMy() // zs 18 coding,private 成员和 protected 成员可以在类内访问
-
- // 定义一个类继承与 Person 类
- class Programmer extends Person {
- constructor(name: string, age: number, hobby: string) {
- super(name, age, hobby)
- }
- sayMy() {
- console.log(this.name) // zs
- // console.log(this._age) // 报错 在子类不可以访问父类的私有成员
- // console.log(this.hobby) // coding 在子类不可以访问父类的私有成员
- }
- }
-
- // 实例化 Programmer 类
- const programmer = new Programmer('zs', 18, 'coding')
- programmer.sayMy()
-
概念
abstract关键字。- // 通过 abstract 关键字 定义一个抽象类,该类不必进行初始化,仅作为基类使用
- abstract class Department {
- // 初始化name成员,参数属性
- constructor(public name: string) { }
-
- printName(): void {
- console.log('部门名称: ' + this.name)
- }
- // 抽象方法必须包含 abstract 关键字
- abstract printMeeting(): void // 必须在派生类中实现
- }
-
- class AccountingDepartment extends Department {
- constructor() {
- super('会计部') // 在派生类的构造函数中必须调用super()
- }
-
- printMeeting(): void {
- console.log('会计部是负责管钱的部门')
- }
- }
-
- // const department = new Department() // 抛出异常:不能创建一个抽象类的实例
- // 实例化抽象子类
- const department = new AccountingDepartment()
- // 调用抽象类中的方法
- department.printName() // 部门名称: 会计部
- // 调用在派生类实现的抽象方法
- department.printMeeting() // 会计部是负责管钱的部门
多态属于继承,是继承的一种延续,在父类内部有一个公用方法,但是不知道具体做什么,由多个子类继承同一个方法,实现不同效果,这个公用方法也叫方法的重写
-
- class Animall {
- name: string;
- constructor(name: string) {
- this.name = name
- }
- eat(): void {
- console.log('我们都可以吃');
- }
- }
-
- class Dog extends Animall {
- constructor(name: string) {
- super(name)
- }
- eat(): void {
- console.log(`${this.name}吃骨头`)
- }
- }
-
- class Cat extends Animall {
- constructor(name: string) {
- super(name)
- }
- eat(): void {
- console.log(`${this.name}吃老鼠`)
- }
- }
-
- let dog = new Dog('小黄')
- dog.eat()
类中的私有成员和保护成员我们并不是真的不能读写,在TS中提供了getters与setters帮助我们有效的控制对对象成员的访问。
- // 定义一个 Person 类
- class Person {
- // 约定 私有成员一般采用 _ 开头
- private _name: string
- // 属性初始化
- constructor(name: string) {
- this._name = name
- }
- // 获取 私有的 _name 属性值
- get getName(): string {
- return this._name
- }
- // 设置 私有的 _name 属性值
- set setName(name: string) {
- this._name = name
- }
- }
- // 实例化类
- const person = new Person('zs')
- console.log(person.getName) // zs 通过 getName 的方式获取
- person.setName = 'ls'//通过 setName 的方式设置 _name 的值
- console.log(person.getName) // // 重新获取 ls
我们可以通过 readonly修饰符将一个属性设置为只读的。只读属性必须在声明时或者在构造函数中进行初始化。
- // 定义一个类,且具有一个只读属性
- class Person {
- // readonly name: string
- // 等同于
- // public readonly name: string
- // constructor(name: string) {
- // this.name = name
- // }
- // 或者
- constructor(public readonly name: string) { }
- }
- // 实例化
- const person = new Person('zs')
- console.log(person.name) // zs
- // 修改name的值
- // person.name = 'ls' // 错误! name 是只读的.