公共属性的修饰符:
- public:公共,默认修饰符,外部和内部都能使用
- private:私有的,只能内部类用,外部不能读写
- protected:当前类和派生类(子类)可访问
- readonly:外部只能读不能写
- static:静态属性或静态方法
类的定义
class User {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
getInfo = (): string => {
return `${this.name}的年龄是${this.age}`;
};
}
const u1 = new User("u1", 19);
const u2 = new User("u2", 20);
console.log(u1.getInfo()); // u1的年龄是19
console.log(u2.getInfo()); // u2的年龄是20
const users: User[] = [u1, u2];
console.log(users);
注意:
如果类中没有constructor ,则其中的属性需要初始化值,否则爆红
如果类中有constructor ,但参数中没有给定义的属性赋值,也会爆红
class Person {
name: string;
age: number; //属性“age”没有初始化表达式,且未在构造函数中明确赋值
constructor(name: string) {
this.name = name;
}
}
public
- 公共,默认修饰符,外部和内部都能使用
class User {
public name: string;
public age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
public getInfo = (): string => {
return `${this.name}的年龄是${this.age}`;
};
}
const u1 = new User("u1", 19);
console.log("u1:", u1);
u1.name = "张三";
console.log("u1_1:", u1);
- 父类的 public, 子类只能设置为 public
class Person {
public name: string = "";
age: number = 0;
public getInfo = (): string => {
return `${this.name}的年龄是${this.age}`;
};
}
// 类“User”错误扩展基类“Person”。
// 属性“getInfo”在类型“Person”中是私有属性,但在类型“User”中不是
class User extends Person {
constructor(name: string) {
super();
this.name = name;
}
private getInfo = (): string => {
return `姓名:${this.name}`;
};
}
protected
protected 修饰符指受保护的,只允许在当前类与子类使用,不允许在类的外部使用
class User {
protected name: string;
public age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
public getInfo = (): string => {
return `${this.name}的年龄是${this.age}`; // 内部是可以访问 protected 的
};
}
const u1 = new User("u1", 19);
u1.name = "张三"; // 属性“name”受保护,只能在类“User”及其子类中访问
console.log(u1.getInfo()); // 张三的年龄是19。虽然爆红,但依然能改
- 父类的 protected ,子类可以修改为 protected 或 public,但不允许修改为private
class Person {
name: string = "";
age: number = 0;
protected getInfo = (): string => {
return `${this.name}的年龄是${this.age}`;
};
}
// 类“User”错误扩展基类“Person”。
// 属性“getInfo”在类型“Person”中是私有属性,但在类型“User”中不是
class User extends Person {
private getInfo = (): string => {
return `姓名:${this.name}`;
};
}
private
private 修饰符指私有的,不允许在子类与类的外部使用
- 子类不能访问父类的 private 属性或方法
class Person {
protected name: string = "";
private age: number = 22;
protected info = (): string => {
return `${this.name}的年龄是${this.age}`;
};
}
class User extends Person {
constructor(name: string, age: number) {
super();
this.name = name;
this.age = age; // 子类不能访问父类的 private 属性或方法
}
public getInfo = (): string => {
return this.info();
};
}
const u1 = new User("u1", 19);
console.log(u1.getInfo()); // u1的年龄是19
- 父类声明的 private 属性或方法,子类不允许覆盖
class Person {
protected name: string = "";
private age: number = 0;
private getInfo = (): string => {
return `${this.name}的年龄是${this.age}`;
};
}
// 类“User”错误扩展基类“Person”。
// 属性“getInfo”在类型“Person”中是私有属性,但在类型“User”中不是
class User extends Person {
constructor(name: string, age: number) {
super();
this.name = name;
}
public getInfo = (): string => {
return `姓名:${this.name}`;
};
}
readonly
readonly 将属性定义为只读,不允许在类的内部与外部进行修改
class User {
name: string;
readonly sex: string;
constructor(name: string, sex: string) {
this.name = name;
this.sex = sex;
}
test() {
this.sex = "男"; //无法为“sex”赋值,因为它是只读属性
}
}
const u1 = new User("u1", "男");
u1.sex = "保密"; // 无法为“sex”赋值,因为它是只读属性
constructor
构造函数是初始化实例参数使用的
我们可以在构造函数 constructor 中定义属性,这样就不用在类中声明属性了,可以简化代码量
必须要在属性前加上 public、private、readonly 等修饰符才有效
class User {
constructor(public name: string) {}
getInfo = () => {
return this.name;
};
}
const u1 = new User("u1");
console.log(u1.getInfo()); // u1
static
static 用于定义静态属性或方法
class User {
static sex: string = "保密";
static getUserInfo() {
return "性别是" + User.sex;
}
}
console.log(User.sex); // 保密
console.log(User.getUserInfo()); // 性别是保密
get/set
使用 get 与 set 访问器可以动态设置和获取属性
class User {
constructor(public _name: string) {}
public get name() {
return this._name;
}
public set name(value: string) {
this._name = value;
}
}
const u1 = new User("u1");
console.log(u1.name); // u1
u1.name = "张三";
console.log(u1.name); // 张三
类实现接口 implements
类实现单个接口
interface IPerson {
eat: () => void;
}
// 类实现接口
class p implements IPerson {
eat() {
console.log("吃饭");
}
}
类实现多个接口
interface IPerson {
eat: () => void;
}
interface IPerson2 {
run: () => void;
}
// 正常
class p implements IPerson, IPerson2 {
eat() {
console.log("吃饭");
}
run() {
console.log("跑步");
}
}
// 异常
class p2 implements IPerson, IPerson2 {
eat() {
console.log("吃饭");
}
}
类同时继承父类, 又实现单个或多个接口
interface IPerson {
eat: () => void;
}
interface IPerson2 {
run: () => void;
}
class User {}
// 正常
class p extends User implements IPerson, IPerson2 {
eat() {
console.log("吃饭");
}
run() {
console.log("跑步");
}
}
// 异常
class p2 extends User implements IPerson, IPerson2 {
eat() {
console.log("吃饭");
}
}
类实现type
类既可以实现接口,也可以实现type
interface A {
name: string;
add: () => void
}
type B = {
age: number,
add: () => void
}
class C implements A {
name = 'xx'
add() {
console.log('类实现接口')
}
}
class D implements B {
age = 20
add() {
console.log('类实现type')
}
}