When should concrete public methods be used if implementing an interface?

Recently I have been trying to avoid down-casting object types from an interface type to their concrete types, and 'if' statements that check for an objects concrete type at run-time. This has made me ask myself a question; Why add public methods to concrete classes that also implement an interface?

I ended up making a distinction between 2 types of classes: a service and a data item, i.e. something you use versus something you create and push out (either to persistent storage or to another process). Usually a server-like class would have no constructor parameters unless it uses dependency injection or a factory (however, you could argue that a service being constructed inside a factory, before it starts being used like a service, matches the data item definition).

You would need to use public methods if you were creating an instance of a class for the first time and it was locally scoped to the method or class. However, when returning the instance from a method, and it implements an interface, usually you return it in its generic form (an interface). This makes the public methods not declared as part of the interface untouchable unless you cast it down to the concrete type which, in SE principles, is a bad thing. Often, if you need to do this then the concrete class should not be using an interface to begin with.

What is the convention for dealing with concrete public methods belonging to a class that implements an interface? Are they only used when the instance of a concrete class is in the same local scope?

Answers 1

This is way too broad. There are many languages where most classes implement various interfaces, e.g. Printable or Iterable, without that being their defining characteristic.

It's a good idea to avoid type-checking and downcasting objects in order to get at their public methods. Doing that shows that it was a mistake to declare an interface type in the first place.

But an object is not always used under the guise of its interface type. There can be many other legit uses where objects are declared as their true type, and it makes no sense to forbid different classes to have different methods merely they can both serve the same master.