TypeScript 学习笔记6: Classes
2017-07-03 12:03
337 查看
原文链接:https://leanpub.com/essentialtypescript/read#leanpub-auto-classes
TypeScript 提供了三种方式创建 custom type:interface,enum,class。
class 是ECMAScript 2015 提供的 syntactic sugar,它不是TypeScript引入的新概念。
说明:
1. constructor() 是构造函数;
2. todo: Todo[] = []; 定义了一个属性,并赋予初值;
3. ge
4000
tAll() 定义了一个成员函数,注意,函数名前面不用写 function 前缀。
对于上面代码中的第2行和第5行,TypeScript 提供了一种便捷的写法:
在constructor 的参数前面加一个访问限定符(private),会自动做两件事:
1. 创建 todos 属性;
2. 创建新的对象时,把构造函数的参数赋值给 todos 属性。
看看TypeScript生成的ES5代码:
说明:
1. static lastId: number = 0; 定义了一个静态成员 lastId,所有的TodoService对象共享这个成员;
2. static getNextId() 定义了一个静态成员函数;
3. 在 add() 方法中使用静态成员函数。
说明:
1. 这里定义了 state 属性;
2. get 和 set 不必成对出现,可以只定义get,也可以只定义set;
3. state保存在 _state 属性中,通常以下划线开头的属性名是私有的内部使用的;
4. 添加了accessor之后,state属性的访问方法没有变化,代码的最后两行给出了使用方法。
这个例子好像是”state模式”哈?
说明:
1. 继承基类使用 extends 关键字;
2. 调用基类的方法,使用 super 关键字;
说明:
1. class 前面的abstract,声明这个类是abstract的,不能实例化;
2. canChangeState() 前面的abstract,说明基类中声明了这个接口,但没有实现,每一个子类必须实现这个方法。
1. private, 只有自己的成员函数可以访问;
2. protected, 自己的派生类可以访问;
3. public,公开的,任何地方都可以访问。
4. 第二小节中的 constructor(private todos: Todo[]),用到了private 限定符,也可以用protected或public。
5. static 成员也可以加访问限定符。
说明:
1. 用 implements 连接类名和接口名;
2. 一个类可以实现多个接口,中间用逗号分隔。
TypeScript 提供了三种方式创建 custom type:interface,enum,class。
class 是ECMAScript 2015 提供的 syntactic sugar,它不是TypeScript引入的新概念。
1. Prototypical Inheritance
JavaScript 本身已经提供了面向对象的语法:对象、构造函数、prototype、属性、方法、继承、重载等等。这一小节讲了ES5实现面向对象的方法。(略过)2. Defining a class
class TodoService { todos: Todo[] = []; constructor(todos: Todo[]) { this.todos = todos; } getAll() { return this.todos; } }
说明:
1. constructor() 是构造函数;
2. todo: Todo[] = []; 定义了一个属性,并赋予初值;
3. ge
4000
tAll() 定义了一个成员函数,注意,函数名前面不用写 function 前缀。
对于上面代码中的第2行和第5行,TypeScript 提供了一种便捷的写法:
class TodoService { constructor(private todos: Todo[]) { } getAll() { return this.todos; } }
在constructor 的参数前面加一个访问限定符(private),会自动做两件事:
1. 创建 todos 属性;
2. 创建新的对象时,把构造函数的参数赋值给 todos 属性。
看看TypeScript生成的ES5代码:
var TodoService = (function () { function TodoService(todos) { this.todos = todos; } TodoService.prototype.getAll = function () { return this.todos; }; return TodoService; }());
3. 静态成员/方法
class TodoService { static lastId: number = 0; constructor(private todos: Todo[]) { } static getNextId() { return TodoService.lastId += 1; } add(todo: Todo) { var newId = TodoService.getNextId(); // ... } getAll() { return this.todos; } }
说明:
1. static lastId: number = 0; 定义了一个静态成员 lastId,所有的TodoService对象共享这个成员;
2. static getNextId() 定义了一个静态成员函数;
3. 在 add() 方法中使用静态成员函数。
4. accessors
4.1 在 object 中使用get/set
var todo = { name: "Pick up drycleaning", get state() { return this._state; }, set state(newState) { if(newState == TodoState.Complete) { var canBeCompleted = this._state == TodoState.Active || this._state == TodoState.Deleted; if(!canBeCompleted) { throw 'Todo must be Active or Deleted in order to be marked as Completed.'; } } this._state = newState; } }; todo.state = TodoState.Active; console.log(todo.state);
说明:
1. 这里定义了 state 属性;
2. get 和 set 不必成对出现,可以只定义get,也可以只定义set;
3. state保存在 _state 属性中,通常以下划线开头的属性名是私有的内部使用的;
4. 添加了accessor之后,state属性的访问方法没有变化,代码的最后两行给出了使用方法。
4.2 在class 中使用accessor
在对象中使用accessor没什么用处,写到class中才是正途。语法一样。class SmartTodo { name: string; _state: TodoState = TodoState.New; constructor(name: string) { this.name = name; } get state() { return this._state; } set state(newState) { if(newState == TodoState.Complete) { var canBeCompleted = this._state == TodoState.Active || this._state == TodoState.Deleted; if(!canBeCompleted) { throw 'Todo must be Active or Deleted in order to be marked as Completed.'; } } this._state = newState; } }; var todo = new SmartTodo("Pick up drycleaning"); todo.state = TodoState.New; todo.state = TodoState.Complete; // BOOM! 抛出异常
5. 继承
class TodoStateChanger { constructor(private newState: TodoState) { } canChangeState(todo: Todo): boolean { return !!todo; } changeState(todo: Todo): Todo { if(this.canChangeState(todo)) { todo.state = this.newState; } return todo; } } class CompleteTodoStateChanger extends TodoStateChanger { constructor() { super(TodoState.Complete); } canChangeState(todo: Todo): boolean { return super.canChangeState(todo) && (todo.state == TodoState.Active || todo.state == TodoState.Deleted); } }
这个例子好像是”state模式”哈?
说明:
1. 继承基类使用 extends 关键字;
2. 调用基类的方法,使用 super 关键字;
6. abstract class
按照 state模式,我们应该给每种state定义一个类,直接创建基类(TodoStateChanger)的对象是没有意义的。用abstract关键字,可以阻止创建一个类的实例:abstract class TodoStateChanger { constructor(private newState: TodoState) { } abstract canChangeState(todo: Todo): boolean; changeState(todo: Todo): Todo { if(this.canChangeState(todo)) { todo.state = this.newState; } return todo; } } class CompleteTodoStateChanger extends TodoStateChanger { constructor() { super(TodoState.Complete); } canChangeState(todo: Todo): boolean { return !!todo && (todo.state == TodoState.Active || todo.state == TodoState.Deleted); } }
说明:
1. class 前面的abstract,声明这个类是abstract的,不能实例化;
2. canChangeState() 前面的abstract,说明基类中声明了这个接口,但没有实现,每一个子类必须实现这个方法。
7. 访问限定符
放在属性/方法前面,控制它们的可访问性:1. private, 只有自己的成员函数可以访问;
2. protected, 自己的派生类可以访问;
3. public,公开的,任何地方都可以访问。
4. 第二小节中的 constructor(private todos: Todo[]),用到了private 限定符,也可以用protected或public。
5. static 成员也可以加访问限定符。
private static lastId = 0; private get state() { } private set state(newState) { } private getAll() { }
8. 实现 interfaces
interface ITodoService { add(todo: Todo): Todo; delete(todoId: number): void; getAll(): Todo[]; getById(todoId: number): Todo; } interface IIdGenerator { nextId: number; } class TodoService implements ITodoService, IIdGenerator { static _lastId: number = 0; constructor(private todos: Todo[]) { } get nextId(): number { return TodoService._lastId += 1; } add(todo: Todo) { todo.id = this.nextId; this.todos.push(todo); return todo; } getAll(): Todo[] { return this.todos; } delete(todoId: number) { var toDelete = this.getById(todoId); var toDeleteIndex = this.todos.indexOf(toDelete); this.todos.splice(toDeleteIndex, 1); } getById(todoId: number): Todo { var filtered = this.todos.filter(x => x.id == todoId); if(filtered.length) { return filtered[0]; } return null; } }
说明:
1. 用 implements 连接类名和接口名;
2. 一个类可以实现多个接口,中间用逗号分隔。
相关文章推荐
- ios开发学习笔记⑤-因为我太傻逼所以不会用storyboard中的use size classes
- thinkCSpy学习笔记: Chapter 14 Classes and functions 类和函数
- Python Turorial 学习笔记8 --Classes
- Swift3.0学习笔记-Classes and Structures
- angular2 学习笔记 (Typescript)
- TypeScript 学习笔记 之插件安装
- WTL for MFC Programmers 学习笔记(二) Part II WTL GUI Base Classes
- Java学习笔记(13)Abstract Classes and Interfaces
- TypeScript学习笔记之变量声明
- 学习笔记——Python」Python中的类(classes)
- 深度学习论文笔记-Deep Learning Face Representation from Predicting 10,000 Classes
- TypeScript 学习笔记之基本类型
- [Egret学习笔记 八]TypeScript与JavaScript通讯
- TypeScript学习笔记一
- TypeScript 学习笔记
- Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value
- TypeScript 学习笔记之基本类型
- thinkCSpy学习笔记: Chapter 15 Classes and methods 类和方法
- TypeScript学习笔记之环境搭建
- TypeScript 学习笔记