OpService: return requested Op with proper type

When asking for an Op of a particular type, it is nice to get back an
object typed according to that class, instead of typed as a general Op.

The only potential danger here is the Optimizer feature, which lets you
replace a Module with a different Module with identical behavior. This
change now enforces that the behavior indeed match with respect to the
object type returned by Module#getDelegateObject(). That is: that object
now needs to be type compatible with the originally requested type.