我想解决javascript OOP问题,但我的代码不完整



在这个挑战中,使用javaScript,你将创建3个类

  1. 超级叫Animal
  2. Dog类和Cat类,都扩展Animal类(狗是动物,猫是动物)
  3. DogCat类应该只有 1 个函数,这是自己实现的sound()函数。这是多态性
  4. 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();

}

}

最新更新