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 ...
随机推荐
- JPEG Image Super-Resolution via Deep Residual Network
基于深度残差网络的JPEG图像超分辨率 JPEG Image Super-Resolution via Deep Residual Network PDF https://www.researchga ...
- 14 Flutter仿京东商城项目 头部搜索导航布局 修改主题 修正ScreenAdapter类
main.dart import 'package:flutter/material.dart'; import 'routes/router.dart'; void main() => run ...
- jpa 总结
转:http://blog.csdn.net/linzhiqiang0316/article/details/52639265 先来介绍一下JPA中一些常用的查询操作: //And --- 等价于 S ...
- 阶段5 3.微服务项目【学成在线】_day04 页面静态化_05-freemarker基础-List指令
controller填充数据 @RequestMapping("/freemarker") @Controller public class FreemarkerControlle ...
- JAVA 基础编程练习题46 【程序 46 字符串连接】
46 [程序 46 字符串连接] 题目:两个字符串连接程序 package cskaoyan; public class cskaoyan46 { public static void main(St ...
- Consul 随记
consul 包含多个组件,但是作为一个整体对外提供服务发现和服务配置工具: 提供的关键特性有: 服务发现:发现的是服务对应的IP地址和PORT端口号 健康检查:检查服务节点状态 Key/Value存 ...
- Bash Shellshock(CVE-2014-6271)破壳漏洞测试
0x01 漏洞原理 Bash使用的环境变量是通过函数名称来调用的,导致漏洞出问题是以"(){"开头定义的环境变量在命令ENV中解析成函数后,Bash执行并未退出,而是继续解析并执行 ...
- swift 第九课 用tableview 做一个下拉菜单Menu
写到这里的时候,自己这个项目已经完成了一半左右,项目进度自己还是挺满意.今天又有一个新的布局,要实现个下拉菜单,刚开始写的时候,觉得会很容易,后来发现也是小错不断, 我想自己限制的自己属于写博客的初期 ...
- 热更新之lua框架设计
目前中大型游戏项目包含部分VR与AR项目,都需要热更新与在线修改Bug等功能实现,虽然Xlua等插件已经给出了关于C#与Lua语言之间的双向无缝调用实现,但是就热更新的架构却没有提出,这需要广大游戏公 ...
- shell学习笔记2-find和xargs
1,find命令形式 find pathname -options [-print - exec -ok] pathname find命令所查找的目录路径.. 表示当前目录,/表示系统根路径 -pri ...