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 treatsWoman
/Man
instances asPerson
types. Thus the OP wants to somehow have implemented a generichello
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 aPerson
class at all since it gets exclusively used as namespace which features a solepopulation
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; }