TypeScript--笔记三(类、继承、泛型、命名空间、装饰器)

一、类

定义类包含两个部分 属性 和 方法

1.模板:

class 类名 {
  // 定义属性
  属性名: 类型;
    constructor(参数: 类型) {
     this.属性名 = 参数;
  }
  方法名() {
    ...
  }
}

其中:

2.直接定义的属性是实例属性,需要通过对象实例去访问 方法同理

const per = new Person()
per.name

3.使用static关键字可以定义类属性(静态类),可以直接通过类访问 方法同理

person.name

4. readonly开头的属性表示一个只读的属性无法修改

5.构造函数

  • constructor()在对象创建时调用
  • 构造函数中this表示当前实例
  • 可以通过this向新建的对象中添加属性
  • 在方法中可以通过this来表示当前调用方法的对象
    综上结合案例试试手:
class person{
  name: string;
  age: number;
  // 在属性前面使用static关键字可以定义类属性(静态类)
  static sex: string = '男';
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age
  }
  sayHello() {
    console.log('你好');
  }
}
const dog = new person('小黑', 3)
console.log(dog);

6.Super 关键字

在类的方法中super代表当前类的父类
如果在子类中写了构造函数,则必须在子类构造函数中用super对父类进行调用
 class Animal{
        name: string;
        constructor(name:string){
            this.name = name
        }
        sayHello(){
            console.log('hi~');
        }
    }
    class Dog extends Animal{
        // 如果在子类中写了构造函数,
        // 则必须在子类构造函数中对父类进行调用
        constructor(name:string,age:number){
            super(name); // 调用父类
        }
        sayHello(){
            // 在类的方法中super代表当前类的父类
            super.sayHello() 
        }
    }
    const dog = new Dog('小黑', 3)
    dog.sayHello()

7.抽象类

  1. 以abstract开头的类就是抽象类
  2. 和其他类区别不大,只是不能用来创建对象
  3. 抽象类就是产生就是专门做父类给其他类继承
  4. 抽象类可以添加抽象方法
  5. 同样需要abstract开头,并且没有方法体也就是没有返回值
  6. 抽象方法只能定义在抽象类中且子类必须对抽象方法进行重写也就是在子类中需要定义sayHello方法
abstract class Zoo{
        name: string;
        constructor(name:string){
            this.name = name
        }
        // 抽象类可以添加抽象方法
        // 同样需要abstract开头,并且没有方法体也就是没有返回值
        // 抽象方法只能定义在抽象类中且子类必须对抽象方法进行重写也就是在子类中需要定义sayHello方法
        abstract sayHello():void
    }

二、继承

先看例子:

// 定义一个公共类
class Animal{
  name: string;
  age: number;
  static sex: string = '男';
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age
  }
  sayHello() {
    console.log('动物在叫');
  }
}

class Dog extends Animal{
  sayHello() {
    console.log('旺旺');
  }
}
const dogs = new Dog('www', 9)

  • Animal为父类 Dog为子类
  • 使用继承后子类将拥有父类所有属性和方法
  • 如果子类添加父类相同的方法 则子类覆盖掉父类方法

三、泛型

在定义函数或者类时 如果遇到类型不明确就可以使用泛型

// 一个泛型
    function fn<T>(a:T):T{
        return a
    }
    fn<string>('abc') // 指定泛型为字符串
   
    // 多个泛型
    function fn2<T,K>(a:T,b:K):T{
        return a
    }
    fn2<number,Boolean>(1,false)
    class MyClass2<T>{
        constructor(public name: T) {
        }
    }

    // 限制泛型范围
    interface Inter{
        label: number
    }
    function f3<T extends Inter>(a:T):number {
        return a.label
    }
    f3({label:6})

四、命名空间

作用: 内部模块主要用于组织代码,避免命名冲突
注意:
1.命名空间里面的类属于私有的,外部要用需要命名空间内部暴露
2.如果是模块的话 需要将这个空间暴露 export namespace A {}
3.这样哪里需要用 引入此文件 同样进行操作
语法: namespace 自定义命名 {}

namespace A {
    interface myInter {
        name: string;
        sayHello(): void;
    }
    export class MyClass implements myInter {
        name: string; 
        constructor(name: string) {
            this.name = name
        }
        sayHello() {
            console.log('你好');
        };
    }

}
let qd = new A.MyClass('小张');

五、装饰器

就是一个方法 可以注入到类、方法、属性、参数上来扩展类、方法、参数的功能
写法: 普通装饰器(无法传参) 装饰器工厂(可传参)

1.类装饰器

在类之前被声明(紧靠类声明)应用于构造函数

// 定义装饰器
function logClass(params:any){
    // params 就是当前类
    // 给当前类拓展了apiUrl属性 run方法
    params.prototype.apiUrl = 'xxxxxx';
    params.prototype.run = function() {}
}
@logClass
class HttpClass {
    constructor(){}
}
let http = new HttpClass()

// 装饰器工厂
function logClass1(params:string){ // 这是一个装饰器工厂
    return function(target:any){ // 这是一个装饰器
        console.log(target);//target就是当前类
        console.log(params);//params就是当前类传递进来的参数
        target.prototype.apiUrl = params;
    }
}
@logClass1('http://www.baidu.com')
class HttpClass1 {
    constructor(){}
}
let https = new HttpClass1()

2. 属性装饰器

属性装饰器会在运行时传入下列2个参数:
参数一:对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
参数二:成员的名字

 function logProperty(params: any) {//params就是当前类传递进来的参数
    return function (target: any, attr: any) {
        console.log(target);
        console.log(attr);
        target[attr] = params;
    }
}

class HttpClient {
    @logProperty("http://www.baidu.com")
    public url: any | undefined;

    getData() {
        console.log(this.url);
    }
}

var httpdata = new HttpClient();
httpdata.getData();

3. 方法装饰器

方法装饰器会在运行时传入下列3个参数:
参数一、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
参数二、成员的名字。
参数三、成员的属性描述符。

function get(params: any) {//params就是当前类传递进来的参数
    return function (target: any, methodName: any, desc: any) {
        console.log(target);
        console.log(methodName);
        console.log(desc);
        target.apiUrl = params;
        target.run = function () {
            console.log("run");
        }
    }
}

class HttpClient {
    public url: any | undefined;
    constructor() {
    }
    @get("http://www.baidu.com")
    getData() {
        console.log(this.url);
    }
}

let http: any = new HttpClient();
console.log(http.apiUrl);
http.run();

4. 参数装饰器

表达式会在运行时当作函数被调用,可以使用参数装饰器为类的原型增加一些元素数据 ,传入下列3个参数:
参数一、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
参数二、方法的名字。
参数三、参数在函数参数列表中的索引。

function logParams(params: any) {
    return function (target: any, methodName: any, paramsIndex: any) {
        console.log(target);
        console.log(methodName);
        console.log(paramsIndex);
        target.apiUrl = params;
    }
}

class HttpClient {
    getData(@logParams("10086") uuid: any) {
        console.log(uuid);
    }
}

var http: any = new HttpClient();
http.getData(123456);
console.log(http.apiUrl);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值