I think the point is, "how much low-level information should a client know?"
If you choose the first solution (abstract base class), you hide more detailed information about the client class. Thus, the client can completely ignore low-level details (protocol, external resource format). When the goal is to completely hide implementation details and types used inside this implementation, I prefer this approach.
Otherwise, if the client already knows some details of the low-level implementation (for example, the client knows that the socket it will use is UDP, and he also WANTS to know this information), then the abstract base class approach may be replaced by an internal "strategy" factory ".
source share