你知道javascript 中 abstract 仍是一个保留字,因此目前来讲还不能像传统面向对象语言那样轻松地建立。抽象类是一种声明但不能使用的类,当你使用就会报错。不过javascript 是灵活的,因此咱们能够在类的方法中手动地抛出错误来模拟抽象类。javascript
// 汽车抽象类,当使用其实例对象的方法时会抛出错误
var Car = function(){};
Car.prototype = {
getPrice : function(){
return new Error('抽象方法不能调用');
},
getSspeed : function(){
return new Error('抽象方法不能调用');
}
};
复制代码
// 抽象工厂方法
var VehicleFactory = function(subType, superType) {
// 判断抽象工厂中是否有该抽象类
if(typeof VehicleFactory[superType] === 'function'){
// 缓存类
function F(){};
// 继承父类属性和方法
F.prototype = new VehicleFactory[superType]();
// 将子类 constructor 指向子类
subType.constructor = subType;
// 子类原型继承 “父类”
subType.prototype = new F();
} else {
// 不存在该抽象类抛出的错误
throw new Error('未建立该抽象类');
}
}
复制代码
// 小汽车抽象类
VehicleFactory.Car = function(){
this.type = 'car';
};
VehicleFactory.Car.prototype = {
getPrice : function(){
return new Error('抽象方法不能调用');
},
getSpeed : function(){
return new Error('抽象方法不能调用');
}
}
复制代码
//公交车抽象类
VehicleFactory.Bus = function(){
this.type = type;
};
VehicleFactory.Bus.prototype = {
getPrice : function(){
return new Error('抽象的方法不能调用');
},
getPaggerNum : function(){
return new Error('抽象的方法不能调用');
}
}
// 货车抽象类
VehicleFactory.Truck = function(){
this.type = 'truck';
};
VehicleFactory.Truck.prototype = {
getPrice : function(){
return new Error('抽象方法不能调用');
},
getTrainLoad : function(){
return new Error('抽象方法不能调用');
}
}
复制代码
你能够看到,抽象工厂类实际上是一个实现子类继承父类的方法,在这个方法中,咱们须要经过传递子类以及要继承父类(抽象类的名称) 而且在抽象工厂方法中又增长了一次对抽象类存在性的一次判断,若是存在,则将子类继承父类的方法。而后子类经过寄生式继承。继承父类 的原型,而是经过 new 关键字复制父类的方法。而后子类经过寄生式继承。继承父类过程当中有一个地方须要注意,就是对过渡类的原型继承时, 咱们不是继承父类的原型方法,还要继承父类的对象属性,因此经过 new 关键字将父类的构造函数执行一遍来复制构造函数中的属性和方法。 对抽象工厂添加抽象类也很特殊,由于抽象工厂是个方法不须要实例化对象,故只须要一份,所以直接为抽象工厂添加类的属性便可,因而咱们就 能够经过点语法在抽象工厂上添加咱们一下子须要的三个汽车簇抽象类 Car, Bus, Truck. 听我给你讲一下,既然抽象工厂是用建立子类的(而本例中实际上是让子类继承父类,是对子类的一个拓展)咱们须要一些产品子类,而后让子类继承相应的产品簇抽象类java
// 宝马汽车子类
var BMW = function(price, speed) {
this.price = price;
this.spped = speed;
}
// 抽象工厂实现对Car 抽象类的继承
VehicleFactory(BMW, 'Car');
BMW.prototype.getPrice = function(){
return this.price;
}
BMW.prototype.getSpeed = function(){
return this.spped;
}
复制代码
// 兰博基尼汽车子类
var Lamborghini = function(price, speed){
this.price = price;
this.speed = speed;
}
// 抽象工厂实现对Car 抽象类的继承
VehicleFactory(Lamborghini, 'Car');
Lamborghini.prototype.getPrice = function(){
return this.price;
}
Lamborghini.prototype.getSpeed = function(){
return this.speed;
}
复制代码
// 宇通汽车子类
var YUTONG = function(price, passenger) {
this.price = price;
this.passenger = passenger;
}
// 抽象工厂实现对 Bus 抽象类的继承
VehicleFactory(YUTONG, 'Bus');
YUTONG.prototype.getPrice = function() {
return this.price;
}
YUTONG.prototype.getPaggerNum = function() {
return this.passenger;
}
复制代码
// 奔驰汽车子类
var BenzTruck = function(price, trainLoad) {
this.price = price;
this.trainLoad = trainLoad;
}
// 抽象工厂实现对 Truck 抽象类的继承
VehicleFactory(BenzTruck, 'Truck')
BenzTruck.prototype.getPrice = function() {
return this.price;
}
BenzTruck.prototype.getTrainLoad = function() {
return this.price;
}
复制代码
经过抽象工厂, 咱们就能知道每一个子类究竟是哪一类别了,而后他也具备了该类所必备的属性和方法了。设计模式
var truck = new BenzTruck(100000, 1000);
console.log(truck.getPrice()); // 100000
console.log(truck.type); // truck
复制代码
抽象工厂模式是设计模式中最为抽象的一种,也是建立中惟一一种抽象化建立模式。该模式建立出的结果不是一个真实的对象实例,而是一个类簇,它制定了类的结构,这也就区别于简单工厂模式建立单一对象,工厂方法模式建立多类对象。固然因为Javascript中不支持抽象化建立于虚拟方法,因此致使这种模式不能向其余面向对象语言中应用的那么普遍。缓存