学习笔记 - class

类型比较

TypeScript 使用的是结构性类型系统。当我们比较两种不同的类型时,并不在乎它们从何处而来,如果所有成员的类型都是兼容的,我们就认为它们的类型是兼容的。

然而,当我们比较带有 private 或 protected 成员的类型的时候,情况就不同了。 如果其中一个类型里包含一个 private 成员,那么只有当另外一个类型中也存在这样一个 private 成员,并且它们都是来自同一处声明时,我们才认为这两个类型是兼容的。对于 protected 成员也使用这个规则。

比如以下两种类型认为是兼容的:

class A { 
    public name: string;
}

class B { 
    public name: string;
}

const test: A = new B();

但是如果带有 private 成员,情况就不一样了:

class A { 
    public name: string;
    private age: number;
}

class B { 
    public name: string;
    private age: number;
}

// fail:
// Type 'B' is not assignable to type 'A'.
//  Types have separate declarations of a private property 'age'.
const test: A = new B();

但是如果 private 类型来自于同一处声明,那么类型又会变成兼容的了:

class Base {
    private age: number;
}

class A extends Base {
    public name: string;
}

class B extends Base {
    public name: string;
}

const test: A = new B();

而下面的例子是不兼容的:

class Base {
    private age: number;
}

class A extends Base {
    public name: string;
}

class B extends Base {
    public name: string;
    private age: number;
}

// fail:
// Type 'B' is not assignable to type 'A'.
//  Types have separate declarations of a private property 'age'.
const test: A = new B();

对于 protected 成员,下面这种情况是兼容的:

class Base {
    protected age: number;
}

class A extends Base {
    public name: string;
}

class B extends Base {
    public name: string;
    protected age: number;
}

const test: A = new B();

注意理解什么是同一处声明子类中的私有成员跟父类中的私有成员没有半点关系,在子类中,对父类的私有成员既不能访问又不能覆盖;而受保护成员就相反了。

所以上述例子中, B 类中的受保护成员 age ,实际上和 Base 类中的 age 指向的是同一个数据成员,而更前面的例子中, B 类中私有成员 age 和 Base 类中的私有成员 age 是完全两个成员变量,所以 A 和 B 是不兼容的。

参数属性

TypeScript 中也可以在构造函数的参数里面声明成员变量:

class Animal {
    constructor(private name: string) { }
}

// 等同于

class Animal {
    private name: string;
    constructor(name: string) {
        this.name = name;
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容