JavaScript类继承:无需super自动调用父子类update方法
无需手动调用
super.update()实现父子类update逻辑自动执行的方案 要解决这个问题,推荐使用**钩子方法(Hook Method)**设计模式:将父类的核心update逻辑固定,同时提供一个子类可重写的钩子函数,父类会自动在update流程中调用这个钩子,这样子类无需手动调用super.update(),就能让父类和子类的逻辑依次执行。
具体实现步骤
1. 修改RigidBody类,引入钩子方法
将父类的update方法作为固定流程入口,内置重力与位置更新逻辑,然后调用一个默认空实现的钩子方法(比如onUpdate),子类通过重写这个钩子来添加自定义逻辑:
class RigidBody { gravity: Vector3 = new Vector3(0, -1, 0) acceleration: Vector3 = new Vector3(0, 0, 0) lastPosition: Vector3 = new Vector3(0, 0, 0) dt: number = 0 constructor() { super() } // 固定的update入口,子类无需重写此方法 update(tick: number) { // 父类核心逻辑:重力与位置更新 this.accelerate() this.updatePosition(tick) // 调用子类自定义逻辑的钩子 this.onUpdate(tick) } // 钩子方法:默认空实现,子类可重写添加自定义逻辑 protected onUpdate(tick: number): void {} updatePosition(tick: number) { if (this.object) { const velocity = this.object.position.sub(this.lastPosition) this.lastPosition = this.object.position.clone() this.object.position.add(velocity).add(this.acceleration.multiplyScalar(this.dt*this.dt)) this.acceleration.copy(new Vector3(0, 0, 0)) this.dt += .05 } } accelerate() { this.acceleration.add(this.gravity) } }
2. 修改Ball类,重写钩子方法
子类不再需要重写update方法,只需要重写onUpdate钩子,专注实现自己的碰撞逻辑即可:
class Ball extends RigidBody { constructor() { super() } // 重写钩子方法,实现自定义碰撞逻辑 protected onUpdate(tick: number) { if (this.object && this.geometry) { let radius = (this.geometry as SphereGeometry).parameters.radius let ground = __GAME__.sceneManager.get("ground") if (ground && ground.object) { if (this.object.position.y <= ground.object.position.y + radius) { this.object.position.y = ground.object.position.y + radius } } } } }
方案优势
- 无需手动调用
super.update(),避免了子类遗漏调用导致的逻辑缺失 - 代码结构清晰:父类负责核心通用逻辑,子类专注于自定义扩展
- 保持单一
update方法的优雅性,不需要拆分多个类似updatePhysics、updateCollision的方法 - 灵活调整执行顺序:如果需要子类逻辑先执行,只需将
this.onUpdate(tick)移到父类核心逻辑之前即可
内容的提问来源于stack exchange,提问作者Esteban MANSART
相关产品推荐
相关产品推荐

