Home > Mobile >  Compostion with javascript - no inheritance
Compostion with javascript - no inheritance

Time:10-22

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 classes 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;
  }
}
  • Related