This is the basic scenario: A method returns a class of type A, but after looking at the internal workings of the code it is found safe to assume that it actually returns B (a subclass of A). Is it then valid to do something like this? Or would you highly discourage it because it is accessing protected data (at least):
Assume that you do not maintain this code that implements the method as well. I.e, your software could ship with a different implementation of this (well established) method.
A returnedData = executeMethod();
if(returnedData instanceof B)
{
((B)returnedData).someFunctionNotExposedThroughAIsItProtected();
//Use it as B, safe but non OOP and accessing protected functionality?
}else
writeAFallBackOfSomeSort();
The key point is the if(returnedData instanceof B)
: if such a statement exist, it is proven that the returned object is a B (which in turn also includes A), so using B public method is safe.
In pure OOP sense this is not "elegant", but it is often the pragmatic way to go.
Think a while: a Dog
is an Animal
, but is unlikely that Animal
has a do-nothing bark
method, otherwise -for completeness- it must have all methods for all possible animals may have, thus making Animal
a sort of "God Object" (a well known anti-pattern).
It is more pragmatic once you've got an Animal
, ask it to bark
only after you recognized it is a Dog
. You can have then more Dog
subclasses (representing different dog races) bark
ing differently, but bark belongs to Dogs
, not Animal
in general.
The problem now becomes: is it correct to suppose an Animal
could be a Dog
? If you can check it, why not!
Use OOP as a technique where convenient, not as a religion to serve.
Consider also that the answer can change depending on the language used and on what feature it has around objects and the way it define what a "object" is. Where no runtime dispatch exist (or where runtime dispatch is single and you need multiple) this can be even a well established method.