Home > Blockchain >  How to invoke a public method depending on a certain instance property?
How to invoke a public method depending on a certain instance property?

Time:11-25

I'm learning Typescript and I'm trying to run method in a class. I have a Class Person, and two classes which extends the Person Class: Man and Woman.

I also have an array of persons, and I need returns hello man! or hello woman! if person is a man or if is a woman.

This is my code:

abstract class Person {
    static population: number = 0;
    constructor() {
        Person.population    ;
    }
}

class Man extends Person {
    age!: number;

    constructor(age: number) {
        super();
        this.age = age;
    }

    public helloMan() {
        console.log('Hello Man!');
    }
}

class Woman extends Person {
    age!: number;

    constructor(age: number) {
        super();
        this.age = age;
    }

    public helloWoman() {
        console.log('Hello Woman!');
    }
}

let persons: Person[] = [];
persons.push(new Man(24));
persons.push(new Woman(27));
persons.push(new Man(42));
persons.push(new Woman(35));

for(let person of persons){

    let typeOfPerson = Object.getPrototypeOf(person).constructor.name;
    switch (typeOfPerson) {
        case "Man":
            // run helloMan method
            break;
    
        case "Woman":
            // run helloWoman method
            break;
    
        default:
            break;
    }
}

¿How I can run the method of each gender?

expected result:

Hello Man!
Hello Woman!
Hello Man!
Hello Woman!

CodePudding user response:

I would use instanceof here:

if (person instanceof Man) {
    person.helloMan()
} else if (person instanceof Woman) {
    person.helloWoman()
}

CodePudding user response:

The beneath provided refactored JavaScript version of the OP's originally provided TypeScript implementation comes with a modeling which now justifies the existence of a Person class more than what got provided with the question.

The modeling provided by the OP was neither in need of a Person class nor of inheritance at all. The explanation was already given with my above 2 comments ...

"@dryant ... 1/2 ... As Anatoly already did mention the entire purpose of inheritance is code-reuse, therefore it does not make any sense to implement two gender specific salutation methods (like with helloWoman / helloMan). The OP her/himself treats Woman/Man instances as Person types. Thus the OP wants to somehow have implemented a generic hello method which then returns the correct result from each gender specific context."

"@dryant ... 2/2 ... And for the OP's current solution where one needs to figure out a person instance's gender via instanceof one does not need a Person class at all since it gets exclusively used as namespace which features a sole population count where the value gets incremented with every instantiation."

// count is protected by module scope
let populationCount = 0;

class Person {
  #gender
  #age;
  #salutation;

  constructor({
    gender = 'not provided',
    age = null,
    salutation = 'Hello!',
  }) {
    populationCount  ;

    this.#gender = gender;
    this.#age = age;
    this.#salutation = salutation;
  }
  get gender() {
    return this.#gender;
  }
  get age() {
    return this.#age;
  }
  hello () {
    console.log(this.#salutation);
  }
  // - neither a `Person` instance nor the `Person`
  //   class itself should feature a property or
  //   method for exposing the population count.
  // - the latter easily can be achieved by an
  //   additionally exported function/method.
}

class Man extends Person {
  constructor({ age = null, salutation = 'Hello Man!' }) {
    super({ gender: 'male', age, salutation });
  }
}
class Woman extends Person {
  constructor({ age = null, salutation = 'Hello Woman!' }) {
    super({ gender: 'female',  age, salutation });
  }
}

const persons = [
  new Man({ age: 24 }),
  new Woman({ age: 27 }),
  new Man({ age: 42 }),
  new Woman({ age: 35 }),
];
console.log({  populationCount });

for (const person of persons) {
  person.hello();
  console.log([

    ({ female: 'Woman\'s', male: 'Man\'s'})[person.gender] ?? 'Person\'s',
    'age is',
    person.age,

  ].join(' '))
}
.as-console-wrapper { min-height: 100%!important; top: 0; }

  • Related