Inheritance (software) - SYSC3020-Winter2016/SYSC3020LectureNotes GitHub Wiki
Generalization is a general notion that can be used to model real-world objects. When it is applied to OO software, it has a more formal meaning.
- subtyping, type inheritance
- This is a “harmless” (rather good) form of inheritance.
- A subclass inherits attribute types and operation signatures (operation names plus formal arguments)
- A subclass is said to support a superclass interface.
- The implementation of inherited operations is deferred until later.
- The interfaces are normally declared through an abstract class, although in most languages an abstract class can provide partial implementations for some operations whereas a pure interface defers the definition of all operations
summary: some functionality is modified (re-implemented).
- Generalization can be used (deliberately or not) to imply code reuse and it is then realized by an implementation inheritance
- A very powerful, sometimes dangerously powerful, interpretation of generalization. It is also the “default” interpretation of generalization.
- Combines the superclass properties in the subclasses and allows overriding them with new implementations, when necessary
- Allows sharing of property descriptions, code reuse, and polymorphism: a method is polymorphic if it is defined for different types (related by inheritance) and has different meanings for different subclasses.
-> functionality is added to the superclass
- Inheritance as an incremental definition of a class.
- A subclass is-a-kind-of superclass
- This is a proper use of implementation inheritance
- The overriding of properties should be used with care. It should only be allowed to make properties more specific (e.g. to produce additional outputs, to make implementations of operations more efficient), not to change the meaning of a property.
functionality is removed from that of the superclass
- Inheritance as a restriction mechanism whereby some inherited properties are suppressed in the subclass
- This is a problematic use of inheritance
- A superclass object can still be substituted by a subclass object provided that whoever is using the object is aware of the suppressed properties (otherwise things may break!)
- When inheritance is used for the purpose of reusing code but does not implement a proper generalization.
- Subclass violates is-a rule.
- Example: Set implemented by inheriting from Hashtable.
- Convenience inheritance results in operations being inherited but meaningless in the context of the subclass. This is potentially dangerous as it can create confusion when one modifies or uses the subclass
- Convenience inheritance should be avoided and substituted with Delegation (covered in OO design (it's a pattern))
The Liskov substitution principle states that if a client code uses the methods provided by a superclass, then developers should be able to add new subclasses without having to change the client code.
This principle defines the notions of generalization / specialization in a formal manner.
Class S is correctly defined as a specialization of class T if the following is true: a client method written in terms of superclass T must be able to use instances of S without knowing whether the instances are of S or T. S is a said to be a subtype of T.
- Instances of a subclass can stand for instances of a superclass without any effect on client classes
- Any future extension (new subclasses) will not affect existing clients (Open-Closed principle)
- Any future extension (new subclasses) will not affect parent methods (Open-Closed principle)