目录
概述
类的定义
类的继承
类的静态方法和属性
类里面的修饰符
抽象类
?多态
getters与setters
readonly修饰符
概述
- 类(Class):定义了一切事物的抽象特点
- 对象(Object):类的实例
- 面向对象(OOP)三大特性:封装继承多态
类的定义
// 定义类
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()
getters与setters
类中的私有成员和保护成员我们并不是真的不能读写,在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修饰符
我们可以通过?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 是只读的.
|