I try to use the speak method also to re use with the Zebra class with composition.
SO I have it like this:
class Animal {
constructor(name, age) {
this.name = name;
this.age = age;
}
speak() {
return `my name is: ${this.name} and I am ${this.age} old`;
}
}
class Zebra {
constructor(Animal) {
this.animal = Animal();
}
}
let animal = new Animal("hello", 99);
let zebra = new Zebra();
console.log(zebra.speak());
also composition!!:
class Person {
String Title;
String Name;
Int Age;
public Person(String title, String name, String age) {
this.Title = title;
this.Name = name;
this.Age = age;
}
}
class Employee {
Int Salary;
private Person person;
public Employee(Person p, Int salary) {
this.person = p;
this.Salary = salary;
}
}
Person johnny = new Person ("Mr.", "John", 25);
Employee john = new Employee (johnny, 50000);
CodePudding user response:
I don't recommend to use composition in this case. This is a use-case for inheritance. But academic questions also deserve an answer.
Either use the animal
property to call speak
:
class Animal {
constructor(name, age) {
this.name = name;
this.age = age;
}
speak() {
return `my name is: ${this.name} and I am ${this.age} old`;
}
}
class Zebra {
constructor(animal) {
this.animal = animal;
}
}
let animal = new Animal("hello", 99);
let zebra = new Zebra(animal);
console.log(zebra.animal.speak());
or add a speak
method to Zebra
(this is a duplicate of another answer by accident. I didn't see it because it doesn't contain a runnable snippet):
class Animal {
constructor(name, age) {
this.name = name;
this.age = age;
}
speak() {
return `my name is: ${this.name} and I am ${this.age} old`;
}
}
class Zebra {
constructor(animal) {
this.animal = animal;
}
speak() {
return this.animal.speak();
}
}
let animal = new Animal("hello", 99);
let zebra = new Zebra(animal);
console.log(zebra.speak());
CodePudding user response:
This would be more of a thing you are looking for
const animal = {
age: 10,
name: 'hello',
speak() {
return `my name is: ${this.name} and I am ${this.age} old`
}
}
const zebra = {
...animal,
age: 100,
name: 'zebra'
}
console.log(zebra.speak())
CodePudding user response:
This is a simple delegation -
class Zebra {
constructor(animal) {
this.Animal = animal; // animal = Animal
}
speak() {
return this.Animal.speak();
}
}
You can also just use functions instead of new classes -
class Zebra {
constructor(speakFunctionality) {
this.speak = speakFunctionality;
}
}
let zebra = new Zebra((name,age) => { return `my name is: ${this.name} and I am ${this.age} old`; });
zebra.speak();
The first approach doesn't use composition in the best possible way - because when you want to reimplement or add another implementation you'll need to inherit Animal class or provide a type with speak()
method.
When doing something like this ask yourself "How do I add a new behavior" - Like you need to implement a Duck
how would you do it.
The second approach (With functions) is better because you don't need to provide new class
es but create functions - which are easier to manipulate in JS.
This is usually called Strategy pattern
where you inject a behavior through ctor or a function.
The example you provided , where you reimplement "Speak" is best suited for Inheritance
rather than Composition
.
A good example for composition would be a Car
with Engine
and different parts like Wheels
.
class Car {
constructor(engine){
this.Engine = engine;
}
}