构造函数
我们来看一个简单的 Animal 类,这里我们能很清晰地看到 Animal 拥有 5 个成员 catName、dogName 属性,一个构造函数,以及 catSay、dogSay 方法。
class Animal {
catName: string;
dogName: string;
constructor(catName: string, dogName: string) {
this.catName = catName;
this.dogName = dogName;
}
catSay() {
console.log(`Mow, I'm ${this.catName}`);
}
dogSay() {
console.log(`Wong, I'm ${this.dogName}`);
}
}
在我们 Animal 类中,我们引用其中任意成员时都用了 this ,这表示我们访问的是类的成员。
public、private、protected 修饰符
public
在其他一些语言中,针对类的成员需要用修饰符来指定成员的可见性。而我们上述代码中并没有使用 public 修饰符来指定成员的可见性,这是因为在 TS 中,类的成员默认为 public。所以以下代码和上述代码语义上是一致的。
class Animal {
public catName: string;
public dogName: string;
public constructor(catName: string, dogName: string) {
this.catName = catName;
this.dogName = dogName;
}
public catSay() {
console.log(`Mow, I'm ${this.catName}`);
}
public dogSay() {
console.log(`Wong, I'm ${this.dogName}`);
}
}
private
private 表示私有成员,当类的成员被标记为 private 时,它将不能在类的外部被访问到。我们为 Animal 类增加一个 owner 的私有成员。
class Animal {
public catName: string;
public dogName: string;
private owner: string;
public constructor(owner: string, catName: string, dogName: string) {
this.owner = owner;
this.catName = catName;
this.dogName = dogName;
}
public catSay() {
console.log(`Mow, I'm ${this.catName}, I love ${this.owner}`);
}
public dogSay() {
console.log(`Wong, I'm ${this.dogName} I love ${this.owner}`);
}
}
const animal = new Animal("Evan", "Lily", "Coco");
console.log(animal.owner); // [ts] Property 'owner' is private and only accessible within class 'Animal'. [2341]
当我们尝试从 Animal 的实例 animal 中访问 owner 的时候,会报错并提示 owner 是私有成员。
protected
protected 表示受保护的成员,行为与 private 相似,同样不允许从类的外部访问,但可以在类的派生类中被访问,我们看如下代码。
class Animal {
public catName: string;
public dogName: string;
protected owner: string;
public constructor(owner: string, catName: string, dogName: string) {
this.owner = owner;
this.catName = catName;
this.dogName = dogName;
}
public catSay() {
console.log(`Mow, I'm ${this.catName}, I love ${this.owner}`);
}
public dogSay() {
console.log(`Wong, I'm ${this.dogName} I love ${this.owner}`);
}
}
class FindAnimalOwner extends Animal {
public findOwner() {
// 此时受保护的 Animal 成员 owner 可以被访问
console.log(`Owner is ${this.owner}`);
}
}
const findAnimalOwner = new FindAnimalOwner("Ivan", "Lily", "Coco");
console.log(findAnimalOwner.findOwner()); // Owner is Ivan
静态成员
我们在上文中讨论的都是类的实例成员,仅当类被实例化时才会被初始化。除了实例成员,在 TS 中,类还拥有静态成员,静态成员存在于类上面而不是类的实例上。
我们给 Animal 增加 catAge 和 dogAge 两个静态属性。
class Animal {
public catName: string;
public dogName: string;
private owner: string;
static catAge: number = 5;
static dogAge: number = 3;
public constructor(owner: string, catName: string, dogName: string) {
this.owner = owner;
this.catName = catName;
this.dogName = dogName;
}
public catSay() {
// 通过 Animal.catAge 来访问 catAge, catAge是存在于类本身的属性,而不是存在于实例上。
console.log(
`Mow, I'm ${this.catName}, I love ${this.owner}, I'm ${
Animal.catAge
} years old.`
);
}
public dogSay() {
console.log(
`Wong, I'm ${this.dogName} I love ${this.owner}, I'm ${
Animal.dogAge
} years old.`
);
}
}
const animal = new Animal("Evan", "Lily", "Coco");