And that brings me to a topic that's entirely different but also very relevant: job interviews bring interviewer-biases with them.
If you run into an old-school interviewer who would do exactly that "Prius extends Car extends Vehicle, etc." nonsense, but you don't know it, they would rate you negatively.
If you run into someone who is just in love with functional programming, you'll lose any OO implementation.
If you run into someone who doesn't like it when you ask questions, you'll lose. If you run into someone who doesn't like you asking questions they don't know the answer to, you lose.
And if you get sent a 3-hour long Hackerrank or Leetcode algorithmic test, everybody loses.
Tech job interviews are just horribly biased and the game is won if you read your audience correctly. And even then, if the other person is a racist, or just doesn't like your face, or had a bad day, or feels threatened, or disapproves of how you write "Javascript" instead of "JavaScript", you still lose.
So don't project programming ideals you don't believe in. If they can't reconcile different opinions, it's their problem. You won't have the conviction or experience to do it convincingly anyway.
The exact example the grandparent used was essentially a wrong answer, so our "old-school interviewer" (that sounds kind of ageist doesn't it?) marking us down for not using it is a bad thing.
An interviewer who loves functional programming and doesn't communicate any preference then marks you down for not reading their mind is someone to avoid.
An interviewer who punishes you for asking questions is a huge red flag and you'll be dodging a huge bullet.
I'm a self-taught dev so I definitely have some thoughts on how tech interviewing goes, but an interview runs both ways. I'd much rather miss out on a job because the other person was racist or they hate when people ask questions, than to end up working with them.
You'd think common sense would tell one not to define what's good for them in general based on what's good for you when they're "missing rent with an eviction and sleeping in your car".
Similar works backwards, if you're using the interview to also ask the right questions, good people are generally not going to lie to you...
I think this is a different challenge related to the "background" hidden context: training interviewers. I think the "foreground" discussion point ("please make me a car") is way less relevant than the skill of an interviewer.
For about a year I tried this with every candidate: literally tell them what I am looking for in the interview and what is on my scorecard. Nobody asked any questions even once.
That's actually a win in your book, not a loss!
It takes a brave interview candidate to say "the best solution depends on the exact nature of the problem - and your problem doesn't make any sense so there's no valid solution".
I got that a few times and it's a good sign I have a senior candidate.
The real-world use case is simple when you imagine that I want to get a JSON payload describing different car configurations, possibly for a "car configurator" on a sales website, or perhaps for a videogame where there are different cars with different attributes at random. Once I go from "make a car" to "give me some json" everyone started to see it's as a less fictitious problem.
> Prius extends Car extends vehicle extends motor extends
The problem isn't that it's too in-depth, or too overbuilt, that answer is as close to objectively wrong as you get on a pretty open ended question and I'd imagine only an extremely junior developer would come up with that.
For example, you could maybe argue that a model of car extends a specific car. I'd expect an experienced developer to favor composition over inheritance at that stage, but that's open to debate.
But if a Vehicle extends a motor, does a motor extend a piston? Does a wheel extend a lug nut?
At that point you're moving away from "arguably correct" to just plain failing to answer the question. It shows they don't know the difference between composition and inheritance.
> It takes a brave interview candidate to say "the best solution depends on the exact nature of the problem - and your problem doesn't make any sense so there's no valid solution".
You're free to ask questions, we're supposed to be trying to collaborate. I don't think it's "brave" to instead say "your problem doesn't make sense". Shows more hubris than anything.
How is it any different than a systems design question?
You can’t add code to ducks.
You can’t refactor ducks.
Ducks don’t implement protocols.
If I got asked this question I'd probably spend the whole interview inquiring about the purpose of the modeling. It's for a simulation? What info do you want to get from the simulation? It's for an ERP app?I don't have problems with simple tasks which are not real-world but abstract something from the real-world use cases. The problem with "model me a car" is that it abstracts nothing.
Also for the most real-life purposes of modeling a car factory you wouldn't even have a "Car" in your object hierarchy.
It wasn't until I started trying to make a simple video game that these concepts made sense: an "Enemy" class could have properties of health and speed that a "Boss" or "Minion" could inherit from, etc.
Virtual functions are about implementation: a derived type that overrides a virtual function does so specifically in order to deliver a specialized implementation.
The degree to which your class's virtuals match its public interface is an exact measure of how bad that interface is, as an OO abstraction. If your class was doing enough work to earn its keep, it would be presenting an interface in terms the client wants to see. Those are implemented for variant internal representations by composing calls to one or more private virtual interfaces.
The above is true about OO subsystems. But not all uses of virtual functions are about OO. Virtual functions are a mechanism. Anywhere the mechanism is useful, it is OK to use it, OO or no OO.
Java offers no other organizational facilities than OO mechanisms, so there you have little choice but to use them everywhere. In problems not suited to OO solutions, use of virtual calls may have nothing to do with OO, and none of the OO rules need apply: if it works, it works.
Any language that offers only one kind of abstraction is a very poor and limited language. Calling it "pure" should not fool anybody. The world is complicated and demands many kinds of tools. Any one will only match certain aspects of certain problems.
I've seen it all. Prius extends Car extends vehicle extends motor extends ...
Right within the first five minutes of the interview.
But I also think these old "a bike extends a " tutorials were the most frustrating thing in the world and made no sense to me when I was trying to learn OOP in the first place. From my memory, I recall all the examples I could find were absolutely nonsense but blogs were full of posts with lots of non-real-world about connecting web requests things to a DB code and lots of "yeah it's just like a person is-a mammal which is-an animal which...".
It wasn't until I wrote some c++ and looked at how it worked in the heap and stack before I started to understand it better. Then later I learnt about SOLID and discovered that you almost never really want to use extension in practice (at least in the problems I worked on), except for things like interfaces in places you expect (and plan to have, and even better if you already do have) a reason for variations in sub-types that have the same contract, or need to cross system boundaries.
I almost always want to use composition. I will use extensions but this should be really specifically be selected for a few key points.