If a School
class relies on an EmailSender
class you might have to inject this EmailSender
through it's constructor with a generic interface like IMessagable
or IMessageSender
or even IEmailSender
so that it can be swapped out for something else in the future.
In order to do this you would create a read-only private field in the School
class.
But then you're saying that the School
HAS-A MessageSender
but surely it just USES it in a few of it's methods??
Even if a class only uses one of many methods in a passed-in object, the entire object is still considered a dependency of the class.
This becomes evident when you change the API (the method signatures) of an object. By handing that object to a class, you essentially guarantee that object's "contract." If you change that object's API, you risk breaking classes that depend on it.
That's why we often use Interfaces to pass dependencies to classes. The interface enforces the contract between the class and its dependency, and encourages decoupling because the passed in object has to conform only to the interface's methods.
The nomenclature IS-A and HAS-A is used primarily to distinguish inheritance from composition.