面向对象编程中的类缩减(与扩展相反)是否存在实现或理论研究?
通常在面向对象编程(OOP)中,我们会创建类层次结构:
class A{ //base class consists of field and method int a; void methodA(){} } class B extends A{ //derived class extends base class int b; //additional field @Override void methodA(){}//method overriding void methodB(){}//additional method } /* Instances of A and B are instances of A. Everything we can do with A can be done with B (API of A is included in API of B) */
从语义上讲,类的定义描述了我们对类实例施加的约束:实例必须拥有指定字段,且指定方法需能作用于类实例。因此理论上没有什么能阻止“类缩减”的实现——即创建/定义一个需求集更少的新派生类。这在我们需要定义实现了大部分基类需求和内部逻辑,但不满足其中子集的特殊类时会很有用。
class C reduces B{ /* reduction of class, breaks the rule that every derived class is instance of every class above in hierarchy, but lets programmer to not repeat same code */ @Remove int a; @Remove void methodB(){} /* removed members are not accessible to instance methods, and may not exist in memory at all. All kept dependent methods should be overridden to exclude dependency on removed members. */ }
缩减后的类C最终包含的成员如下:
class C { //result of reduction, C contains these members from ancestors int b; //from B void methodA(){} //from A }
为了兼容instanceof(或等效关键字)的使用,不能仅因为类C派生自B就将其称为A或B的实例,但它仍可能实现某些祖先类的API。对于非纯扩展的层次结构,应使用另一种算法来判断派生类与其祖先类的兼容性,需通过某种流程找到接口匹配的最近祖先,并使用其.class来评估instanceof。
类C可能没有int a和methodB(),但仍拥有来自类A的methodA()。如果int a不是公有的,C就实现了A的接口,应被视为A的实例。
我所知的所有语言都没有这种内置功能。
面向对象编程中的最佳实践是避免这种思路,开发者应重新设计层次结构而非缩减类。比如在Java中,可将类A定义为接口,再由B和C分别实现。
通常,若要通过缩减类来保留大部分内部逻辑,OOP建议将核心逻辑封装到独立类中,再通过组合将其加入类中,必要时暴露原有的公共方法,同样需使用公共接口。
要隐藏或“禁用”方法,可修改访问修饰符,或重写方法使其无实际操作或抛出异常。
当然这些替代方案确实存在且已被成功使用,但最初的想法是直接创建一个功能明确缩减但保留大部分内部逻辑的派生类,因此我认为这种“缩减”特性在高级编程语言的某些场景中会很有用。
请问这种类缩减概念是否已在某种编程语言中实现?或至少在相关理论研究中被讨论过?
内容的提问来源于stack exchange,提问作者TomatOgorodow

