TypeScript中类继承实现与super关键字的使用疑问
TypeScript继承与super关键字相关问题解答
1. 当前代码的问题确认
你给出的代码确实存在参数未使用的问题:Student类的构造函数定义了3个入参,但你把this.firstName = firstName这类赋值逻辑注释了,所以实例化时传入的"x","y",22完全没有生效,最终print()输出的是你给类属性写死的默认值"x",这个问题和super的使用无关,只要把注释的3行赋值逻辑打开即可修复。
另外额外提一句:当前的继承设计存在逻辑不合理的问题,Student(学生)实体继承OsProject(操作系统项目)不符合常规业务抽象,更合理的设计是Student继承Person类,和项目类做关联而非继承,不过这属于业务设计范畴,不影响语法运行。
2. super的作用与必填规则
作用
super的核心作用是触发父类的构造函数执行,完成父类属性、原型方法的初始化挂载,只有执行完super之后,子类的this对象才能正确继承到父类的所有成员。比如你当前代码中,执行super之后Student实例才能访问到从Project、OsProject继承来的projectName属性、calculateBudget方法等。
必填规则
TypeScript有强制语法要求:只要子类显式声明了constructor构造函数,就必须在构造函数的第一行调用super(),否则会直接报语法错误。如果子类没有显式写constructor,TypeScript会自动生成一个默认的空构造函数,内部自动调用super(),这种场景不需要你手动写super。
3. super的常见使用场景
- 子类显式声明了自定义构造函数:这是最常见的场景,属于语法强制要求的必填项,没有特殊情况不能省略。
- 子类需要调用父类的同名方法:比如子类重写了父类的
calculateBudget方法,但内部还需要复用父类的原有逻辑,就可以通过super.calculateBudget()调用父类的实现。 - 父类构造函数需要传参:如果父类的constructor定义了入参,你需要在super中传入对应参数完成父类初始化,比如你给Project类添加构造函数
constructor(projectName:string, budget:number),那么OsProject的构造函数中就要写super("os项目", 1000)完成父类属性的初始化。
修复后可正常运行的代码示例
interface Person{ firstName: string; lastName : string; age: number; } ///////////////////////////////////////////// abstract class Project{ projectName: string = "sds"; budget: number = 1; calculateBudget(){ return this.budget*2 } abstract changeName(name: string): void } class OsProject extends Project{ changeName(name: string){ this.projectName = name } } ////////////////////////////////////// class Student extends OsProject implements Person{ firstName: string = "x"; lastName: string = "y"; age: number = 1; constructor(firstName: string, lastName: string, age: number){ super() // 打开注释完成参数赋值 this.firstName = firstName; this.lastName = lastName; this.age = age; } print(){ console.log(this.firstName) } } const myStudent:Student = new Student("张三","李四",22) myStudent.print() // 输出:张三
内容的提问来源于stack exchange,提问作者Shafagh Rastegari
相关产品推荐
相关产品推荐

