基本使用

  1. (() => {
  2. class Person {
  3. // 定义属性
  4. name: string
  5. age: number
  6. // 构造方法,实例化对象的时候,直接对属性的值进行初始化
  7. constructor(name: string = '张三', age: number = 18) {
  8. // 更新对象中的属性数据
  9. this.name = name
  10. this.age = age
  11. }
  12. // 实例方法
  13. sayHi(message: string): string {
  14. return '大家好,我叫' + this.name + '我今年' + this.age + '岁了,我对大家说:' + message
  15. }
  16. }
  17. // 创建类的实例,使用默认属性
  18. const person1 = new Person()
  19. // 调用实例的方法
  20. console.log(person1.sayHi('你好啊'))
  21. // 创建类的实例,使用自定义属性
  22. const person2 = new Person('李四', 20)
  23. // 调用实例的方法
  24. console.log(person2.sayHi('hello'))
  25. })()
  26. // 输出结果
  27. // 大家好,我叫张三我今年18岁了,我对大家说:你好啊
  28. // 大家好,我叫李四我今年20岁了,我对大家说:hello

继承

  1. (() => {
  2. // 定义一个父类(超类)
  3. class Person {
  4. // 定义属性
  5. name: string
  6. age: number
  7. // 构造方法,实例化对象的时候,直接对属性的值进行初始化
  8. constructor(name: string, age: number) {
  9. // 更新对象中的属性数据
  10. this.name = name
  11. this.age = age
  12. }
  13. // 实例方法
  14. sayHi(message: string): string {
  15. return '大家好,我叫' + this.name + '我今年' + this.age + '岁了,我对大家说:' + message
  16. }
  17. }
  18. // 定义一个子类(派生类)
  19. class Student extends Person {
  20. // 调用父类中的构造函数
  21. constructor(name: string, age: number) {
  22. super(name,age);
  23. }
  24. // 继承父类中的方法
  25. sayHi(message: string): string {
  26. return super.sayHi(message);
  27. }
  28. }
  29. // 创建类的实例,使用自定义属性
  30. const student = new Student('李四', 20)
  31. // 调用实例的方法
  32. console.log(student.sayHi('hello'))
  33. })()
  34. // 输出结果
  35. // 大家好,我叫李四我今年20岁了,我对大家说:hello

多态

父类型的引用指向了子类型的对象,不同类型的对象针对相同的方法产生了不同的行为

  1. (() => {
  2. // 定义一个父类(超类)
  3. class Person {
  4. // 定义属性
  5. name: string
  6. // 构造方法,实例化对象的时候,直接对属性的值进行初始化
  7. constructor(name: string) {
  8. // 跟鞋对象中的属性数据
  9. this.name = name
  10. }
  11. // 实例方法
  12. run(num: number = 0): string {
  13. return '大家好,我叫' + this.name + '我跑了' + num + '米'
  14. }
  15. }
  16. // 定义第一个子类(派生类)
  17. class Student extends Person {
  18. // 调用父类中的构造函数
  19. constructor(name: string) {
  20. super(name);
  21. }
  22. // 重写父类中的方法
  23. run(num: number = 5): string {
  24. return '大家好,我叫' + this.name + '我跑了' + num + '米'
  25. }
  26. }
  27. // 定义第二个子类(派生类)
  28. class Teacher extends Person {
  29. // 调用父类中的构造函数
  30. constructor(name: string) {
  31. super(name);
  32. }
  33. // 重写父类中的方法
  34. run(num: number = 10): string {
  35. return '大家好,我叫' + this.name + '我跑了' + num + '米'
  36. }
  37. }
  38. // 创建父类的实例
  39. const person1: Person = new Person('张三')
  40. // 调用实例的方法
  41. console.log(person1.run())
  42. // 创建子类1的对象
  43. const student1 = new Student('李四')
  44. console.log(student1.run())
  45. // 创建子类2的对象
  46. const teacher1 = new Teacher('王五')
  47. console.log(teacher1.run())
  48. // 创建父类的实例
  49. const person2: Person = new Person('张三')
  50. // 调用实例的方法
  51. console.log(person2.run())
  52. // 使用父类型创建子类1的对象
  53. const student2: Person = new Student('李四')
  54. console.log(student2.run())
  55. // 创建使用父类型创建子类2的对象
  56. const teacher2: Person = new Teacher('王五')
  57. console.log(teacher2.run())
  58. // 定义函数,该函数需要传入参数是Person类型的
  59. function showRun(per: Person):void{
  60. console.log(per.run())
  61. }
  62. showRun(person2)
  63. showRun(student2)
  64. showRun(teacher2)
  65. })()
  66. // 输出结果
  67. // 大家好,我叫张三我跑了0米
  68. // 大家好,我叫李四我跑了5米
  69. // 大家好,我叫王五我跑了10米
  70. // 大家好,我叫张三我跑了0米
  71. // 大家好,我叫李四我跑了5米
  72. // 大家好,我叫王五我跑了10米
  73. // 大家好,我叫张三我跑了0米
  74. // 大家好,我叫李四我跑了5米
  75. // 大家好,我叫王五我跑了10米

修饰符

主要用于描述类中的成员(属性,构造函数,方法)的可访问性,默认是pubile,公共的,任何位置都可以访问类中的成员

public (默认值, 公开的外部也可以访问)

  1. (() => {
  2. // 定义一个父类(超类)
  3. class Person {
  4. // 定义属性
  5. public name: string
  6. // 构造方法,实例化对象的时候,直接对属性的值进行初始化
  7. public constructor(name: string) {
  8. // 更新对象中的属性数据
  9. this.name = name
  10. }
  11. // 实例方法
  12. public run(num: number = 0): string {
  13. return '大家好,我叫' + this.name + '我跑了' + num + '米'
  14. }
  15. }
  16. })()
  17. // 创建父类的实例
  18. const person1: Person = new Person('张三')
  19. // 类的外部访问类中的成员属性
  20. console.log(person1.name)
  21. // 类的外部访问类中的成员方法
  22. console.log(person1.run())
  23. // 执行结果
  24. // 张三
  25. // 大家好,我叫张三我跑了0米

private(只能类内部可以访问,子类也无法访问)

  1. (() => {
  2. // 定义一个父类(超类)
  3. class Person {
  4. // 定义属性
  5. private name: string
  6. // 构造方法,实例化对象的时候,直接对属性的值进行初始化
  7. private constructor(name: string) {
  8. // 更新对象中的属性数据
  9. this.name = name
  10. }
  11. // 实例方法
  12. private run(num: number = 0): string {
  13. return '大家好,我叫' + this.name + '我跑了' + num + '米'
  14. }
  15. }
  16. // 定义第一个子类(派生类)
  17. class Student extends Person {
  18. // 调用父类中的构造函数
  19. constructor(name: string) {
  20. super(name);
  21. }
  22. // 重写父类中的方法
  23. run(num: number = 5): string {
  24. return '大家好,我叫' + this.name + '我跑了' + num + '米'
  25. }
  26. }
  27. // 创建父类的实例
  28. const person1: Person = new Person('张三')
  29. // 类的外部访问类中的成员属性
  30. console.log(person1.name)
  31. // 类的外部访问类中的成员方法
  32. console.log(person1.run())
  33. // 创建子类1的对象
  34. const student = new Student('李四')
  35. console.log(student.run())
  36. })()
  37. one.ts(20,9): error TS2415: Class 'Student' incorrectly extends base class 'Person'.
  38. Property 'run' is private in type 'Person' but not in type 'Student'.
  39. one.ts(20,25): error TS2675: Cannot extend a class 'Person'. Class constructor is marked as private.
  40. one.ts(28,30): error TS2341: Property 'name' is private and only accessible within class 'Person'.
  41. one.ts(32,27): error TS2673: Constructor of class 'Person' is private and only accessible within the class declaration.
  42. one.ts(34,23): error TS2341: Property 'name' is private and only accessible within class 'Person'.
  43. one.ts(36,23): error TS2341: Property 'run' is private and only accessible within class 'Person'.
  • 外部和子类访问均报错

    protected(类内部和子类可以访问)

    1. (() => {
    2. // 定义一个父类(超类)
    3. class Person {
    4. // 定义属性
    5. protected name: string
    6. // 构造方法,实例化对象的时候,直接对属性的值进行初始化
    7. protected constructor(name: string) {
    8. // 更新对象中的属性数据
    9. this.name = name
    10. }
    11. // 实例方法
    12. protected run(num: number = 0): string {
    13. return '大家好,我叫' + this.name + '我跑了' + num + '米'
    14. }
    15. }
    16. // 定义第一个子类(派生类)
    17. class Student extends Person {
    18. // 调用父类中的构造函数
    19. constructor(name: string) {
    20. super(name);
    21. }
    22. // 重写父类中的方法
    23. run(num: number = 5): string {
    24. return '大家好,我叫' + this.name + '我跑了' + num + '米'
    25. }
    26. }
    27. // 创建父类的实例
    28. const person1: Person = new Person('张三')
    29. // 类的外部访问类中的成员属性
    30. console.log(person1.name)
    31. // 类的外部访问类中的成员方法
    32. console.log(person1.run())
    33. // 创建子类的对象
    34. const student = new Student('李四')
    35. console.log(student.run())
    36. })()
    37. // 输出结果
    38. // one.ts(32,27): error TS2674: Constructor of class 'Person' is protected and only accessible within the class declaration.
    39. // one.ts(34,23): error TS2445: Property 'name' is protected and only accessible within class 'Person' and its subclasses.
    40. // one.ts(36,23): error TS2445: Property 'run' is protected and only accessible within class 'Person' and its subclasses.
  • 子类使用正常,外部使用报错

    readonly

    readonly关键字将属性设置为只读的。 只读属性必须在声明时或构造函数里被初始化。外部不能修改属性值,内部普通方法也不能修改,只能在创建对象初始化时,指定属性的值

  1. (() => {
  2. // 定义一个父类(超类)
  3. class Person {
  4. // 定义属性
  5. readonly name: string
  6. // 构造方法,实例化对象的时候,直接对属性的值进行初始化
  7. constructor(name: string) {
  8. // 更新对象中的属性数据
  9. this.name = name
  10. }
  11. // 实例方法
  12. run(): string {
  13. // 类内部方法修改成员属性
  14. return this.name = 'abc'
  15. }
  16. }
  17. // 创建父类的实例
  18. const person1: Person = new Person('张三')
  19. // 类的外部访问类中的成员属性
  20. console.log(person1.name)
  21. // 修改实例的属性
  22. person1.name = '李四'
  23. console.log(person1.name)
  24. })()
  25. // 输出结果
  26. // one.ts(14,19): error TS2540: Cannot assign to 'name' because it is a read-only property.
  27. // one.ts(22,11): error TS2540: Cannot assign to 'name' because it is a read-only property.

存取器

通过 getters/setters 来截取对对象成员的访问。用于控制对对象成员的访问。

  1. (() => {
  2. // 外部可以传入姓氏和名字,使用set和get控制姓名数据,外部可以访问和修改
  3. class Person{
  4. firstName:string // 姓
  5. lastName:string // 名
  6. constructor(firstName:string,lastName:string) {
  7. this.firstName = firstName
  8. this.lastName = lastName
  9. }
  10. // 读取器——负责数据读取
  11. get fullName(){
  12. return this.firstName + '-' + this.lastName
  13. }
  14. // 设置器——负责数据的修改
  15. set fullName(val){
  16. let names = val.split('-')
  17. this.firstName = names[0]
  18. this.lastName = names[1]
  19. }
  20. }
  21. // 实例化对象
  22. const person:Person = new Person('东方','不败')
  23. // 获取对象的成员属性
  24. console.log(person.fullName)
  25. // 设置属性的数据
  26. person.fullName = '诸葛-孔明'
  27. console.log(person.fullName)
  28. })()
  29. // 输出结果
  30. // 东方-不败
  31. // 诸葛-孔明

静态属性与方法

通过static修饰的属性和方法,在使用时直接通过类名.的方式调用

  1. /*
  2. 静态属性, 是类对象的属性
  3. 非静态属性, 是类的实例对象的属性
  4. */
  5. (() => {
  6. // 定义一个类
  7. class Person{
  8. // 定义一个静态属性。类中默认有一个内置的name静态属性,不能冲突
  9. static names:string = '张三'
  10. // 定义一个静态方法
  11. static sayHi(){
  12. console.log('Hi')
  13. }
  14. }
  15. // 调用类的静态属性
  16. console.log(Person.names)
  17. // 设置类的静态属性值
  18. Person.names = '李四'
  19. console.log(Person.names)
  20. // 调用类的静态方法
  21. Person.sayHi()
  22. })()
  23. // 输出结果
  24. // 张三
  25. // 李四
  26. // Hi

抽象类

抽象类做为其它派生类的基类使用。 它们不能被实例化。不同于接口,抽象类可以包含成员的实现细节。 abstract 关键字是用于定义抽象类和在抽象类内部定义抽象方法

  1. /*
  2. 抽象类
  3. 不能创建实例对象, 只有实现类才能创建实例
  4. 可以包含未实现的抽象方法
  5. */
  6. (() => {
  7. // 定义一个抽象父类
  8. abstract class Person{
  9. // 定义一个抽象方法(抽象类中只定义,不能有具体的实现)
  10. abstract run()
  11. // 定义一个实例方法
  12. sayHi(){
  13. console.log('Hi')
  14. }
  15. }
  16. // 定义一个子类(派生类)
  17. class Student extends Person{
  18. // 重新实现抽象类中的方法,此时这个方法就是当前Person类的实例方法
  19. run(){
  20. console.log('整齐的跑')
  21. }
  22. }
  23. // 实例化student对象
  24. const student:Student = new Student()
  25. student.sayHi()
  26. // 调用抽象类中的实例方法
  27. student.run()
  28. })()
  29. // 输出结果
  30. // Hi
  31. // 整齐的跑