问题

  • public, private, protected的用法和注意事项,适用场景
  • 抽象对象的用法
  • 接口的用法
  • 抽象对象和接口的区别

修饰符

所谓在类的外部访问,也就是通过实例person.xxx的形式访问

public

在类的外部可以访问

private 不可读写

  • 不能在类的外部访问,即不能通过person.name访问,能通过person.getName()方法访问
  • 子类的内部、外部都不能访问
  • 当构造函数修饰为 private 时,该类不允许被继承或者实例化:

    protected

  • 与private类似

  • 不同的是可以在子类的内部访问,外部也不能访问
  • protected constructor 构造函数被标记为constructor,这个类不能被实例化,即不能new Person(),但是可以继承 class Employee extends Person

    readonly 只读 (包括类与接口中)

  • 只读不可写(写:只能在声明时或构造函数里被初始化)

    super

    子类的构造函数中用 super(name) ,调用父类的constructor;
    子类的方法中,调用 super.someExtendsFunc() ,效果和 this.someExtendsFunc() 一样

参数属性

通过给构造函数参数添加一个访问限定符来声明,相当于把变量定义和在构造函数中初始化简写为一步。

  1. class Animal {
  2. // 这里的name是构造函数参数
  3. // 声明了一个同名的私有属性
  4. constructor(private name: string) { }
  5. move(distanceInMeters: number) {
  6. console.log(`${this.name} moved ${distanceInMeters}m.`);
  7. }
  8. }

存取器

通过设置get, set,即使成员变量是public,也会限制在类的外部set(通过鉴证password等方法)。
首先,存取器要求你将编译器设置为输出ECMAScript 5或更高。 不支持降级到ECMAScript 3。 其次,只带有get不带有set的存取器自动被推断为readonly。

抽象类与接口的区别

接口和抽象类有什么区别?
java的接口和抽象类有什么区别?

  • 门和警报的例子
  • 抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类主要用来继承、复用。
  • 继承是一个 “是不是”的关系,而 接口 实现则是 “有没有”的关系。接口主要用来约束行为。

    抽象类

    用来被继承,相当于建立一个类的模子,就像一个接口是建立一个对象的模子一个道理。

  • 子类的构造函数中必须调用super()

  • 子类中必须实现抽象类定义的抽象方法
  • 抽象类中没有定义的方法,子类中无法实现
  • 抽象方法 的语法与接口方法相似,两者都是定义方法签名但不包含方法体
  • 不同于接口,抽象类可以包含成员的实现细节——即包含非抽象方法(包含方法体)。
  • 抽象类中的 抽象方法 不包含具体实现并且 必须 在派生类中实现

    1. abstract class Animal {
    2. abstract makeSound(): void;
    3. move(): void {
    4. console.log("roaming the earth...");
    5. }
    6. }

    接口(java中)

  • 接口中的变量会被隐式地指定为public static final变量(并且只能是public static final变量)。

  • 方法会被隐式地指定为public abstract方法且只能是public abstract方法(用其他关键字),一般情况下不在接口中定义变量。
  • 如果一个非抽象类遵循了某个接口,就必须实现该接口中的所有方法。
  • Java8的interface新特性 新 interface 的方法可以用default 或 static修饰

类与接口

接口的两种模式:

  1. 对「对象的形状(Shape)」进行描述
  2. 类的一部分行为进行抽象

把不同类之间可以有一些共有的特性,这时候就可以把特性提取成接口。这个接口相当于一个抽象类中的抽象方法。
implements 实现

一个类可以实现1个、多个接口

接口继承接口

接口继承类(把类当做接口使用)

  1. class Point {
  2. x: number;
  3. y: number;
  4. }
  5. interface Point3d extends Point {
  6. z: number;
  7. }
  8. let point3d: Point3d = {x: 1, y: 2, z: 3};

类与接口的使用

  • 定义数据模型的话,不仅为了编辑器的智能提示和类型检查
  • 可以直接new对应实例
  • 在ts中,class编译后,在js中依然能找到

    接口

  • 定义数据模型的话,大部分功能只是为了编辑器的智能提示和类型检查

  • 在ts中,interface编译后,就不存在了

    创建对象

  • 接口:对「对象的形状(Shape)」进行描述

  • 类:也可作为类型定义
  1. 接口/类 + 对象字面量创建:所有属性都要写
  2. 类 + new()方式创建: 只写构造函数中的属性

    对类的一部分行为进行抽象

  • 使用接口

declare class和interface的区别

declare class语法实际上是用于为未在TypeScript中编写的外部代码添加类型定义 - 因此实现在其他地方
例如jQuery等插件,不是本身这个项目使用,而是引用他的地方使用

接口interface和type的区别

typescript 中的 interface 和 type 到底有什么区别
个人认为两种场景可能会使用到type而不能用interface:我的评论

  1. 具体定义数组每个位置的类型

    1. type PetList = [Dog, Pet]
  2. 限定具体几个值的基本类型联合类型

    1. type someAnimal = 'dog' | 'cat'

    练习

    course01

组合与继承

组合优于继承的例子,鸭子
java继承和组合的区别,看两个例子,你就明白了
template method 模板方法

Practice

  1. let bookTags: string[] = ['畅销', '经典', '必读'];
  2. let bookGrades: Array < number > = [1, 2, 3, 4, 5];
  3. // 接口:对「对象的形状(Shape)」进行描述
  4. interface Production {
  5. // 对象中只读
  6. readonly name: string,
  7. author: string,
  8. category: string,
  9. edition ? : string;
  10. repertery ? : number | boolean;
  11. [propName: string]: any;
  12. }
  13. class Library {
  14. // 静态私有属性
  15. private static language = 'Chinese';
  16. private buildingHeight: number = 18;
  17. // 参数属性
  18. constructor(
  19. private name: string,
  20. private address: string,
  21. ) {}
  22. getName(): string {
  23. return this.name;
  24. }
  25. getAddress(): string {
  26. return this.address;
  27. }
  28. // getter
  29. get generation(): number {
  30. return this.generation;
  31. }
  32. // setter
  33. set generation(value: number) {
  34. console.log('generation is updated');
  35. }
  36. }
  37. let createLibrary: () => void = () => {
  38. let library: Library = new Library('Deepdraw Library', 'ChengDu');
  39. // 内部访问private属性address
  40. console.log("library's name: " + library.getAddress());
  41. // address为private属性,外部不能访问(读)
  42. console.log("library's address" + library.address);
  43. // address为private属性,外部不能访问(写)
  44. library.address = '成都';
  45. // 静态私有属性外部也不能访问
  46. console.log("library'S buildingHeight" + library.buildingHeight);
  47. // getter行为
  48. console.log(library.generation);
  49. // setter行为
  50. library.generation = 6;
  51. }
  52. class Book {
  53. readonly name: string;
  54. private author: string;
  55. protected category: string;
  56. static isBook(book: Book): boolean {
  57. return book instanceof Book;
  58. }
  59. constructor(
  60. private id: string,
  61. detail: Production
  62. ) {
  63. this.name = detail.name;
  64. this.author = detail.author;
  65. this.category = detail.category;
  66. }
  67. getAuthor(): string {
  68. return this.author;
  69. }
  70. getCategory(): string {
  71. return this.category;
  72. }
  73. }
  74. class ITBook extends Book {
  75. static difficulty: number = 5;
  76. private buyer: string = 'software developer';
  77. private seller: string = '孔夫子';
  78. constructor(private sId: string, detail: Production) {
  79. // 调用父类的constructor
  80. super(sId, detail);
  81. }
  82. getParent() {
  83. // readyonly属性,子类的内部可以访问
  84. console.log(this.name);
  85. // private属性,子类的内部也不能访问
  86. console.log(this.id);
  87. // private属性,子类的内部也不能访问
  88. console.log(this.author);
  89. // protected属性,子类的内部可以访问
  90. console.log(this.category);
  91. }
  92. // names是父类的只读属性,子类继承后可以读
  93. // buyer, seller是子类的private属性,子类内部可以访问
  94. getWholeInfo(): string {
  95. return `${this.name} for ${this.buyer}, and the seller is ${this.seller}`;
  96. }
  97. }
  98. class JSBook extends ITBook {
  99. protected constructor(
  100. private ssId: string,
  101. detail: Production,
  102. private rate: number
  103. ) {
  104. super(ssId, detail);
  105. }
  106. }
  107. function addCommonBook(): Book {
  108. let bookDetail: Production = {
  109. name: '鲁迅选集',
  110. author: '鲁迅',
  111. category: '文学',
  112. edition: '1900'
  113. }
  114. let book = new Book('01', bookDetail);
  115. // readonly属性name,可以读
  116. console.log("book name is" + book.name);
  117. // readonly属性name,不能写
  118. book.name = 'readonly属性name不能修改';
  119. // private属性author,内部可以访问
  120. console.log("book'category is: " + book.getAuthor());
  121. // protected属性category,内部可以访问
  122. console.log("book'category is: " + book.getCategory());
  123. // privatge, protected属性,外部不能访问
  124. console.log(book.author);
  125. console.log(book.category);
  126. return book;
  127. }
  128. function addITBook(): ITBook {
  129. let bookDetail = {
  130. name: '前端攻城狮',
  131. author: '严靖',
  132. category: '计算机'
  133. }
  134. let frontEndBook = new ITBook('001', bookDetail);
  135. // 静态公有属性,鉴别是否子类
  136. console.log('is instance of Book?', Book.isBook(frontEndBook));
  137. // buyer, seller, 子类的private属性,子类内部可以访问
  138. console.log("book's whole infomation: " + frontEndBook.getWholeInfo());
  139. // 检查子类的内部是否可以访问派生属性
  140. frontEndBook.getParent();
  141. return frontEndBook;
  142. }
  143. // 当构造函数修饰为 private 时,该类不允许被继承或者实例化:
  144. // 当构造函数修饰为 protected 时,该类只允许被继承
  145. function addJSBook(): void {
  146. let professionalJSBook = new JSBook();
  147. }
  148. interface BookKeyWords {
  149. (tag: string, rate: number): string;
  150. }
  151. let createBookCategory: BookKeyWords = (tag: string = '经典', rate?: number): string => {
  152. return tag + rate;
  153. }
  154. createLibrary();
  155. addCommonBook();
  156. addITBook();

泛型单例及new()类型

new()是什么
泛型单例