使用组合而非继承的JavaScript实现:复用speak方法问题
问题分析与解决方案
你的JavaScript代码存在几个关键问题,导致无法正常调用speak方法,对照你给出的Java组合示例,我们来逐一修正:
问题点梳理
- Zebra构造函数逻辑错误:你试图在构造函数里直接执行
Animal()(这会当作普通函数调用,而非类实例化),且没有正确接收外部传入的Animal实例,和Java中接收Person对象的逻辑不符。 - Zebra类未暴露speak方法:Java中Employee持有Person实例后,若要复用Person的方法也需要在Employee中做对应处理;同理,Zebra需要自己定义speak方法,转发调用内部Animal实例的方法。
- 实例化Zebra时未传入Animal实例:和Java中
new Employee(johnny, 50000)传入Person实例的逻辑一致,你需要把创建好的Animal实例传给Zebra的构造函数。
修正后的代码
class Animal { constructor(name, age) { this.name = name; this.age = age; } speak() { return `my name is: ${this.name} and I am ${this.age} old`; } } class Zebra { // 构造函数接收已实例化的Animal对象,和Java接收Person对象逻辑对齐 constructor(animalInstance) { this.animal = animalInstance; } // 定义speak方法,内部转发调用Animal实例的speak方法 speak() { return this.animal.speak(); } } // 创建Animal实例 let animal = new Animal("hello", 99); // 将Animal实例传入Zebra构造函数 let zebra = new Zebra(animal); console.log(zebra.speak()); // 输出: my name is: hello and I am 99 old
关键修改说明
- 构造函数参数调整:Zebra的构造函数现在接收一个已实例化的Animal对象,赋值给
this.animal,和Java中Employee持有Person引用的逻辑完全对应。 - 添加方法转发:Zebra类新增
speak方法,内部调用this.animal.speak()来复用Animal的方法逻辑,这是组合模式下复用方法的常规实现方式。 - 正确实例化Zebra:创建Zebra时传入已有的Animal实例,确保Zebra内部持有可用的Animal对象。
内容的提问来源于stack exchange,提问作者mightycode Newton
相关产品推荐
相关产品推荐

