2022年4月13日 星期三

Problem of Inheritage (OOP)

Fragile base class

is a fundamental architectural problem of object-oriented programming systems where base classes (superclasses) are considered "fragile" because seemingly safe modifications to a base class, when inherited by the derived classes, may cause the derived classes to malfunction. The programmer cannot determine whether a base class change is safe simply by examining in isolation the methods of the base class.

Confused overloading

class Base
 {
 public void MyMethod(int i)
 {
  MessageBox.Show("Base method Int");
 }
  
 public void MyMethod(object i)
 {
  MessageBox.Show("Base Method Object");
 }
}
class Derived : Base
{   
}

now,

Derived MyObject = new Derived();
MyObject.MyMethod(1);

changed to:

class Base
{
 public void MyMethod(int i)
 {
  MessageBox.Show("Base method Int");
 }
}
class Derived : Base
{
 public void MyMethod(object i)
 {
  MessageBox.Show("Derived Method Object");
 }
}

and then,

Derived MyObject = new Derived();
MyObject.MyMethod(1);

the call to MyMethod(1) that previously correctly called MyMethod(int) in the Base class now calls MyMethod(object) in the Derived class.


Coupling interface and implementation

A class that is design to be inherited from is doing two things: it defines an interface through which any of its subclasses can be used, and it defines an implementation. But it also bundles these two things together into one class. This has a few negative effects:

  1. Any implementation of that interface is forced to also accept the base class’s implementation.
  2. The base class’s implementation frequently becomes fragile and difficult to change (more on that in a bit).
  3. We can no longer have several alternative base implementations on equal footing.


Open recursion

Open recursion is the technical name for how late-binding gets done in classes. When the base class calls another method on itself, expecting to get its own implementation, and gets a subclass implementation instead, that’s the general idea of what open recursion enables.

(fragile base class)

class SuperClass:
   def method1(self):
       self.method2()
   def method2(self):
       print(self.__class__.__name__)
 
= SuperClass()
s.method1()
 
class SubClass(SuperClass):
def method2(self):
    print(self.__class__.__name__)
 
sub = SubClass()
sub.method1()

You just want a different implementation of method 2, but keeps the behavior of method1. But now you changed both...