如何为游戏对象使用抽象构造函数?请修复我的继承代码问题
问题分析与解决方案
你遇到的核心问题是子类构造函数没有调用父类的构造函数,导致xCoord和yCoord这些实例属性没有被初始化到PlayerShip和EnemyShip的实例中。虽然你通过Object.create(Ship.prototype)把子类的原型链连到了Ship的原型上,但这只继承了原型上的方法/属性,实例属性必须通过调用父类构造函数来赋值。
修正后的代码
var player, enemies = [], enemiesCntInit = 10; // 父构造函数:Ship function Ship(x, y) { this.xCoord = x; this.yCoord = y; }; // 子类PlayerShip:必须调用父构造函数初始化实例属性 function PlayerShip(x, y) { // 调用Ship构造函数,将当前实例this传入,初始化xCoord和yCoord Ship.call(this, x, y); this.petrol = 100; }; // 继承原型,并修正constructor指向(避免原型链混乱) PlayerShip.prototype = Object.create(Ship.prototype); PlayerShip.prototype.constructor = PlayerShip; // 子类EnemyShip同理处理 function EnemyShip(x, y) { Ship.call(this, x, y); this.color = 'red'; }; EnemyShip.prototype = Object.create(Ship.prototype); EnemyShip.prototype.constructor = EnemyShip; player = new PlayerShip(100, 100); for(var i = 0; i < enemiesCntInit; i++) { enemies.push(new EnemyShip(0, 0)); } console.log(player); // 现在会包含xCoord:100, yCoord:100, petrol:100 console.log(enemies); // 每个EnemyShip实例都有xCoord:0, yCoord:0, color:'red'
如何实现抽象构造函数
抽象构造函数的核心是禁止直接实例化,只能作为父类被继承。在ES5中可以通过检查当前实例的构造函数是否为抽象类本身来实现:
function Ship(x, y) { // 如果直接new Ship(),抛出错误阻止实例化 if (this.constructor === Ship) { throw new Error('Ship是抽象构造函数,不能直接实例化,请继承后使用'); } this.xCoord = x; this.yCoord = y; } // 测试:直接实例化会报错 // var ship = new Ship(50,50); // 抛出Error // 子类正常继承并实例化 function PlayerShip(x, y) { Ship.call(this, x, y); this.petrol = 100; } PlayerShip.prototype = Object.create(Ship.prototype); PlayerShip.prototype.constructor = PlayerShip; var player = new PlayerShip(100,100); // 正常工作
如果用ES6 Class语法,实现抽象类会更直观,通过new.target判断当前调用构造函数的是否为抽象类本身:
class Ship { constructor(x, y) { if (new.target === Ship) { throw new Error('Ship是抽象类,不能直接实例化'); } this.xCoord = x; this.yCoord = y; } } class PlayerShip extends Ship { constructor(x, y) { super(x, y); // ES6中用super调用父类构造函数 this.petrol = 100; } } // new Ship(); // 报错 const player = new PlayerShip(100,100); // 正常创建实例
这样就保证了Ship只能被继承,不能直接创建实例,符合抽象构造函数的设计要求。
内容的提问来源于stack exchange,提问作者provoter33
相关产品推荐
相关产品推荐

