TypeScript是一个结构类型系统。意思就是当我们比较两个类型的时候,只关注他们的架构是否一样,而不是在乎他们的原型是否一样。
但是,当我们谈到Class的时候,上面的结论并不总是正确。这个取决于我们的Class的属性是public, private,还是protected。
一:当Class的所有属性都是public
首先,当你不特别指定的时候,Class的属性默认是public的。
如果是2个基于某个class而new出来的对象,我们说这两个对象的类型是否兼容,只要看这个对象的结构是否一致,而不一定要对应的class是否是相同的。– 但是,这点只针对于class的所有属性都是public的时候。看下面的例子:
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
}
class Person {
name: string;
constructor(name: string) {
this.name = name;
}
}
let animal: Animal = new Animal('kitty');
let person: Person = new Person('nana');
animal = person; //这样是不会报错的,以为animal和person有相同的结构
animal = 1; //报错,数字number型和animal结构不一样。
二:当Class拥有private或者protect属性时候
当Class拥有private或者protected的属性的时候,光是结构一样,并不能带来类型一样的结果:
class Animal {
private name: string;
constructor(name: string) {
this.name = name;
}
}
class Person {
name: string;
constructor(name: string) {
this.name = name;
}
}
let animal: Animal = new Animal('kitty');
let person: Person = new Person('nana');
animal = person; //Error, 类型不一样
这段代码,我们仅仅是使得Animal的name变为private,并没有改变它的结构,但是animal和person已经是不同类型。当我们把person赋值给animal的时候,就会得到一个error。
这里我们是把Animal的属性改为了private,对于protected也是一样的结果。
三:Public, Protect, Private的区别
1: public的属性,可以在instance上访问
2: protect的属性,不可以在instance上访问,但是可以在子类里 面访问
3: private的属性,只能在本class内部访问
例如:
class Animal {
public category: string;
protected color: string;
private name: string;
constructor(category: string, name: string, color: string) {
this.category = category;
this.name = name;
this.color = color;
}
}
class Cat extends Animal {
constructor(category: string, name: string, color: string) {
super(category, name, color);
}
printInfo() {
console.log(`The category of the cat is ${this.category}`); // No Error
console.log(`The color of the cat is ${this.color}`);// No Error
console.log(`The name of the cat is ${this.name}`);//Error!
}
}
let animal = new Animal('animal', 'animal', 'white');
let cat = new Cat('cat', 'kitty', 'black');
animal.category = 'animal_1';//No Error. 可以在instance上访问public的属性
console.log(cat.color);//Error!不能在insatance上访问protect的属性
总结的话,我们的属性访问权限有3个level:
1:可以在instance上访问的:public
2:可以在子类里面访问的:public和protected
3:只可以在class内部访问的:private