I have a class Person like this:
class Person {
constructor(name, age, gender, interests) {
Object.assign(this, {name, age, gender, interests});
}
}
And I can make sub-class like this:
class Teacher extends Person {
constructor(name, age, gender, interests, subject, grade) {
super(name, age, gender, interests);
Object.assign(this, {subject, grade});
}
}
But what if I want to make sub-class but I don't want to inherit all the properties from the Person class. For example I don't want to inherit the interests property. Do I just exclude it like this:
class Student extends Person {
constructor(name, age, gender, height, weight) {
super(name, age, gender); // I haven't included the interests property here
Object.assign(this, {height, weight});
}
}
I am still beginner so I am not sure if this is good practice or not. Have a nice day!
2 Answers 2
super(name, age, gender); // I haven't included the interests property here
By not adding an argument to a function call, the parameter will implicitly be undefined. The upper therefore equals:
super(name, age, gender, undefined)
Therefore the interests property does still exist, it is just undefined. That is actually a good solution if all your code assumes that interests could not be defined. If not, e.g. if you are doing calculations with it without an explicit check, your calculations might suddenly be NaN, which gets you into some trouble:
if(person.age > 18) {
alert("adult");
} else alert("child"); // or maybe the person is not a child, and it's age property was just not set?
Now instead of setting that existing property to a value that indicates that it is undefined, you could omit the interests property at all, by:
1) Moving it to a subclass:
class Person {
constructor(name, age, gender) {
Object.assign(this, {name, age, gender });
}
}
class PersonWithInterests extends Person {
constructor(name, age, gender, interests) {
super(name, age, gender);
Object.assign(this, { interests });
}
}
2) Create a Mixin:
A Mixin is a class, that can extend more than one class. If more than a Person has an interest, it might be benefitial to create a mixin for it:
const Interested = Super => class InterestMixin extends Super {
constructor(args) { // passing in an object here makes the Mixin more flexible, all superclasses have to deal with it though
super(args);
this.interests = args.interests;
}
};
class Animal { }
const PersonWithInterest = Interested(Person);
const AnimalWithInterest = Interested(Animal);
new PersonWithInterest({ name: "Jonas", interests: 10 })
new AnimalWithInterest({ type: "bear", interests: 20 })
(If you end up creating a new Mixin for every single property, this solution is not really viable anymore. If you can't group multiple properties into a useful Mixin, go with the first way instead (having optional properties)).
2 Comments
Inheritance means what it means ... you inherit what the parent gives to you. So 'avoiding attributes' it not really recommended (and I'm not sure you can even do it).
Two solutions :
- Architecture wise (that I recommend): in your specific case, I would just put
interestsin theTeacherclass. If other classes would have theintereststoo, I would create a sub-class likePersonIntereston whichTeacherwould inherit from. - Code wise: you set
intereststonullorundefinedin the class where you don't need it.
13 Comments
undefined gets added through a Subclass.Teacher is indeed a person with an interest and every Student isn't (that's a big assumption). But then you try to add another optional property - PersonWithFavouriteColor. You now have to inherit from two things to get the two optional properties. Add a couple more and a couple more actual classes (e.g., Accountant and Merchant) and try to give each a different set of the optional properties. It's not scalable.
Personshould perhaps not includeinterestsand another typeInterestedPersonbe created to have that property.Studentis aPerson. If aPersonhasinterests, so does theStudent. A child class can always be substituted anywhere the parent class could be used.InterestedPersonneed not even be a class you inherit, you could acquire it through object composition. Otherwise what happens if you do have a teacher who has an interest?