在这个挑战中,使用javaScript,你将创建3个类
- 超级叫
Animal
。 Dog
类和Cat
类,都扩展Animal
类(狗是动物,猫是动物)Dog
和Cat
类应该只有 1 个函数,这是自己实现的sound()
函数。这是多态性Home
类。但我们稍后会讨论
// Javascript
var dog = new Dog();
dog.eat(); // -> 'Rax eat'
dog.sounds();// -> 'Dog barks'
var cat = new Cat();
cat.eat();// -> 'Stormy eats'
cat.sounds();// -> 'Cat meows'
现在让我们添加构图。创建一个名为Home
的新类。很多人家里都有狗和猫。Home
应该有一个名为adoptPet
的函数,它将任何Animal
作为输入。新宠物应存储在数组/列表中的Home
对象中。Home
对象还应该有一个名为makeAllSounds
的函数。它应该像这样工作:
// Javascript
var home = new Home();
var dog1 = new Dog();
var dog2 = new Dog();
var cat = new Cat();
home.makeAllSounds();// this doesn't give/return any result/data
home.adoptPet(dog1);
home.makeAllSounds();
// this prints :
// Dog barks
home.adoptPet(cat);
home.makeAllSounds();
// this prints :
// Dog barks
// Cat meows
home.adoptPet(dog2);
home.makeAllSounds();
// this prints :
// Dog barks
// Cat meows
//Dog barks
向adoptPet
添加一些功能,以便在您尝试两次领养同一只宠物时引发错误/异常
例如:
home.adoptPet(dog1) // totally ok
home.adoptPet(dog1) // not ok at all
问题结束。 这就是上面的问题。
现在这是我自己写的代码,下面写了解决问题,但不起作用,我不知道如何完成代码。
function Animal () { }
Animal.prototype.eat = function() {
return "Rax eat";
};
function Dog() { }
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructure = Dog;
Dog.prototype.sound = function() {
return "Dog barks";
}
let dog = Object.create(Dog.prototype);
let dog1 = Object.create(Dog.prototype);
let dog2 = Object.create(Dog.prototype);
function Cat() { }
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;
Cat.prototype.sound = function() {
return "Cat meows";
};
let cat = Object.create(Cat.prototype);
console.log (dog.sound())
console.log (cat.sound())
function Home() { }
Home.prototype = {
constructor: Home,
adoptPet: ["cat", "dog", "dog1", "dog2"]
}
自 2015 年以来,应该不再需要经历像这样分配prototype
属性的痛苦,并使用此类分配在两个类之间建立继承。
我建议完全重写代码,并使用class
语法,您不需要显式地进行此继承摆弄prototype
属性:
class Animal {
eat() {
return "Rax eat";
}
}
class Dog extends Animal {
sound() {
return "Dog barks";
}
}
class Cat extends Animal {
sound() {
return "Cat meows";
}
}
class Home {
constructor() {
this.pets = []; // Could be a `new Set` for better efficiency
}
adoptPet(animal) {
if (this.pets.includes(animal)) {
throw new Error("Cannot adopt the same pet twice");
}
this.pets.push(animal);
}
makeAllSounds() {
for (let pet of this.pets) {
console.log(pet.sound());
}
}
}
var home = new Home();
var dog1 = new Dog();
var dog2 = new Dog();
var cat = new Cat();
home.makeAllSounds(); // this doesn't give/return any result/data
console.log("== Adding dog ==");
home.adoptPet(dog1);
home.makeAllSounds(); // this prints: Dog barks
console.log("== Adding cat ==");
home.adoptPet(cat);
home.makeAllSounds(); // this prints : Dog barks / Cat meows
console.log("== Adding dog ==");
home.adoptPet(dog2);
home.makeAllSounds(); // ...
home.adoptPet(dog1) // not ok!
一个不好的做法是使用类的引用来知道它是否是同一种动物,使用一些标识符字段来知道它是否是同一只动物,为什么?
这是因为您可以拥有另一个对象的相同字段,但引用不同。
//Custom exceptions:
class BaseException extends Error{
constructor (message = "", fileName, lineNumber){
super(message, fileName, lineNumber);
this.name = "BaseException";
if (Error.captureStackTrace) {
Error.captureStackTrace(this, BaseException);
}
}
}
class ThePetExistsException extends BaseException{
constructor (pet ,fileName, lineNumber){
if(pet instanceof Animal){
super("The pet with id: " + pet.animalID + " exists.", fileName, lineNumber);
}
this.name = "ThePetExistsException";
}
}
//Closure
let counter = (function (){
let counter = 0;
return (function (){
return ++counter;
})
})();
class Animal{
constructor(){
this.animalID = counter();
}
}
class Cat extends Animal{
constructor(){
super();
}
sound(){
return 'Cat meows';
}
}
class Dog extends Animal{
constructor(){
super();
}
sound(){
return 'Dog barks';
}
}
class Home{
constructor(){
this.pets = new Array();
}
adoptPet(animal){
if(animal instanceof Animal && this.pets.findIndex(function(element){
if(element.animalID == animal.animalID){
return true;
}
}) == -1){
this.pets.push(animal);
}else{
throw new ThePetExistsException(animal);
}
}
makeAllSounds(){
this.pets.forEach(function(element){
console.log(element.sound());
});
}
}
//Instancing classes an checking.
let dog = new Dog();
let cat = new Cat();
let home = new Home();
try{
home.adoptPet(dog);
home.adoptPet(dog); //Error
home.adoptPet(cat);
home.makeAllSounds();
}catch(e){
if(e instanceof ThePetExistsException){
//Handle exception..
console.log("Handle exception ThePetExistsException");
home.adoptPet(cat);
home.adoptPet(new Dog());
home.adoptPet(new Cat());
home.adoptPet(new Dog());
home.adoptPet(new Cat());
home.adoptPet(new Dog());
home.adoptPet(new Cat());
home.makeAllSounds();
}
}