简体   繁体   中英

UML generalization without polymorphism

Is it possible to have a generalization relationship between two classes in which the subclass adds new operations that are not on the superclass (not overriding, not overloading)? It is not a LSP violation? I don't want polymorphism, just reuse of code in subclasses.

EDIT: the superclass is abstract, partially defined

Yes, UML allows defining new operations in a subclass that are not present in the superclass.

This is not necessarily a violation of the Liskov Substitution Principle. Instances of the subclass can be substituted where instances of the superclass are expected (but you don't have to exploit this).

However, make sure that instances of your subclass can really be considered instances of the superclass as well. If this is not the case and you just want to reuse code, the generalization is not the right solution.

Example: Class StringCollection has an operation sort. Now, you want to reuse this sort operation in a new class called FileManager. FileManager is not just a StringCollection, so you should not use a generalization. Instead, you could use a ≪use≫-dependency (FileManager uses StringCollection) or a composition (FileManager contains StringCollection).

A subclass can add new elements, like operations or attributes, to a more specific class that are not defined in the more generic class. Also the more specific class can override functions, hide attributes, and implement abstract operations. I guess LSP means Liskov's substitution principle.

If this is violated or not is less a syntactic question than can be answered by UML; instead it is a semantic question about reasoning about the meaning of the classes. Consider the classical example whether a square is more generic than a rectangle. Or is it vice versa? But syntactically both is the same, such as many other less questionable hierarchies.

The question about polymorphism is a bit tricky. UML does not use this term explicitly. But it states clearly that each instance of a more specific class(ifier) is also an instance of the more generic class(ifier) and inherits all of its features. This means there is no UML syntax that allows you to inherit the implementation only.

But you can solve this easily by applying a suitable design pattern. The question is not concrete enough to judge witch pattern is the most appropriate one but good candidates are strategy or bridge pattern. Then you have complete inheritance between the classes that implement your algorithms (and they can be private or less visible - depending on the language), but the classes that are used by the clients have no generalization relation and thus cannot be used in a polymorphic way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM