- 静态成员
在类中定义的成员和方法都属于对象级别的,在实际的开发场景中,我们也需要去定义类级别的成员和方法。
通过关键字static来定义
class Student {
static call: string = 'kychen';
static attendClass() {
console.log('类中的方法...');
}
}
console.log(Student.call); // kychen
Student.attendClass(); // 类中的方法...
- 抽象类abstract
父类不需要对某些方法进行具体的实现,因此,在父类中定义的方法,我们可以定义为抽象方法。
抽象方法的特征:
- 抽象方法指的是没有具体实现的方法,也就是抽象方法。
- 抽象方法,必须存在于抽象类中
- 抽象类是使用abstract声明的类
- 抽象类的特征
- 抽象类是不能被实例化的
- 抽象方法必须被子类实现,否则这个类必须是一个抽象类
- 抽象类的测试
abstract class Person {
abstract getInfo(): string; // 定义抽象类公共的获取信息的方法
}
// 子类继承抽象类,实现抽象类中的抽象方法
// 学生类
class Student extends Person {
private _name: string = '';
constructor(sname: string) {
super();
this._name = sname;
}
getInfo() {
return 'student-name: ' + this._name;
}
}
// 教师类
class Teacher extends Person {
private _salary: number = 0;
private _post: string = '';
constructor(salary: number, post: string) {
super();
this._salary = salary;
this._post = post;
}
getInfo() {
return 'teacher-salary: ¥' + this._salary + 'teacher-post: ' + this._post;
}
}
function printInfo(person: Person) {
console.log(person.getInfo());
}
const stu = new Student('kychen');
const tec = new Teacher(8000, '中级教师');
printInfo(stu); // student-name: kychen
printInfo(tec); // teacher-salary: ¥8000teacher-post: 中级教师
- 接口定义可选属性
interface Person {
name: string;
age?: number;
info?: {
name: string;
}
}
const p: Person = {
name: 'stu',
age: 20
}
- 接口定义只读属性
interface Person {
name: string;
age?: number;
readonly info?: {
name: string;
}
}
const p: Person = {
name: 'stu',
age: 20,
info: {
name: 'stu2'
}
}
p.info = {}; // 报错,Cannot assign to 'info' because it is a read-only property.
- 索引类型
使用interface定义对象类型时,其中的属性名、类型、方法都是确定的
interface TagLabel {
[index: number]: string;
}
const tag: TagLabel = {
1: 'first',
2: 'second',
3: 'three'
}
console.log(tag['1']); // first
interface DevelopTime {
[name: string]: number;
java: number
}
const dev: DevelopTime = {
'javascript': 1996,
'java': 1995
}
console.log(dev['javascript']);
- 函数类型
// 接口
interface CalcFunc {
(num1: number, num2: number): number
}
const add: CalcFunc = (n1, n2) => {
return n1 + n2;
}
const sub: CalcFunc = (n1, n2) => {
return n1 - n2;
}
console.log(add(1, 5));
console.log(sub(3, 2));
接口可以定义函数的类型,但是除非个别情况,最好还是使用类型别名来定义函数
// 类型别名
type CalcFunc = (num1: number, num2: number) => number;
const add: CalcFunc = (n1, n2) => {
return n1 + n2;
}
const sub: CalcFunc = (n1, n2) => {
return n1 - n2;
}
console.log(add(1, 5));
console.log(sub(3, 2));
- 接口继承
接口和类一样是可以进行继承的,使用extends关键字,但是接口支持多继承,而类不支持多继承。
interface Student {
name: string;
eating: () => void;
studing: () => string;
}
interface Teacher {
driver: () => void;
write: () => void;
}
interface Examinee extends Student, Teacher {
sno: number
}
const exam: Examinee = {
sno: 0,
name: 'exam',
eating: () => { console.log('eating'); },
studing: () => { return 'studing' },
driver: () => { console.log('driver'); },
write: () => { console.log('write'); }
}
exam.eating(); // eating
- 接口的实现与使用
interface Student {
studing: () => void;
}
interface Teacher {
teaching: () => void;
}
class Parent implements Student, Teacher {
studing = () => {
console.log('studing');
}
teaching = () => {
console.log('teaching');
};
}
function teach(teacher: Teacher) {
teacher.teaching();
}
// 创建对象
const p = new Parent();
teach(p); // teaching
- 交叉类型
联合类型表示多个类型中的一个即可
type Alignment = 'left' | 'right' | 'center'
还有另外一种类型合并,就是交叉类型,交叉类型表示需要满足多个类型的条件,交叉类型使用&符号;
- 交叉类型的应用
在实际的开发场景中,通常是针对对象类型进行交叉的