oopinheritancetheory

Class reduction in OOP (as opposite to extension). Is it exists?


Usually in OOP we create class hierarchies


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)
*/

Semantically definition of classes describes constrictions that we put on instances of class: they have to have these fields and these methods should work with instances of the class. So, nothing in theory prevents implementation of "class reduction" - creation/definition of a new derived class with reduced set of requirements. It would be useful in cases where we need to define exceptional classes that implement most of base requirements and inner logic, but not subset of it.

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.
*/
}

class C { //result of reduction, C contains these members from ancestors
int b; //from B
void methodA(){} //from A
}

To maintain compatibility with instanceof(or equivalent) keyword usage, class C can't be called an instance of A or B just because it is being derived from B, but it still may implement API of some of its ancestors. With not pure extension hierarchies, another algorithm should be used to determine compatibility of derived class with it's ancestor. Some procedure should find closest ancestor with matching interface and use its .class to evaluate instanceof instead.
Class C may not have int a and methodB(), but it still have methodA() from class A. If int a is not public, C implements interface of A, and should be considered instance of A.

All languages I know don't have such embedded functionality.

Good practice in OOP is considered to avoid this type of thinking and instead of reducing classes, developer should instead rethink hierarchies. In this example, in Java class A can simply be defined as interface and be implemented separately in B and C.

Generally in case of reduction to preserve big part of internal logic, OOP suggests to encapsulate big logic in it's own class and then add it to class composition while exposing it's previously public methods (if necessary), again common interface should be used.

To hide or "disable" methods, access modifier may be changed or methods may be overridden to essentially do nothing or throw exception.

Of course these workarounds do exist and being used successfully. But the first intention was to simply make a derived class with explicitly reduced functionality, while preserving most of internal logic, that is why I think this "reduction" feature could be useful is some cases in high level programming language.

Is such concept already exists in any programming language? Or is it at least discussed in any theoretical work?


Solution

  • Yes, the concept of explicitly turning off a method exists in Ruby—you can call the method undef_method to turn off a method at class definition time. An attempt to call the undefined method causes a runtime exception:

    class Base
      def greet; puts "Hello"; end
    end
    
    class Derived < Base
      undef_method :greet
    end
    
    d = Derived.new
    d.greet # test.rb:9:in `<main>': undefined method `greet' for #<Derived:0x000000010991d188> (NoMethodError)
    

    See this answer for more information about undef_method and remove_method.