Multiple inheritance without multiple inheritance and without code duplication

I have a theoretical question about how to deal with the following script in a language that does not allow multiple inheritance.

Imagine that I have a base class Foo, and from it I want to create three subclasses:

  • The Bar class inherits Foo and implements "A" functionality.
  • The Baz class inherits Foo and implements the "B" functionality.
  • The Qux class inherits Foo and implements the functionality of "A" and "B"

Imagine that the code for implementing the "A" and "B" functions is always the same. Is there a way to write code for "A" and "B" only once, and then apply the appropriate classes (or "inherit")?

+5
source share
4 answers

Well, the only way to see how you achieve this in C # / Java is with composition. Consider this:

class Foo { } interface A { public void a(); } interface B { public void b(); } class ImplA implements A { @Override public void a() { System.out.println("a"); } } class ImplB implements B { @Override public void b() { System.out.println("b"); } } class Bar extends Foo { A a = new ImplA(); public void a() { aa(); } } class Baz extends Foo { B b = new ImplB(); public void b() { bb(); } } class Qux extends Foo { A a = new ImplA(); B b = new ImplB(); public void b() { bb(); } public void a() { aa(); } } 

Now Qux has both Foo functionality through normal inheritance, and A and B implementations by composition.

+3
source

A more general term for this is Mixin . Some languages ​​provide out-of-box support, such as Scala and D. There are various ways to achieve the same results in other languages.

One way to create pseudo-mixin in C # is to use empty interfaces and provide methods using extension methods.

 interface A { } static class AMixin { public static void aFunc(this A inst) { ... //implementation to work for all A. } } interface B { } static class BMixin { public static void bFunc(this B inst) { ... } } class Qux : Foo, A, B { ... } 
+3
source

This is achieved in languages ​​where there are traits (here: ):

 class Foo { def fooM() {} } trait A { def aFunc() {} } trait B { def bFunc() {} } class Bar extends Foo with A {} class Baz extends Foo with B {} class Qux extends Foo with A with B {} 

Since Scala runs on top of Java (it has neither multiple inheritance nor features), it converts to something similar (simplified) - this may be a hint on how to implement it in Java / C # manually:

 class Foo { } interface A { void aFunc(); } interface B { void bFunc(); } class Bar extends Foo implements A { public void aFunc() { $A.aFunc(); } } class Baz extends Foo implements B { public void bFunc() { $B.bFunc(); } } class Qux extends Foo implements A, B { public void aFunc() { $A.aFunc(); } public void bFunc() { $B.bFunc(); } } class $A { public static void aFunc() {} } class $B { public static void bFunc() {} } 
+1
source

There are several ways to do something like this. More specifically, if at some point you abandon the aspect of inheritance, there are ways to introduce the same functionality for different classes when writing a unit only once.

Ok, I love AOP and they exist for many languages ​​(C # and Java have several). AOP Frameworks basically allows you to add standalone functions to different classes throughout the inheritance structure.

For C # you have PostSharp , and for Java you have AspectJ , among many others.

Many AOP frameworks allow you to "intercept" or "redefine" method calls without using inheritance.

+1
source

Source: https://habr.com/ru/post/983442/


All Articles