design – What is “premature abstraction”?

It sounds a bit like you want to solve a problem that does not yet exist, and that you have no good reason to assume will occur, unless you just believe the client is wrong in what they’re requesting. If that’s the case, I would recommend more communication over implementing a guess solution, abstract or otherwise. While it might seem innocuous to just slap “abstract” on the class definition and feel safe knowing you can extend it later, you might find that you never need to, or you may find yourself extending it in ways that over-complicate the design down the line, by abstracting the wrong things.

Going with your example, do you imagine that it is the robot itself, the items being bagged or the method of bagging that will change down the line?

Premature abstraction really just means you have no good reason to perform the abstraction and since abstractions are far from free in many languages you may be incurring overhead without justification.

Edit To answer some points from OP in the comments, I’m updating this to clarify and respond in a way that doesn’t require a long comment chain while addressing points (1) and (2) more specifically.

(1) To me this sounds like the programmer isn’t being pragmatic enough, they have made assumptions that things would exist in the final program that doesnt, so they are working with to low of a level of abstraction, the problem isn’t premature abstraction, it’s premature concretion.

(Emphasis mine). Assuming things would exist in the final program that doesn’t is exactly what I see in your example. The customer asked for an item-bagging robot. This is a very specific request, if somewhat vague in its language. The customer wants a robot that bags items, so you produce a pair of objects

public class Item {
/* Relevant item attributes as specified by customer */
public class BaggingRobot {
  private Collection<Item> items;

  public void bag(Item item);

Your model is simple and precise, it follows the requirements set by the customer without adding any complexity to the solution and without making an assumption that the customer wanted more than they asked for. If, when presented with this, they clarify the need for the robot to have interchangeable bagging mechanics, only then do you have enough information to justify creating an interface or other method of abstraction, since you can now point to specific value that is added to the system through the abstraction.

On the contrary, if you start with abstraction from pure pragmatism, you either spend time creating a separate interface and implementing it in a concretion, or create an abstract class, or whatever manner of abstraction you like. Should it then turn out that the customer is satisfied with this, and no further extension is necessary, you have spent time and resources in vain, and/or introduced overhead and complexity into the system for no gain.

In regards to (2), I agree that omitting things of importance is not on its face a hallmark of premature abstraction. Abstraction or not, you can omit something of importance and unless its found far down the line of a chain of abstraction, it will not be harder or easier to sort that out either way.

Instead, I would interpret that as meaning that any abstraction runs the risk of obfuscating your domain model. Incorrect abstraction can make a system very difficult to reason about, since you are creating relationships that can drastically affect the further growth of the domain model and domain understanding. You run the risk of omitting not important information about the thing being abstracted, but about the system as a whole, by taking your model down the wrong rabbit hole.