LOADING

TypeScript面向对象

🦉 TS面向对象

TypeScript的面向对象和ES6以后的语法其实差不太多

定义类

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

示例:

class Person {
    //构造器
    constructor(name: string, age: number) {
        //this指向创建时候的示例
        this.name = name;
        this.age = age
    }
    //普通属性
    name: string;
    age: number;
    //只读属性,无法修改
    readonly onyRead:number =123;
    //静态属性
    static  money:number = 33333;
    //方法
    sing(){
        console.log(this.name+" is singing");
    }
}
//使用
let kano = new Person('kano',18);
kano.sing()
console.log(Person.money);

继承

继承在语法上和其他的面向对象语言没有什么太大差距,不过确实比较像Java

//Animal
class Animal {
    name: string
    age: number

    constructor(name: string, age: number) {
        this.name = name
        this.age = age
    }

    say() {
        console.log('Something say');
    }
}

//Dog
class Dog extends Animal {
    constructor(name: string, age: number) {
        //访问基类的构造器,传递参数
        super(name, age)
    }

    override say() {
        console.log('Dog Bark');
    }
    //父类的say
    originalSay(){
        super.say()
    }
    run(){
        console.log(this.name+'is running')
    }
}

//cat
class Cat extends Animal {
    constructor(name: string, age: number) {
        super(name, age)
    }
    //不写override默认重写父类方法
    say() {
        console.log('cat miaomiao');
    }
}

抽象类

//Animal抽象类,禁止被作为实例
abstract class Animal {
    name: string
    age: number
    //抽象类中的方法是受保护的
    protected constructor(name: string, age: number) {
        this.name = name
        this.age = age
    }
    //抽象方法
    abstract say():void;
}

//Dog
//抽象类的内容必须全部实现
class Dog extends Animal {
    constructor(name: string, age: number) {
        super(name, age)
    }
    override say() {
        console.log('Dog Bark');
    }
}

//cat
class Cat extends Animal {
    constructor(name: string, age: number) {
        super(name, age)
    }
    say() {
        console.log('cat miaomiao');
    }
}

接口

接口可以描述一个对象内属性的类型,相当于给派生对象一个规范
和TS的type差不多,不过也有区别:
-接口可以在定义类的时候去限制类的结构
-接口中的所有属性,都不能有实际的值,这一点和C#是一样的

//描述一个对象的类型
type myType = {
    name:string,
    age:number
}

//接口用来定义一个类结构,规范
interface myInterface{
    name:string,
    age:number
}
//同名接口可以合并
interface myInterface{
    gender:string
}

//实现接口
const obj:myInterface ={
    name:'xxs',
    age:1,
    gender:'male'
}
//实现类型
const typeObj:myType={
    name:'zs',
    age:11
}

定义类时,可以使类去实现接口(满足接口的要求)
和其他面向对象语言一样,TS的接口也是可以多继承的

//USB2.0规范
interface USB2 {
    type: string
    pins: number
    transferData(): void
}

//USB3.0规范(老)
interface USB3 {
    type: string
    transferData(): void
}

class MyUSBCable implements USB3, USB2 {
    constructor(pins: number, type: string) {
        this.pins = pins
        this.type = type
    }
    pins: number;
    type: string;
    transferData(): void {
        if(this.pins <= 4){
            console.log('lowSpeed type:' + this.type)
        }else{
            console.log('hiSpeed type:'+this.type)
        }
    }
}

const uselessCable = new MyUSBCable(4,"MicroUSB")
uselessCable.transferData()

属性封装

TS也有类似get,set的访问修饰符,用来增强和约束对象中的属性

//定义一个表示人的类
class Person {
    // private _name: string;
    // private _age: number;

    //getter与setter
    get name() {
        return this._name
    }
    set name(value) {
        this._name = value;
    }

    get age() {
        return this._age
    }
    set age(value) {
        if (value > 0) {
            this._age = value
        }
    }
    //可以直接将属性定义在构造函数里面(感觉好绕,不建议这么写)
    constructor(private _name: string,private _age: number) {
        // this._name = name
        // this._age = age
    }
}

const p = new Person('nana', 18);
//不规范赋值
p.age = -111;
p.name = 'kano'

泛型

在定义函数或者是类的时候,如果遇到变量、返回值类型不明确的时候就可以使用泛型

//泛型
//T表示任意类型,名字随意
function fn<T>(a: T): T {
    return a;
}
//可以直接调用具有泛型的函数
console.log(fn(10));//不指定泛型,TS会自动推断
//手动指定类型
console.log(fn<boolean>(false));//指定泛型,执行效率更高

泛型也可以有多参数

//多参数泛型
function fn2<T, K>(a: T, b: K): T {
    console.log(a, b)
    return a;
}
fn2<number, string>(123, 'kano')

泛型限定,下面的泛型只允许实现了IO接口的类/对象作为参数

interface IO {
    someNumber: string
}

//限定泛型
//函数只接收实现了IO接口的类/对象
function fn3<T extends IO>(a: T): string {
    return a.someNumber
}

// class cable implements IO{
//     public someNumber:string
//     constructor(cable:string) {
//         this.someNumber = cable
//     }
// }

//传一个实现IO接口的对象
// const usbCable = new cable('usbCable')

//传一个实现IO接口的类
console.log(class cable implements IO{
    public someNumber:string
    constructor(cable:string) {
        this.someNumber = cable
    }
});

除此之外,类也可以是泛型的

//泛型类
class cls<T>{
    prop:T
    constructor(props:T) {
        this.prop = props
    }
}
const obj = new cls<number>(123)

补充

使用接口描述一个数组:

interface Arr {
    [index:number]: number
}
let arr:Arr = [1,3,4]

强制转换:

function fn(flag:boolean|number):boolean {
    return !!flag
}

!!就表示强制转换

    发表回复

    电子邮件地址不会被公开。必填项已用 * 标注