LSP violation or not

From: Niklas Matthies (usenet-nospam_at_nmhq.net)
Date: 08/11/04


Date: 11 Aug 2004 01:32:59 GMT

Let's say I have a TextInput widget class with setText()/getText()
accessors. I want to provide an IntegerInput widget class with
setInteger()/getInteger() accessors which is going to be implemented
in terms of the TextInput widget class (because the integer will be
displayed to/typed in by the GUI user as text). The "clean" way, of
course, is to use composition/delegation to hide this implementation
detail.

For technical reasons I don't want to go into, having a TextInput
widget wrapped in an IntegerInput widget causes certain non-trivial
implementation complications and has a negative impact on certain
efficiency aspects. Those would go away if IntegerInput simply
inherits from TextInput. This would even be correct insofar as an
IntegerInput is-a TextInput, just with a restricted set of possible
inputs.

The problem, of course, is that setText() would have to be overridden
to only accept strings that correspond to integers, while the contract
of TextInput can be understood to accept any strings (up to a certain
length). Thus IntegerInput would violate the LSP, since it can't be
used anywhere a TextInput can be used. (For example a unit test for
TextInput is quite likely to fail, given an IntegerInput.)
The situation is actually pretty similar to the classic circle/ellipse
example.

My question is: Do you think it's nevertheless acceptable to derive
IntegerInput from TextInput? Or maybe there should be a common base
class that is identical to TextInput except that it leaves unspecified
what values setText() may accept (a distinction which might appear
pretty subtle to the users of the classes), and have both TextInput
and IntegerInput derive from it?

(There's another solution for implementing IntegerInput, namely to not
make it a widget in its own right, but make it a mere adapter for
TextInput instances which provides an "integer view" of it. But for
reasons of ease-of-use there is a requirement for IntegerInput to be a
real, fully-featured widget. For example it must be registerable as a
child of some parent widget and behave accordingly.)

-- Niklas Matthies



Relevant Pages

  • Re: LSP violation or not
    ... abstract validateInput(string newtext) // throw if you don't like ... > Let's say I have a TextInput widget class with setText/getText ... > in terms of the TextInput widget class (because the integer will be ... > widget wrapped in an IntegerInput widget causes certain non-trivial ...
    (comp.object)
  • Re: LSP violation or not
    ... >setInteger/getIntegeraccessors which is going to be implemented ... >in terms of the TextInput widget class (because the integer will be ... >For technical reasons I don't want to go into, having a TextInput ... >widget wrapped in an IntegerInput widget causes certain non-trivial ...
    (comp.object)
  • Re: LSP violation or not
    ... > Let's say I have a TextInput widget class with setText/getText ... > in terms of the TextInput widget class (because the integer will be ... > widget wrapped in an IntegerInput widget causes certain non-trivial ... Subclassing in the way you describe would constitute a violation of the LSP, ...
    (comp.object)
  • Re: LSP violation or not
    ... >> TextInput widget wrapped in an IntegerInput widget ... >> Those would go away if IntegerInput simply inherits ... We have input forms with several hundreds of input fields (lots ...
    (comp.object)
  • Re: LSP violation or not
    ... > in terms of the TextInput widget class (because the integer will be ... > For technical reasons I don't want to go into, having a TextInput ... > widget wrapped in an IntegerInput widget causes certain non-trivial ...
    (comp.object)