Instances of a supertype must be replaceable by instances of a subtype without altering the desirable properties of the program. That is the very definition of "subtype" using the Liskov Substitution Principle, which gives a behavioral contract-based notion of subtyping that takes aliasing into account.
This means that everywhere I have an instance of SomeClass
I can also use an instance of SomeInst
. However, in your example that is not true: if I have an instance i
of SomeClass
then I can call i.method(s)
, where s
is an instance of SomeType
. According to the Liskov Substitution Principle, I
must be able to do the same, when I call ii.method(s)
, where ii
is an instance of SomeType
. But I am not allowed to. I am only allowed to pass an instance of SomeTypeString
.
Ergo, your example violates the Liskov Substitution Principle, or, in other words, SomeInst
is not allowed to be a subtype of SomeClass
.
Note that this is actually not new. This was already known in the 1960s even before Barbara Liskov formulated the LSP, these are just the standard subtyping rules for functions:
- functions are contravariant in their parameter types
- functions are covariant in their return types