TypeScript躬行记(3)——类
类是对对象的抽象,描述了对象的特征和行为,而对象就是类的实例。ES6引入了类的概念(相关内容可参考ES类和ES6类的继承两节),TypeScript在此基础上,不仅根据ES7等规范完善了类的语法,还添加了许多其它语法。而在使用TypeScript的类时,不必关心兼容性问题,因为这些工作已由编译器完成。
下面是一个简单的类,包含3个成员:带private修饰符的name属性、构造函数constructor()和getName()方法,最后一句使用new运算符创建了Person类的实例,并调用了一次它的构造函数。
class Person {
private name: string;
constructor(name: string) {
this.name = name;
}
getName() {
return this.name;
}
}
let worker = new Person("strick");
编译后的代码如下所示,通过传统的构造函数和基于原型的继承来模拟一个类。
var Person = /** @class */ (function() {
function Person(name) {
this.name = name;
}
Person.prototype.getName = function() {
return this.name;
};
return Person;
})();
var worker = new Person("strick");
一、属性
在ES6中,实例属性(即自有属性)得作为this对象的属性存在,并且一般都会在构造函数中执行初始化,而TypeScript允许在类中直接定义实例属性,如下所示。
class Person {
constructor(name: string) {
this.name = name;
}
}
//TypeScript中的实例属性
class Person {
name: string;
}
不仅如此,TypeScript还提供了存在于类本身上的静态属性,即不需要实例化就能调用的属性。在下面的示例中,为age属性添加了static关键字,使其成为静态属性,通过类的名称就能直接调用它。
class Person {
static age: number;
}
Person.age = ;
二、修饰符
修饰符是用于限定成员或类型的一种符号,TypeScript包含三个访问修饰符:public、private和protected,以及一个成员修饰符:readonly。
1)public
在TypeScript中,成员默认都是public的,即在派生类(也叫子类)或类的外部都能被访问。在下面的示例中,Person类中的name属性是公共的,Programmer类继承了Person类。注意,当派生类包含一个构造函数时,必须调用super()方法,执行基类(即父类)的构造函数,并且该方法得在访问this对象之前调用。
class Person {
public name: string;
constructor(name: string) {
this.name = name;
}
}
class Programmer extends Person {
constructor(name: string) {
super(name);
}
}
在初始化Person类或Programmer类之后,就能通过创建的实例来访问name属性,如下所示。
let person = new Person("strick");
person.name; //"strick"
let programmer = new Programmer("freedom");
programmer.name; //"freedom"
2)private
当成员被修饰为private时,只能在类的内部访问它,例如在基类Person中声明一个私有的age属性,在类的实例或派生类的实例中访问age属性都会在编译阶段报错,如下所示。
class Person {
private age: number;
}
person.age; //错误
programmer.age; //错误
当构造函数被修饰为private时(如下所示),包含它的类既不能实例化,也不能被继承。
class Person {
private constructor(name: string) {
this.name = name;
}
}
3)protected
此修饰符与private的行为类似,只是有一点不同,即在派生类中还是可以访问它的,例如在基类Person中声明一个受保护的school属性,在派生类中就能访问到它,如下所示(省略了基类的构造函数)。
class Person {
protected school: string;
}
class Programmer extends Person {
constructor(name: string) {
super(name);
this.school = "university";
}
}
当构造函数被修饰为protected时(如下所示),包含它的类不能实例化,但可以被继承。
class Person {
protected constructor(name: string) {
this.name = name;
}
}
4)readonly
当成员被修饰为readonly时,它就变成只读的,只能在声明时或构造函数里初始化,其它地方对它的修改都是禁止的,如下所示。
class Person {
readonly gender: string = "女"; //正确
constructor() {
this.gender = "男"; //正确
}
}
let person = new Person();
person.gender = "女"; //错误
当readonly与其它修饰符一起使用时,需跟在它们后面,如下所示。
class Person {
protected readonly gender: string;
}
三、参数属性
参数属性可以便捷的在构造函数中声明并初始化一个类的属性,此类参数会与三个访问修饰符或readonly组合使用,如下所示。
class Person {
constructor(public name: string) { }
}
构造函数中的name是一个参数属性,相当于在Person类中声明一个name属性,并在构造函数中为其初始化,如下所示。
class Person {
public name: string;
constructor(name: string) {
this.name = name;
}
}
四、抽象类
抽象类是供其它派生类继承的基类,它与接口一样,不能被实例化,但可以包含成员的实现细节。在声明一个类时,如果包含abstract关键字,那么这就是一个抽象类,如下所示,当对其进行实例化时,会在编译时报错。
abstract class Person { }
let person = new Person(); //错误
在抽象类中,会声明一个或多个带abstract类修饰符的抽象方法,它们只有名称,不包含实现细节,可与访问修饰符组合使用,如下所示。
abstract class Person {
protected abstract work(): void
}
派生类中必须实现继承的抽象方法(如下所示),否则会在编译阶段报错。
class Programmer extends Person {
public work(): void {
console.log("code");
}
}
TypeScript躬行记(3)——类的更多相关文章
- TypeScript躬行记(8)——装饰器
装饰器(Decorator)可声明在类及其成员(例如属性.方法等)之上,为它们提供一种标注,用于分离复杂逻辑或附加额外逻辑,其语法形式为@expression.expression是一个会在运行时被调 ...
- TypeScript躬行记(1)——数据类型
TypeScript不仅支持JavaScript所包含的数据类型,还额外扩展了许多实用的数据类型,例如枚举.空值.任意值等. 一.JavaScript的数据类型 JavaScript的数据类型包括6种 ...
- TypeScript躬行记(2)——接口
在传统的面向对象语言中,接口(Interface)好比协议,它会列出一系列的规则(即对行为进行抽象),再由类来实现这些规则.而TypeScript中的接口更加灵活,除了包含常规的作用之外,它还能扩展其 ...
- TypeScript躬行记(5)——类型兼容性
TypeScript是一种基于结构类型的语言,可根据其成员来描述类型.以结构相同的Person接口和Programmer类为例,如下所示. interface Person { name: strin ...
- TypeScript躬行记(7)——命名空间
TypeScript中的命名空间可将那些具有内在联系的接口.类或对象等代码组织在一起,既能隔离作用域,也能避免命名冲突,并且使得代码结构清晰,更易追踪.在命名空间内部,所有实体部分默认都是私有的,需要 ...
- TypeScript躬行记(6)——高级类型
本节将对TypeScript中类型的高级特性做详细讲解,包括交叉类型.类型别名.类型保护等. 一.交叉类型 交叉类型(Intersection Type)是将多个类型通过“&”符号合并成一个新 ...
- TypeScript躬行记(4)——泛型
泛型是程序设计语言中的一种风格或范式,相当于类型模板,允许在声明类.接口或函数等成员时忽略类型,而在未来使用时再指定类型,其主要目的是为它们提供有意义的约束,提升代码的可重用性. 一.泛型参数 当一个 ...
- ES6躬行记(1)——let和const
古语云:“纸上得来终觉浅,绝知此事要躬行”.的确,不管看了多少本书,如果自己不实践,那么就很难领会其中的精髓.自己研读过许多ES6相关的书籍和资料,平时工作中也会用到,但在用到时经常需要上搜索引擎中查 ...
- ES6躬行记 笔记
ES6躬行记(18)--迭代器 要实现以下接口## next() ,return,throw 可以用for-of保证迭代对象的正确性 例如 var str = "向
随机推荐
- react antd Table动态合并单元格
示例数据 原始数组 const data = [ { key: '0', name: 'John Brown', age:22, address: 'New York No. 1 Lake Park' ...
- OpenStack集成ceph
openstack组件集成ceph OpenStack集成ceph详细过程可以查看ceph官方文档:ceph document OpenStack Queens版本,1台控制节点controller, ...
- 2019-10-10:渗透测试,基础学习,mysql语法基础,笔记
mysql常用命令mysql -u用户名 -p,登录方式也称为,二进制方式exit 退出mysql 查看mysql版本select version(); 查看mysql所有数据库show dateba ...
- Chapter 07-Basic statistics(Part4 t-tests&&nonparametric tests of group difference)
一. t-tests 这一部分我们使用分布在MASS包中的UScrime数据集.它是关于美国47个州在1960年时,关于惩罚制度对犯罪率的影响. Prob:监禁(坐牢)的概率: U1:14到24岁的城 ...
- 微信小程序——动态修改页面数据(和样式)及参数传递
1.1.1动态修改页面数据 在小程序中我们经常要动态渲染数据,对于新手而言我们常常遇到修改的数据在控制台显示和页面显示不一致,因为我们用“=”修改数据的,这种是可以修改,但无法改变页面的状态的,还会造 ...
- 带着canvas去流浪系列之四 绘制散点图
[摘要] 用原生canvasAPI实现百度Echarts图表 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvasAPI ...
- 带着canvas去流浪系列之六 绘制雷达图
[摘要] 用canvas原生API实现百度Echarts基本图表. 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvas ...
- 上手spring boot项目(一)之如何在controller类中返回到页面
题记:在学习了springboot和thymeleaf之后,想完成一个项目练练手,于是使用springboot+mybatis和thymeleaf完成一个博客系统,在完成的过程中出现的一些问题,将这些 ...
- 整合多个maven工程时Spring配置加载JDBC问题
问题叙述: 两个工程都通过JDBC访问mysql数据库,各自运行OK, 但合并成一个maven工程后,发现前一个工程访问数据库异常,貌似拿不到自己的DAO. 解决办法: 发现这两个工程的xml配置中, ...
- Golang中的布隆过滤器
目录 1. 布隆过滤器的概念 2. 布隆过滤器应用场景 3. 布隆过滤器工作原理 4. 布隆过滤器的优缺点 5. 布隆过滤器注意事项 6. Go实现布隆过滤器 1. 布隆过滤器的概念 布隆过滤器(Bl ...