typescript 类和接口

发布于:2023-07-27 ⋅ 阅读:(125) ⋅ 点赞:(0)

原文链接: typescript 类和接口

上一篇: win10 串口 使用

下一篇: python opencv 知到 刷课 脚本

简单类

class Stu {
    name: string;

    constructor(name: string) {
        this.name = name;
    }

    say(): string {
        return `hello ${this.name}`
    }
}


let stu = new Stu("ace")

// hello ace
console.log(stu.say()); 

与强类型语言类似,TypeScript的类成员可以显式声明访问级别:public、protected、private

在TypeScript里,如果不显示指定访问级别,则默认为public。

class User {
    name: string;
    private sex: string;
    protected age: number;
    constructor(_name: string) {
        this.name = _name;
    }

    sayHello(): string {
        return `Hello,${this.name}!`;
    }
}

let user = new User('John Reese');
user.name = 'Root';                 // 公有属性,可以赋值
user.sex = 'female';                // 私有属性,无法赋值
user.age = 28;                      // 受保护属性,无法赋值
user.sayHello();

属性的get和set访问器

通过get和set关键字声明属性访问器,通过属性访问器可以精确控制属性的赋值和获取值。

class User {
    private _name: string;

    get name(): string {
        return this._name;
    }

    set name(newName: string) {
        this._name = newName;
    }

    constructor(_name: string) {
        this.name = _name;
    }

    sayHello(): string {
        return `Hello,${this._name}!`;
    }
}

let user = new User('John Reese');
user.name = 'Root';
user.sayHello();

静态属性

静态属性即是通过类型而不是实例就可以访问的属性

通过static关键字可以声明类型的静态属性。

class User {
    static sex_type = ['male', 'female'];       // 静态属性
    name: string;
    sex: string;

    constructor(_name: string) {
        this.name = _name;
    }

    sayHello(): string {
        return `Hello,${this.name}!`;
    }
}

let user = new User('John Reese');
user.name = 'Root';
user.sex = User.sex_type[1];
user.sayHello();

类的继承

同强类型语言一样,TypeScript也支持类的继承

子类通过extends关键字可以继承其他类,通过super方法调用基类对应的方法,也可以直接重写基类的方法。

// 基类
class Animal {
    name: string;

    constructor(theName: string) {
        this.name = theName;
    }

    eat() {
        console.log(`${this.name} 吃食物。`);
    }
}

// 子类继承基类
class Dog extends Animal {
    constructor(theName: string) {
        super(theName);
    }

    eat() {
        super.eat();
        console.log('并且吃的是狗粮。');
    }
}

class People extends Animal {
    constructor(theName: string) {
        super(theName);
    }

    // 子类重写基类方法
    eat() {
        console.log(`${this.name} 拒绝吃狗粮。`);
    }
}

let animal = new Animal('动物');
animal.eat();

let dog: Animal;
dog = new Dog('狗');
dog.eat();

let people: Animal;
people = new People('人类');
people.eat();

抽象类

通过abstract关键字声明抽象类和抽象方法,子类继承抽象类后,需要实现抽象方法。同样的,抽象类不能被实例化。

// 抽象类
abstract class Animal {
    name: string;

    constructor(theName: string) {
        this.name = theName;
    }

    abstract eat();
}

// 子类继承抽象类
class Dog extends Animal {
    constructor(theName: string) {
        super(theName);
    }

    eat() {
        console.log(`${this.name} 吃狗粮。`);
    }
}

let animal = new Animal('动物');      // 抽象类无法实例化
animal.eat();

let dog: Animal;
dog = new Dog('狗');
dog.eat();

接口

在JavaScript里没有对应的类型与之对应,所以编译之后不会生成任何JavaScript代码。

简单接口

interface Animal {
    name: string;
}

1. 作为参数类型

接口类型可以作为方法的参数类型,效果等同于直接指定Json对象的类型。

interface Animal {
    name: string;
}

let printName = function(param: Animal) {
    console.log(`Name is ${param.name}`);
}

printName({name: 'Dog'});

接口成员也可以是缺省的

interface Animal {
    name: string;
    age?: number;
}

let printName = function (param: Animal) {
    if (param.age) {
        console.log(`Name is ${param.name}, and age is ${param.age}`);
    } else {
        console.log(`Name is ${param.name}`);
    }
}

printName({ name: 'Dog' });
printName({ name: 'Dog', age: 5 });

但是在某些情况下,调用方法时,参数赋值可能会有多个,接口在作为参数类型时也支持拥有多个成员的情况。

interface Animal {
    name: string;
    age?: number;
    [propName: string]: any;        // 其他成员
}

let printName = function (param: Animal) {
    if (param.age) {
        console.log(`Name is ${param.name}, and age is ${param.age}`);
    } else {
        console.log(`Name is ${param.name}`);
    }
}

printName({ name: 'Dog' });
printName({ name: 'Dog', age: 5 });
printName({ name: 'Dog', age: 5, character: '粘人' });    // 多于明确定义的属性个数

作为其他类型

接口也可以定义方法的类型,和数组类型

interface FuncType {
    (x: string, y: string): string;         // 声明方法成员
}

let func1: FuncType;
func1 = function (prop1: string, prop2: string): string {       // 方法参数名称不需要与接口成员的参数名称保持一致
    return prop1 + ' ' + prop2;
}

interface ArrayType {
    [index: number]: string;                // 声明数组成员
}

let arr: ArrayType;
arr = ['Dog', 'Cat'];

接口的继承与实现

同强类型语言一样,TypeScript的接口支持继承与实现。

interface Animal {
    name: string;
    eat(): void;
}

class Dog implements Animal {
    name: string;
    constructor(theName: string) {
        this.name = theName;
    }

    eat() {
        console.log(`${this.name} 吃狗粮。`)
    }
}

class Cat implements Animal {
    name: string;
    constructor(theName: string) {
        this.name = theName;
    }

    eat() {
        console.log(`${this.name} 吃猫粮。`)
    }
}

let dog: Animal;
dog = new Dog('狗狗');
dog.eat();

let cat: Animal;
cat = new Cat('喵星人');
cat.eat();

类通过implements关键字继承接口,并实现接口成员。

同时,接口也可以多重继承。

interface Animal {
    name: string;
    eat(): void;
}

interface Person extends Animal {                   // 继承自Animal接口
    use(): void;
}

class People implements Person {
    name: string;
    constructor(theName: string) {
        this.name = theName;
    }

    eat() {
        console.log(`${this.name} 拒绝吃狗粮。`)
    }

    use() {
        console.log(`${this.name} 会使用工具。`)
    }
}

let man: Person;
man = new People('男人');
man.eat();
man.use();

类型转换

在TypeScript里,接口可以对符合任一成员类型的对象进行转换,转换之后的对象自动继承了接口的其他成员。

声明了拥有name属性的json对象,通过<>将json对象转换成了Animal类型的对象。转换后的对象则拥有了另外的age属性和eat方法。

interface Animal {
    name: string;
    age: number;
    eat(): void;
}

let thing = { name: '桌子' };
let otherThing = <Animal>thing;             // 类型转换
otherThing.age = 5;
otherThing.eat = function () {
    console.log(`${this.name} 不知道吃什么。`)
};

接口继承类

在TypeScript里,接口可以继承类,这样接口就具有了类里的所有成员,同时这个接口只能引用这个类或者它的子类的实例。

当继承链过深,代码需要在某一个子类的类型下执行时,这种方法比较有效。

class People {
    name: string;
    private age: number;
    constructor(theName: string) {
        this.name = theName;
    }

    eat() {
        console.log(`${this.name} 拒绝吃狗粮。`);
    }

    use() {
        console.log(`${this.name} 会使用工具。`)
    }
}

interface Animal extends People {               // 接口

}

class Man extends People {                      // 子类

}

class Cat {                                     // 拥有同样结构的另外一个类
    name: string;
    private age: number;
    constructor(theName: string) {
        this.name = theName;
    }

    eat() {
        // 具体实现
    }

    use() {
        // 具体实现
    }
}

let cat: Animal;
cat = new Cat('喵星人');                       // Cat类不是People的子类,无法被Animal引用

let man: Animal;
man = new Man('男人');
man.eat();


网站公告

今日签到

点亮在社区的每一天
去签到