基本使用
(() => {class Person {// 定义属性name: stringage: number// 构造方法,实例化对象的时候,直接对属性的值进行初始化constructor(name: string = '张三', age: number = 18) {// 更新对象中的属性数据this.name = namethis.age = age}// 实例方法sayHi(message: string): string {return '大家好,我叫' + this.name + '我今年' + this.age + '岁了,我对大家说:' + message}}// 创建类的实例,使用默认属性const person1 = new Person()// 调用实例的方法console.log(person1.sayHi('你好啊'))// 创建类的实例,使用自定义属性const person2 = new Person('李四', 20)// 调用实例的方法console.log(person2.sayHi('hello'))})()// 输出结果// 大家好,我叫张三我今年18岁了,我对大家说:你好啊// 大家好,我叫李四我今年20岁了,我对大家说:hello
继承
(() => {// 定义一个父类(超类)class Person {// 定义属性name: stringage: number// 构造方法,实例化对象的时候,直接对属性的值进行初始化constructor(name: string, age: number) {// 更新对象中的属性数据this.name = namethis.age = age}// 实例方法sayHi(message: string): string {return '大家好,我叫' + this.name + '我今年' + this.age + '岁了,我对大家说:' + message}}// 定义一个子类(派生类)class Student extends Person {// 调用父类中的构造函数constructor(name: string, age: number) {super(name,age);}// 继承父类中的方法sayHi(message: string): string {return super.sayHi(message);}}// 创建类的实例,使用自定义属性const student = new Student('李四', 20)// 调用实例的方法console.log(student.sayHi('hello'))})()// 输出结果// 大家好,我叫李四我今年20岁了,我对大家说:hello
多态
父类型的引用指向了子类型的对象,不同类型的对象针对相同的方法产生了不同的行为
(() => {// 定义一个父类(超类)class Person {// 定义属性name: string// 构造方法,实例化对象的时候,直接对属性的值进行初始化constructor(name: string) {// 跟鞋对象中的属性数据this.name = name}// 实例方法run(num: number = 0): string {return '大家好,我叫' + this.name + '我跑了' + num + '米'}}// 定义第一个子类(派生类)class Student extends Person {// 调用父类中的构造函数constructor(name: string) {super(name);}// 重写父类中的方法run(num: number = 5): string {return '大家好,我叫' + this.name + '我跑了' + num + '米'}}// 定义第二个子类(派生类)class Teacher extends Person {// 调用父类中的构造函数constructor(name: string) {super(name);}// 重写父类中的方法run(num: number = 10): string {return '大家好,我叫' + this.name + '我跑了' + num + '米'}}// 创建父类的实例const person1: Person = new Person('张三')// 调用实例的方法console.log(person1.run())// 创建子类1的对象const student1 = new Student('李四')console.log(student1.run())// 创建子类2的对象const teacher1 = new Teacher('王五')console.log(teacher1.run())// 创建父类的实例const person2: Person = new Person('张三')// 调用实例的方法console.log(person2.run())// 使用父类型创建子类1的对象const student2: Person = new Student('李四')console.log(student2.run())// 创建使用父类型创建子类2的对象const teacher2: Person = new Teacher('王五')console.log(teacher2.run())// 定义函数,该函数需要传入参数是Person类型的function showRun(per: Person):void{console.log(per.run())}showRun(person2)showRun(student2)showRun(teacher2)})()// 输出结果// 大家好,我叫张三我跑了0米// 大家好,我叫李四我跑了5米// 大家好,我叫王五我跑了10米// 大家好,我叫张三我跑了0米// 大家好,我叫李四我跑了5米// 大家好,我叫王五我跑了10米// 大家好,我叫张三我跑了0米// 大家好,我叫李四我跑了5米// 大家好,我叫王五我跑了10米
修饰符
主要用于描述类中的成员(属性,构造函数,方法)的可访问性,默认是pubile,公共的,任何位置都可以访问类中的成员
public (默认值, 公开的外部也可以访问)
(() => {// 定义一个父类(超类)class Person {// 定义属性public name: string// 构造方法,实例化对象的时候,直接对属性的值进行初始化public constructor(name: string) {// 更新对象中的属性数据this.name = name}// 实例方法public run(num: number = 0): string {return '大家好,我叫' + this.name + '我跑了' + num + '米'}}})()// 创建父类的实例const person1: Person = new Person('张三')// 类的外部访问类中的成员属性console.log(person1.name)// 类的外部访问类中的成员方法console.log(person1.run())// 执行结果// 张三// 大家好,我叫张三我跑了0米
private(只能类内部可以访问,子类也无法访问)
(() => {// 定义一个父类(超类)class Person {// 定义属性private name: string// 构造方法,实例化对象的时候,直接对属性的值进行初始化private constructor(name: string) {// 更新对象中的属性数据this.name = name}// 实例方法private run(num: number = 0): string {return '大家好,我叫' + this.name + '我跑了' + num + '米'}}// 定义第一个子类(派生类)class Student extends Person {// 调用父类中的构造函数constructor(name: string) {super(name);}// 重写父类中的方法run(num: number = 5): string {return '大家好,我叫' + this.name + '我跑了' + num + '米'}}// 创建父类的实例const person1: Person = new Person('张三')// 类的外部访问类中的成员属性console.log(person1.name)// 类的外部访问类中的成员方法console.log(person1.run())// 创建子类1的对象const student = new Student('李四')console.log(student.run())})()one.ts(20,9): error TS2415: Class 'Student' incorrectly extends base class 'Person'.Property 'run' is private in type 'Person' but not in type 'Student'.one.ts(20,25): error TS2675: Cannot extend a class 'Person'. Class constructor is marked as private.one.ts(28,30): error TS2341: Property 'name' is private and only accessible within class 'Person'.one.ts(32,27): error TS2673: Constructor of class 'Person' is private and only accessible within the class declaration.one.ts(34,23): error TS2341: Property 'name' is private and only accessible within class 'Person'.one.ts(36,23): error TS2341: Property 'run' is private and only accessible within class 'Person'.
-
protected(类内部和子类可以访问)
(() => {// 定义一个父类(超类)class Person {// 定义属性protected name: string// 构造方法,实例化对象的时候,直接对属性的值进行初始化protected constructor(name: string) {// 更新对象中的属性数据this.name = name}// 实例方法protected run(num: number = 0): string {return '大家好,我叫' + this.name + '我跑了' + num + '米'}}// 定义第一个子类(派生类)class Student extends Person {// 调用父类中的构造函数constructor(name: string) {super(name);}// 重写父类中的方法run(num: number = 5): string {return '大家好,我叫' + this.name + '我跑了' + num + '米'}}// 创建父类的实例const person1: Person = new Person('张三')// 类的外部访问类中的成员属性console.log(person1.name)// 类的外部访问类中的成员方法console.log(person1.run())// 创建子类的对象const student = new Student('李四')console.log(student.run())})()// 输出结果// one.ts(32,27): error TS2674: Constructor of class 'Person' is protected and only accessible within the class declaration.// one.ts(34,23): error TS2445: Property 'name' is protected and only accessible within class 'Person' and its subclasses.// one.ts(36,23): error TS2445: Property 'run' is protected and only accessible within class 'Person' and its subclasses.
-
readonly
readonly关键字将属性设置为只读的。 只读属性必须在声明时或构造函数里被初始化。外部不能修改属性值,内部普通方法也不能修改,只能在创建对象初始化时,指定属性的值
(() => {// 定义一个父类(超类)class Person {// 定义属性readonly name: string// 构造方法,实例化对象的时候,直接对属性的值进行初始化constructor(name: string) {// 更新对象中的属性数据this.name = name}// 实例方法run(): string {// 类内部方法修改成员属性return this.name = 'abc'}}// 创建父类的实例const person1: Person = new Person('张三')// 类的外部访问类中的成员属性console.log(person1.name)// 修改实例的属性person1.name = '李四'console.log(person1.name)})()// 输出结果// one.ts(14,19): error TS2540: Cannot assign to 'name' because it is a read-only property.// one.ts(22,11): error TS2540: Cannot assign to 'name' because it is a read-only property.
存取器
通过
getters/setters来截取对对象成员的访问。用于控制对对象成员的访问。
(() => {// 外部可以传入姓氏和名字,使用set和get控制姓名数据,外部可以访问和修改class Person{firstName:string // 姓lastName:string // 名constructor(firstName:string,lastName:string) {this.firstName = firstNamethis.lastName = lastName}// 读取器——负责数据读取get fullName(){return this.firstName + '-' + this.lastName}// 设置器——负责数据的修改set fullName(val){let names = val.split('-')this.firstName = names[0]this.lastName = names[1]}}// 实例化对象const person:Person = new Person('东方','不败')// 获取对象的成员属性console.log(person.fullName)// 设置属性的数据person.fullName = '诸葛-孔明'console.log(person.fullName)})()// 输出结果// 东方-不败// 诸葛-孔明
静态属性与方法
通过static修饰的属性和方法,在使用时直接通过类名.的方式调用
/*静态属性, 是类对象的属性非静态属性, 是类的实例对象的属性*/(() => {// 定义一个类class Person{// 定义一个静态属性。类中默认有一个内置的name静态属性,不能冲突static names:string = '张三'// 定义一个静态方法static sayHi(){console.log('Hi')}}// 调用类的静态属性console.log(Person.names)// 设置类的静态属性值Person.names = '李四'console.log(Person.names)// 调用类的静态方法Person.sayHi()})()// 输出结果// 张三// 李四// Hi
抽象类
抽象类做为其它派生类的基类使用。 它们不能被实例化。不同于接口,抽象类可以包含成员的实现细节。
abstract关键字是用于定义抽象类和在抽象类内部定义抽象方法
/*抽象类不能创建实例对象, 只有实现类才能创建实例可以包含未实现的抽象方法*/(() => {// 定义一个抽象父类abstract class Person{// 定义一个抽象方法(抽象类中只定义,不能有具体的实现)abstract run()// 定义一个实例方法sayHi(){console.log('Hi')}}// 定义一个子类(派生类)class Student extends Person{// 重新实现抽象类中的方法,此时这个方法就是当前Person类的实例方法run(){console.log('整齐的跑')}}// 实例化student对象const student:Student = new Student()student.sayHi()// 调用抽象类中的实例方法student.run()})()// 输出结果// Hi// 整齐的跑
