Câu hỏi khá cũ, nhưng tôi đã tạo ra một số giải pháp khả thi làm thế nào để tạo "lớp" trừu tượng và tạo khối của đối tượng kiểu đó.
//our Abstract class
var Animal=function(){
this.name="Animal";
this.fullname=this.name;
//check if we have abstract paramater in prototype
if (Object.getPrototypeOf(this).hasOwnProperty("abstract")){
throw new Error("Can't instantiate abstract class!");
}
};
//very important - Animal prototype has property abstract
Animal.prototype.abstract=true;
Animal.prototype.hello=function(){
console.log("Hello from "+this.name);
};
Animal.prototype.fullHello=function(){
console.log("Hello from "+this.fullname);
};
//first inheritans
var Cat=function(){
Animal.call(this);//run constructor of animal
this.name="Cat";
this.fullname=this.fullname+" - "+this.name;
};
Cat.prototype=Object.create(Animal.prototype);
//second inheritans
var Tiger=function(){
Cat.call(this);//run constructor of animal
this.name="Tiger";
this.fullname=this.fullname+" - "+this.name;
};
Tiger.prototype=Object.create(Cat.prototype);
//cat can be used
console.log("WE CREATE CAT:");
var cat=new Cat();
cat.hello();
cat.fullHello();
//tiger can be used
console.log("WE CREATE TIGER:");
var tiger=new Tiger();
tiger.hello();
tiger.fullHello();
console.log("WE CREATE ANIMAL ( IT IS ABSTRACT ):");
//animal is abstract, cannot be used - see error in console
var animal=new Animal();
animal=animal.fullHello();
Như Bạn có thể thấy đối tượng cuối cùng cung cấp cho chúng tôi lỗi, đó là vì Động vật trong nguyên mẫu có thuộc tính abstract
. Để chắc chắn nó không phải là Động vật không phải là thứ có Animal.prototype
trong chuỗi nguyên mẫu, tôi làm:
Object.getPrototypeOf(this).hasOwnProperty("abstract")
Vì vậy, tôi kiểm tra xem đối tượng nguyên mẫu gần nhất của tôi có thuộc abstract
tính hay không, chỉ đối tượng được tạo trực tiếp từ Animal
nguyên mẫu mới có điều kiện này đúng. Hàm hasOwnProperty
chỉ kiểm tra các thuộc tính của đối tượng hiện tại không phải nguyên mẫu của nó, vì vậy điều này cho chúng ta 100% chắc chắn rằng thuộc tính được khai báo ở đây không phải trong chuỗi nguyên mẫu.
Mọi đối tượng xuất phát từ Object đều kế thừa phương thức hasOwnProperty . Phương pháp này có thể được sử dụng để xác định xem một đối tượng có thuộc tính được chỉ định là thuộc tính trực tiếp của đối tượng đó hay không; không giống như toán tử in, phương thức này không kiểm tra chuỗi nguyên mẫu của đối tượng. Thông tin thêm về nó:
Theo đề xuất của tôi, chúng ta không phải thay đổi constructor
mọi lúc sauObject.create
như nó là trong câu trả lời tốt nhất hiện nay bởi @ Jordão.
Giải pháp cũng cho phép tạo nhiều lớp trừu tượng trong hệ thống phân cấp, chúng ta chỉ cần tạo abstract
thuộc tính trong nguyên mẫu.