1. 类的成员变量、成员方法,静态变量、静态方法、构造函数、实例化对象
// 创建类
class Student {
// 成员变量
name: string;
age: number;
// 静态变量
static other: string = "我是静态的变量,不常改变";
// 构造函数
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
// 成员方法
play(ball: string): void {
console.log(this.name + "在玩" + ball);
}
// 静态方法
static say(word: string): void {
console.log(this.other + "在说" + word);
}
}
// 创建类的实例化对象,通过实例对象来调用成员方法和变量
let alias = new Student("alias", 18);
alias.play("棒球");
console.log(alias.name);
// 通过类的名称直接调用静态方法和属性,注意:静态方法只能调用静态变量
Student.say("hello world");
console.log(Student.other);
2. 类的继承
1.单继承
// 父类
class Person {
public name: string;
constructor(name: string) {
this.name = name;
}
// 成员方法
play(ball: string): void {
console.log(ball);
}
}
// 子类
class Student extends Person {
public grade: string;
constructor(name: string, grade: string) {
super(name); // super 引用父类的构造函数
this.grade = grade;
}
// 方法重写:子类方法名和父类相同,将重写父类方法
play(ball: string): void {
console.log(this.name + "在玩" + ball);
}
}
const alias = new Student("alias", "一年级");
console.log(alias);
alias.play("篮球");
2.多继承
需要注意的是在 ts 中,子类只能继承一个父类,不可多继承,但是接口可以实现多继承
// Person1和Person2可以是接口,但不能是类
class Student extends Person1, Person2 {}
方式一:多重继承
TypeScript 不支持继承多个类,但支持多重继承
// 父类1
class Person1 {
public name: string;
constructor(name: string) {
this.name = name;
}
play(ball: string): void {
console.log(ball);
}
}
// 父类2 继承 父类1
class Person2 extends Person1 {
public age: number;
constructor(name: string, age: number) {
super(name); // super 引用父类的构造函数
this.age = age;
}
study(say: string): void {
console.log(this.name + say);
}
}
// 子类 继承 父类2
class Student extends Person2 {
public grade: string;
constructor(name: string, age: number, grade: string) {
super(name, age); // super 引用父类的构造函数
this.grade = grade;
}
// 方法重写:子类方法名和父类相同,将重写父类方法
play(ball: string): void {
console.log(this.name + "在玩" + ball);
}
}
const alias = new Student("alias", 8, "一年级");
console.log(alias);
alias.play("篮球");
alias.study("说:你好");
方式二:Mixins 模拟
// 父类一
class Person1 {
name: string;
constructor(name: string) {
this.name = name;
}
eat(food: string): void {
console.log(this.name + "吃" + food);
}
}
// 父类二
class Person2 {
age: number;
constructor(age: number) {
this.age = age;
}
play(ball: string): void {
console.log(this.age + "岁玩" + ball);
}
}
// 创建子类,把父类当成接口,内部的字段和方法必须和父类的字段和方法对应上,用于占位
// 用implements连接多个父类
class Student implements Person1, Person2 {
grade: string;
name: string;
age: number;
constructor(name: string, age: number, grade: string) {
this.age = age;
this.name = name;
this.grade = grade;
}
play(ball: string): void {}
eat(food: string): void {}
}
// 定义方法 applyMixins,使用js原型链操作连接子类的方法和父类的方法
function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach((baseCtor) => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
derivedCtor.prototype[name] = baseCtor.prototype[name];
});
});
}
// 把mixins混入定义的类
applyMixins(Student, [Person1, Person2]);
const alias = new Student("alias", 18, "一年级");
console.log(alias);
alias.eat("面包");
alias.play("棒球");
3. 类实现接口
- 在实现接口的类中,必须按照接口规范来定义类的成员变量和方法(重写接口中的所有变量和方法),只可多不可少
- 接口中定义的所有成员变量和方法都是抽象的,在实现它的类中必须都重写
- 在接口的成员变量后加 ? 代表此成员变量可不用被类重写
- 在接口中的成员方法不写方法体
// 定义接口规范
interface Person {
name: string;
age?: number; // 在接口的成员变量后加 ? 代表此成员变量可不用被类实现
eat(food: string): void; // 在接口中可不写方法体
}
// 定义类实现接口()
class Student implements Person {
name: string;
constructor(name: string) {
this.name = name;
}
// 在类中必写方法体
eat(food: string): void {
console.log(this.name + "吃" + food);
}
}
let alias = new Student("alias");
console.log(alias);
alias.eat("苹果");
4. 抽象类
- 抽象类不可以被实例化,只能被继承
- 抽象类中定义的抽象方法必须被继承它的子类重写
- 抽象类中的方法和变量可以是抽象的(被 abstract 修饰)也可以是不抽象的,但接口的方法和变量都是抽象的(都要被重写)
- 在抽象类中的抽象方法不写方法体
- 一个类只能继承一个抽象类
// 定义抽象类
abstract class Person {
name: string;
age?: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
// 非抽象方法
eat(food: string): void {
console.log(this.name + "吃" + food);
}
// 抽象方法,无方法体
abstract play(ball: string): void;
}
// 定义子类继承抽象类
class Student extends Person {
sex: string;
constructor(name: string, age: number, sex: string) {
super(name, age);
this.name = name;
this.sex = sex;
}
// 在子类中必须重写抽象类的抽象方法
play(ball: string): void {
console.log(this.name + "玩" + ball);
}
}
let alias = new Student("alias", 18, "女");
console.log(alias);
alias.eat("苹果");
alias.play("篮球");
网友评论