TypeScript入门四:TypeScript的类(class)
- TypeScript类的基本使用(修饰符)
- TypeScript类的抽象类(abstract)
- TypeScript类的高级技巧
一、TypeScript类的基本使用(修饰符)
TypeScript的类与ES6的类非常类是,所以建议先了解ES6的类的相关内容:ES6入门六:class的基本语法、继承、私有与静态属性、修饰器。
1.最简单的TypeScript的类示例与ES6实现对比:
class tsClass{
public a:string ; //公有成员
private b:number[] ; //私有成员
protected c:string[] ; //被保护的成员
static e:string = 'e'; //静态属性
constructor(astr:string,barr:number[],carr:string[]){
this.a = astr;
this.b = barr;
this.c = carr;
}
}
class SublevelCla extends tsClass {
private dname: string; //私有成员
constructor (astr:string,barr:number[],carr:string[],dname:string){
super(astr,barr,carr);//继承tsClass构造字段
this.dname = dname;//sublevelCla自身构造字段
}
fun():void{
console.log(tsClass.e);//通过类获取静态成员
}
} let sub = new SublevelCla('a',[1,2,3],['a','b','c'],'sublevelName');
sub.fun();
console.log(sub.a);
// console.log(sub.b); //报错:私有成员不能被外部访问
// console.log(sub.c); //报错:被保护的成员不能被外部访问
// console.log(sub.dname); //报错:私有成员不能被外部访问
Ts类与Js类的修饰符对比:
Ts有公共成员(public)修饰符;Js没有该修饰符,但可以在构造函数constructor内直接使用this定义公共成员,用于生成每个实例对象的属性。
Ts有私有成员(private)修饰符;Js的私有成员修饰符是(#),该成员只能在当前类中使用,TS与JS没有区别。
Ts有受保护成员(protected)修饰符;Js没有该修饰符,也没有对应的成员语法。在Ts中受保护成员可以被字类访问在子类中使用,但不能被实例对象在外部访问。
Ts有静态成员(static)修饰符;Js中也有同样的修饰符,该成员最终被解析到类的自身属性上(解析成ES5的话就是函数的属性),静态属性可以被类名直接在任何地方引用。
Ts有只读成员(readonly)修饰符;Js中没有该修饰符,但是可以通过属性访问器get来实现。
//js示例代码
class jsClass{
#b ;
#c ;
static e = 'e';
constructor(astr,barr,carr,){
this.a = astr;
this.#b = barr;
this.#c = carr;
}
} class jsSubc extends jsClass{
constructor(astr,barr,carr,dname){
super(astr,barr,carr);
this.dname = dname;
}
fun(){
console.log(jsClass.e);
}
}
let jsub = new jsSubc('a',[1,2,3],['a','b','c'],'sublevelName');
jsub.fun();
console.log(jsub.a);
// console.log(jsub.b);//undefined
关于类的继承在Ts和Js中都是使用extends关键字,并且在构造函数中使用super方法实现构造继承,这个方法都必须写在字类构造函数内的最前面。
Ts受保护的成员的使用方式就是通过添加到父类构造函数,然后字类构造继承该成员,在子类中就能使用this关键字访问该成员了,子类中不需要再在自生声明该成员了。
//这个官方示例完美的展示了受保护成员的应用
class Person {
protected name: string;
constructor(name: string) { this.name = name; }
} class Employee extends Person {
private department: string; constructor(name: string, department: string) {
super(name)
this.department = department;
} public getElevatorPitch() {
return `Hello, my name is ${this.name} and I work in ${this.department}.`;
}
} let howard = new Employee("Howard", "Sales");
console.log(howard.getElevatorPitch());
console.log(howard.name); // 错误
Ts只读成员示例在官方文档中也有非常好的示例,这里直接复制展示该示例:
class Octopus {
readonly name: string;
readonly numberOfLegs: number = 8;
constructor (theName: string) {
this.name = theName;
}
}
let dad = new Octopus("Man with the 8 strong legs");
dad.name = "Man with the 3-piece suit"; // 错误! name 是只读的.
同样Ts中也可以使用set与get作为存取器,通过属性访问器setter和getter实现的成员相当于定义了一个(public)公有成员,每个实例都会产生自己的实例属性,唯一的区别就是在不写入值时会读取类中定义的私有属性值,这个特性与JS完全一致。常见的使用访问器实现读写私有属性(一般只写):
class Person{
private _name: string = 'person';
//给私有属性赋值
set setName(val:string){
this._name = val;
}
//读取私有属性值(一般不建议使用)
get getName(){
return this._name;
}
}
var obj1 = new Person();
var obj2 = new Person();
obj1.setName = 'obj1';
console.log(obj2.getName);//person
console.log(obj1.getName);//obj1
//js
class Person{
#name = 'person';
//给私有属性赋值
set setName(val){
this.#name = val;
}
//读取私有属性值(一般不建议使用)
get getName(){
return this.#name;
}
}
var obj1 = new Person();
var obj2 = new Person();
obj1.setName = 'obj1';
console.log(obj2.getName);//person
console.log(obj1.getName);//obj1
js示例
二、TypeScript类的抽象类(abstract)
关于抽象类需要先理解几个概念,什么是抽象类,什么是派生类,什么是抽象类型的引用。
抽象类顾名思义就是类的抽象,它不是用来具体实现对象实例化的类,而是定义类结构。比如规定类必须要实现那些方法和成员变量,但其自身并不做具体细节实现,这些方法也叫做抽象方法和抽象成员变量(同样使用abstract关键字修饰),这些被抽象出来的方法和成员变量必须在派生类中实现。抽象类自身也可以包含成员的实现细节,比如定义构造函数的具体内容,成员变量和方法,这些实现细节会被派生类继承用于实例化具体的对象。
派生类就是抽象类的具体实现,在派生类中必须实现抽象类中定义的抽象方法和成员变量,并且不能随意增加抽象类没有定义的方法和成员变量(即使能在抽象类中实现,但是不能被抽象类的引用使用这些在派生类中私自定义的内容,但可以被非抽象类引用的变量接收),这一点与继承是有区别的。并且在构造函数constructor内必须使用super()方法继承抽象类的构造。
抽象类型的引用就是变量类型为抽象类的变量,该变量只能引用抽象类对应的派生类构造的对象,并且只能使用抽象类自身实现的细节内容和抽象内容,而不能使用派生类中实现的非抽象内容。
abstract class Department {
constructor(public name: string) {
}
printName(): void {
console.log('Department name: ' + this.name);
}
abstract printMeeting(): void; // 必须在派生类中实现
} class AccountingDepartment extends Department {
public a:string;
constructor() {
super('Accounting and Auditing'); // 在派生类的构造函数中必须调用 super()
this.a='aaa'
}
printMeeting(): void {
console.log('The Accounting Department meets each Monday at 10am.');
}
generateReports(): void {
console.log('Generating accounting reports...');
}
} let department: Department; // 允许创建一个对抽象类型的引用
// department = new Department(); // 错误: 不能创建一个抽象类的实例
department = new AccountingDepartment(); // 允许对一个抽象子类进行实例化和赋值
department.printName();
department.printMeeting();
// department.generateReports(); // 错误: 方法在声明的抽象类中不存在 let accounting = new AccountingDepartment();//非抽象引用变量能接收的派生类实例对象
accounting.generateReports();//并且能使用派生类自身定义的内容
三、TypeScript类的高级技巧
1.构造函数
关于构造函数作为类的核心内容,是每个类实例化对象时new指令直接调用的方法,实际上TypeScript与ES6在这方面并没有差别,如果了解ES6的化我们都知道class只是一个语法糖,它的底层实现还是function,类中的构造函数就是ES5的方法主体,它最终被赋给该方法原型上的constructor属性,而类中实现的一系列的修饰符和特性最后都会被解析为类自身或者原型上的属性和方法,用来配合主体方法实现对象实例的构造。
//ES5基于function实现的类
let Greeter = (function () {
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
return Greeter;
})(); let greeter;
greeter = new Greeter("world");
console.log(greeter.greet());
再来对比看一下TypeScript的改写实现:
class Greeter {
static standardGreeting = "Hello, there";
greeting: string;
greet() {
if (this.greeting) {
return "Hello, " + this.greeting;
}
else {
return Greeter.standardGreeting;
}
}
} let greeter1: Greeter;
greeter1 = new Greeter();
console.log(greeter1.greet()); let greeterMaker: typeof Greeter = Greeter;
greeterMaker.standardGreeting = "Hey there!"; let greeter2: Greeter = new greeterMaker();
console.log(greeter2.greet());
2.把类当成接口(关于接口在TypeScript接口相关博客中会有更详细的内容)
class Point {
x: number;
y: number;
} interface Point3d extends Point {
z: number;
} let point3d: Point3d = {x: 1, y: 2, z: 3};
TypeScript入门四:TypeScript的类(class)的更多相关文章
- TypeScript入门五:TypeScript的接口
TypeScript接口的基本使用 TypeScript函数类型接口 TypeScript可索引类型接口 TypeScript类类型接口 TypeScript接口与继承 一.TypeScript接口的 ...
- TypeScript入门指南(JavaScript的超集)
TypeScript入门指南(JavaScript的超集) 你是否听过 TypeScript? TypeScript 是 JavaScript 的超集,TypeScript结合了类型检查和静态分析 ...
- Typescript 学习笔记五:类
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- TypeScript入门实例
前言 TypeScript是JavaScript的超集,微软公司开发,利用es6语法,实现对js的面向对象编程思想,写代码的时候会像强类型语言一样,指定参数类型.返回值类型,类型不对会报错,但编译后还 ...
- typescript 入门教程一
##### 从今天开始,持续更新typescript入门教程系列.... 目前ts越来越火,主流的前端框架,好比*angular,vue 3*均是采用ts来编写,所有很多公司的项目都是用**ts**来 ...
- TypeScript入门七:TypeScript的枚举
关于枚举 数字枚举 字符串枚举 异构枚举 计算的和常量成员 运行时的枚举与反向映射 常量枚举与外部枚举 一.关于枚举 枚举:一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计 ...
- TypeScript入门三:TypeScript函数类型
TypeScript函数类型 TypeScript函数的参数 TypeScript函数的this与箭头函数 TypeScript函数重载 一.TypeScript函数类型 在上一篇博客中已经对声明Ty ...
- TypeScript 入门教程学习笔记
TypeScript 入门教程学习笔记 1. 数据类型定义 类型 实例 说明 Number let num: number = 1; 基本类型 String let myName: string = ...
- TypeScript 入门自学笔记 — 类型断言(二)
码文不易,转载请带上本文链接,感谢~ https://www.cnblogs.com/echoyya/p/14558034.html 目录 码文不易,转载请带上本文链接,感谢~ https://www ...
随机推荐
- 为TMenuItem增加指针Data属性
Delphi的有些组件中都包含.Data属性,比如TTreeNode,.Data属性可以认为是一个指针,可以指向任何类或者结构,方便后续操作. 但是TMenuItem没有.Data属性,下面介绍最简单 ...
- jQuery.fn.extend与jQuery.extend的区别
jquery 本身并不提供 jQuery.color() 这个方法,如果我们需要对jQuery本身提供的方法进行扩展,则我们就需要是用jQuery.fn.extend: jQuery.fn.exten ...
- Spring Aop(四)——基于Aspectj注解的Advice介绍
转发地址:https://www.iteye.com/blog/elim-2395315 4 基于Aspectj注解的Advice介绍 之前介绍过,Advice一共有五种类型,分别是before.af ...
- Python操作qml对象
1. 如何在python里获得qml里的对象? 1.1 获取根对象 QML: import QtQuick 2.12 import QtQuick.Controls 2.12 ApplicationW ...
- windows下redis配置密码
redis安装后目录如下: 最简单的启动方式是直接双击redis-server.exe 如果要设置密码,首先打开配置文件,要注意的是这两个都是配置文件,记住你改的是哪一个,不放心的可以两个都改. 然后 ...
- centos(linux)-maven配置
1.确认已经安装jdk 2.下载 3.解压 tar -zxvf apache-maven-xxx(tab补全文件名) 4.配置环境变量 (1)sudo vim /etc/profile (2)在最下面 ...
- Memcache分布式锁
在分布式缓存的应用中,会遇到多个客户端同时争用的问题.这个时候,需要用到分布式锁,得到锁的客户端才有操作权限 下面通过一个简单例子介绍: 这里引用的是Memcached.ClientLibrary.d ...
- POJ 1161 Walls【floyd 以面为点建图】
题目链接:http://poj.org/problem?id=1161 题目大意: 1.给出m个区域,n个俱乐部点.接下来是n个俱乐部点以及各个区域由什么点围成.求一个区域到各个俱乐部点的距离之和最小 ...
- springboot中配置文件使用1
1.表达方式:application.properties或者application.yml,这是已经约定成俗的文件,不用修改文件名,此文件为全局配置文件. 2.语法格式:yml或者yaml. a.基 ...
- Redis 原子操作——事务
MULTI 标记一个事务块的开始. 事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性(atomic)地执行. 可用版本: >= 1.2.0 时间复杂度: O(1) ...