I'd say inheritance is NOT a good use-case for Person / Employee
A person can play many roles, at the same time. Composition is better in this case. A person has many roles
Inheritance is better for types of legal parties though (see The Party Model). A person is a legal party. An company is an organisation is a legal party
I'd say that inheritance, with method overriding, is the worst anti-pattern of mainstream OOP, which contains a number of otherwise sound ideas, like encapsulation.
I like the Go's approach to that (taken from Oberon), and the Rust's system of traits.
In one large codebase I saw there was a rule to make classes either abstract (without implementation of key parts), or final. Everything else is done via interfaces and composition.
> I'd say inheritance is NOT a good use-case for Person / Employee
Good call. If I wanted Person distinct from Employee, how I'd probably start, in an analysis model, is have Employment as an association/relationship between Person and Company.
In my meta-model, associations like Employment can have attributes, and that might be where things like "employee number" and "salary" come in.
And, taking that a little further, we can represent the history of how things like salary change over time.
(Meanwhile, a project that went with only an Employee record/object might not have saved any coding time initially, and they're quickly piling on expensive, hard-to-maintain kludges, just to meet evolving business needs. Even the first time an employee got a raise, they might've already been hitting incorrectness cases, just trying to get two parts of the system to use the right salary for the right time.)
A person can play many roles, at the same time. Composition is better in this case. A person has many roles
Inheritance is better for types of legal parties though (see The Party Model). A person is a legal party. An company is an organisation is a legal party