Lecture 16 - 02/24
- Programs have a cost in terms of development time and execution time (more on latter in coming lectures)
- Program development/readability/debugging time improved by:
- Modularity: break the task into simpler subproblems
- Abstraction barriers between different modules of code/different classes
- Invariants: parts of an algorithm/data structure that must always hold true (such as size)
- Unit tests to test the functionality of different small components of a section of code, and comments on the tests to describe what they should do
- Comments on the constructors/methods to describe their purpose
- Modules are encapsulated if their implementation is completely hidden by an abstraction barrier, and we can only access through some API (Application Programming Interface)/suite of constructors and methods
- Implementation inheritance breaks encapsulation
- Let us have a superclass with method A and method B. Let method A call method B.
- Let us also have a subclass that overrides method B. Let this overridden method B call method A.
- Due to the overriding, when calling method B of an object of type subclass, we call the subclass's method B. This will in turn call the superclass's method A. Here is the difference: the method A calls method B, so before it would call method B of the superclass, but now it calls method B of the subclass. This change breaks encapsulation and could potentially lead to errors
- Moral: inheritance from classes across package boundaries is very risky; it is safe to extend classes that are specifically designed in documentation for extension; it is save to use inheritance within the same package, where both subclass and superclass are under the control of the same programmers