深入Typescript--03-Typescript中的类(努力加餐饭)
2024-10-21 03:18:28
Typescript中的类
一.TS中定义类
class Pointer{
x!:number; // 实例上的属性必须先声明
y!:number;
constructor(x:number,y?:number,...args:number[]){
this.x = x;
this.y = y as number;
}
}
let p = new Pointer(100,200);
- 实例上的属性需要先声明在使用,构造函数中的参数可以使用可选参数和剩余参数
二.类中的修饰符
- public修饰符(谁都可以访问到)
class Animal {
public name!: string; // 不写public默认也是公开的
public age!: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
class Cat extends Animal {
constructor(name: string, age: number) {
super(name, age);
console.log(this.name,this.age); // 子类访问
}
}
let p = new Cat('Tom', 18);
console.log(p.name,p.age); // 外层访问
class Animal {
constructor(public name: string, public age: number) {
this.name = name;
this.age = age;
}
}
我们可以通过参数属性来简化父类中的代码
protected修饰符 (自己和子类可以访问到)
class Animal {
constructor(protected name: string, protected age: number) {
this.name = name;
this.age = age;
}
}
class Cat extends Animal {
constructor(name: string, age: number) {
super(name, age);
console.log(this.name, this.age)
}
}
let p = new Cat('Tom', 18);
console.log(p.name,p.age);// 无法访问
- private修饰符 (除了自己都访问不到)
class Animal {
constructor(private name: string, private age: number) {
this.name = name;
this.age = age;
}
}
class Cat extends Animal {
constructor(name: string, age: number) {
super(name, age);
console.log(this.name, this.age); // 无法访问
}
}
let p = new Cat('Tom', 18);
console.log(p.name,p.age);// 无法访问
- readonly修饰符 (仅读修饰符)
class Animal {
constructor(public readonly name: string, public age: number) {
this.name = name;
this.age = age;
}
changeName(name:string){
this.name = name; // 仅读属性只能在constructor中被赋值
}
}
class Cat extends Animal {
constructor(name: string, age: number) {
super(name, age);
}
}
let p = new Cat('Tom', 18);
p.changeName('Jerry');
三.静态属性和方法
class Animal {
static type = '哺乳动物'; // 静态属性
static getName() { // 静态方法
return '动物类';
}
private _name: string = 'Tom';
get name() { // 属性访问器
return this._name;
}
set name(name: string) {
this._name = name;
}
}
let animal = new Animal();
console.log(animal.name);
- 静态属性和静态方法是可以被子类所继承的
四.Super属性
class Animal {
say(message:string){
console.log(message);
}
static getType(){
return '动物'
}
}
class Cat extends Animal {
say(){ // 原型方法中的super指代的是父类的原型
super.say('猫猫叫');
}
static getType(){ // 静态方法中的super指代的是父类
return super.getType()
}
}
let cat = new Cat();
console.log(Cat.getType())
五.类的装饰器
- 简单来说,就是给一个类,添加一些好用的方法,其他类也能用,写到原型上面,参考5.1
- 或者是修饰类里的一些属性方法,搞通用的那种函数,用来修饰,节省代码,可参考5.2,5.3
- 还可以修饰函数的参数哇 5.4
- 装饰器作用就是为了扩展类,扩展类中的属性和方法
- 只能修饰类,不可以修饰函数,函数有变量提升的问题
- 装饰器必须是一个函数
- 执行=洋葱模型,先从外层执行,执行完后,从内层倒序执行,一层一层剥开,再一层一层执行
1.装饰类
function addSay(target:any){
target.prototype.say = function(){console.log('say')}
}
@addSay
class Person {
say!:Function
}
let person = new Person
person.say();
- 装饰类可以给类扩展功能,需要开启experimentalDecorators:true
2.装饰类中属性
// target 是类的原型,,key 是需要修饰的属性
function toUpperCase(target:any,key:string){
let value = target[key];
Object.defineProperty(target,key,{ // 原型定义属性
get(){
return value.toUpperCase();
},
set(newValue){
value = newValue
}
})
}
function double(target: any, key: string) {
let value = target[key];
Object.defineProperty(target, key, {
get() {
return value * 2;
},
set(newValue) {value = newValue}
})
}
class Person {
@toUpperCase
name: string = 'JiangWen'
@double
static age: number = 10;
getName() {
return this.name;
}
}
let person = new Person();
console.log(person.getName(),Person.age)
- 装饰属性可以对属性的内容进行改写,装饰的是实例属性则target指向类的原型、装饰的是静态属性则target执行类本身~
3.装饰类中方法
// 设置某些方法属性是否可用
function noEnum(target:any,key:string,descriptor:PropertyDescriptor){
console.log(descriptor)
descriptor.enumerable = false;
}
class Person {
@toUpperCase
name: string = 'JiangWen'
@double
static age: number = 10;
@noEnum
getName() {
return this.name;
}
}
let person = new Person();
console.log(person); // getName 不可枚举
4.装饰参数
function addPrefix(target:any,key:string,paramIndex:number){
console.log(target,key,paramIndex); // Person.prototype getName 0
}
class Person {
@toUpperCase
name: string = 'JiangWen'
@double
static age: number = 10;
prefix!:string
@noEnum
getName(@addPrefix prefix:string) {
return this.name;
}
}
六.抽象类
- 抽象类无法被实例化,只能被继承,抽象方法不能在抽象类中实现,只能在抽象类的具体子类中实现,而且必须实现。
- 定义类型时void表示函数的返回值为空
abstract class Animal{
name!:string;
abstract speak():void
}
class Cat extends Animal {
speak(){
console.log('猫猫叫');
}
}
class Dog extends Animal{
speak():string{
console.log('汪汪叫');
return 'wangwang'
}
}
最新文章
- 【腾讯Bugly干货分享】动态链接库加载原理及HotFix方案介绍
- HDU 5512
- BZOJ2904
- 为初学者写ORM,ORM的原理及测试案例
- diy 电脑 重装系统
- 【转载】ADO.NET与ROM的比较(1):ADO.NET实现CRUD
- JavaScript星级评分
- CSAPC2008 skyline
- hibernate框架学习之主键生成策略generator
- UVa-156 Ananagrams 反片语【map】【vector】
- day19:常用模块(collections,time,random,os,sys)
- python中的运算符归类
- SQL 给字符串补0
- C# [ModelName]标记 模型,类名称重复。
- ios ideviceintaller安装
- c#设计模式之代理模式(Proxy Pattern)
- Python爬虫学习:Python内置的爬虫模块urllib库
- CentOS系统下yum命令的详细使用方法
- jstorm相关
- nginx config的多个config配置