I agree! I actually wanted to include one, but as I started to explain it it started getting too wordy, which made the post feel like it was more about composition vs inheritance than classes vs alternatives, thus distracting from the main point.
I think this is mostly a limitation of me as a writer though rather than being an inherent thing. Ie. I think there's gotta be a way to give that example in a concise enough way where it doesn't distract from the main point.
Hm. I think your post would be a bit more compelling if you skipped examples of verbosity that are due to Java being shitty. JS would be simpler for the point? [nevermind the person who said that it's a low-quality post; it's just imperfect, not low-quality!]
The compositional method of this is for each employee to have an `EmploymentStatus` member which contains information relevant to their employment status -- so `ContractorStatus` would contain hourly rate as a field; `FullTimeStatus` would contain salary as a field, etc.
The class-based version of this puts the same attributes on the classes directly. Without additional fields that vary depending on the type, it doesn't make a lot of sense as an example. The `generatePayCheck` function doesn't demonstrate this, because it could just as easily be a standalone function that switches on the class or on an `employeeType: Contractor | PartTime | FullTime` field (and in languages that are less janky, this can be a discriminated union that includes additional fields in the type. I guess you can do that with Java via interfaces as well but it's not gonna be fun).
A function that switches on the type, or an instance method on varying classes, or a discriminated union, or a composed attribute -- these are all isomorphic... up until you find yourself needing another type of variation at the same time. Perhaps you're modeling a university workforce and people are also either `Administration | Educator | Service` employees. Now you can't have 3x3=9 total classes, so you _need_ composition (for at least one of the type hierarchies, possibly both).
The best place to use class hierarchies is when there is one 'canonical' inheritance hierarchy, rather than a bunch of ones that should be ideally compositional. What classes give you that unions don't is built-in methods, but you need those methods to be relevant to every type in the class hierarchy, so they really need to be intrinsic to the type of object you're talking about. For employees, `getPaycheck()` is probably a reasonable example of an actual class method for this reason.
I think this is mostly a limitation of me as a writer though rather than being an inherent thing. Ie. I think there's gotta be a way to give that example in a concise enough way where it doesn't distract from the main point.