I have a theoretical question concerning how to deal with the following scenario in a language which does not allow multiple inheritance.
Imagine I have a base class Foo and from it I am wishing to create three sub-classes:
Class Bar inherits Foo and implements functionality "A"
Class Baz inherits Foo and implements functionality "B"
Class Qux inherits Foo and implements functionalities "A" and "B"
Imagine that the code to implement functionalities "A" and "B" is always the same. Is there a way to write the code for "A" and "B" only once, and then have the appropriate classes apply (or "inherit") it?
Well the only way I can see you achieving this in C#/Java is by 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() {
a.a();
}
}
class Baz extends Foo {
B b = new ImplB();
public void b() {
b.b();
}
}
class Qux extends Foo {
A a = new ImplA();
B b = new ImplB();
public void b() {
b.b();
}
public void a() {
a.a();
}
}
Now Qux has both the functionality of Foo via normal inheritance but also the implementations of A and B by composition.
The more general term for this is a Mixin. Some languages provide support out of the box, such as Scala and D. There are various ways to achieve the same results in other languages though.
One way you can create a pseudo-mixin in C# is to use empty interfaces and provide the methods with 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 {
...
}
This is achievable in languages providing traits (here: scala):
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 {}
Because Scala runs on top of Java (having neither multiple inheritance nor traits) it is translated into something like this (simplified) - which might be a hint 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() {}
}
There are several ways to do something like this. More specifically, if we abandon the inheritance aspect for a moment, there are ways to introduce the same unit of functionality to different classes, while writing the unit only once.
Okay, I love AOP Frameworks, and they exist for many languages (C# and Java having several). AOP Frameworks basically allow you add self-contained functionality into different classes throughout your inheritance structure.
For C#, you have PostSharp and for Java you have AspectJ, among many others.
Many AOP frameworks allow 'hijacking' or 'overriding' method calls without using inheritance.
Related
As I was learning about interfaces I came across the fact that they can be used to implement Multiple Interface Inheritance and that Multiple Class Inheritance is not possible in C#. So, I found the following code which implements multiple interface inheritance.
using System;
namespace Test
{
interface IB
{
void PrintB();
}
class A
{
public void PrintA()
{
Console.WriteLine("PrintA() Method.");
}
}
class B : IB
{
public void PrintB()
{
Console.WriteLine("PrintB() Method.");
}
}
class C : A, IB
{
B bObject = new B();
public void PrintB()
{
bObject.PrintB();
}
}
class Program
{
public static void Main()
{
C cObject = new C();
cObject.PrintA();
cObject.PrintB();
}
}
}
But in this code we are inheriting Class A directly. But for inheriting the method of Class B we are using interface IB.
Now, I can't see the advantage of doing so. We could write this code without using interface IB like this.
using System;
namespace Test
{
class A
{
public void PrintA()
{
Console.WriteLine("PrintA() Method.");
}
}
class B
{
public void PrintB()
{
Console.WriteLine("PrintB() Method.");
}
}
class C : A
{
B bObject = new B();
public void PrintB()
{
bObject.PrintB();
}
}
class Program
{
public static void Main()
{
C cObject = new C();
cObject.PrintA();
cObject.PrintB();
}
}
}
Now, why did we used interface in the first place, if we could write it without the interface?
Does this mean multiple inheritance can be done without using interfaces?
Or multiple inheritance cannot be done even using interfaces?
You are missing a point about virtual methods. We want to be able to do this:
interface IPrint
{
void Print();
}
class A : IPrint
{
public void Print()
{
}
}
class B : IPrint
{
public void Print()
{
}
}
...
foreach (IPrint p in printables)
{
p.Print();
}
Your approach cannot do that, because your PrintB in class C is just a method. Inheritance is not about having methods with the same name, but about defining verbs that perform an action on the instance of the class they are designed for.
Multiple Inheritance leads to the Diamond Problem. And that Diamond is a Programmers worst enemy.
So the designers of .NET or the CLI (I can never remember wich) decided they are were not going to deal with that, and mandated "single Inheritance only". Wich is one of the common strategies to deal with that "Diamond of Death".
As only allowing single Inheritance meant somet things would be missing, they Implemented Interfaces to offset it. It is one of the many ways in wich .NET is more restrictive then say Native C++ and had to invent a replacement for something trivial. But in the long run it prooved to be slightly better doing it this way.
I understand this is not possible in C#, because Generics are not Templates and they are implented differently(processing on runtime rather than during compile):
public class Foo<T> : T
{
}
The question though remains. Is there an equivalent or perhaps an alternative way to achieve this?
In my case I have three different parent classes I want to inherit from, let's call them A, B, C:
public class A {}
public class B {}
public class C {}
Then I have the Foo class, and then MANY more inheriting from Foo but each of them needing only one of the A, B, C:
public class X : Foo<A> {}
public class Y : Foo<B> {}
public class Z : Foo<C> {}
So class X needs all the functionality in Foo and all the functionality in A, Y from Foo and B and so on...
How do I do this in C#?
I suppose you cannot modify the A, B and C classes (otherwise you could just inherit all of them from Foo), therefore this is my idea:
I would define "Foo" as an interface (that I would call "IFoo"):
public interface IFoo {}
and implement all its methods as Extension methods:
public static class IFooExtension
{
public static void Method1(this IFoo f) {
// do whatever here;
}
}
then I'd declare the further classe as follow:
public class X : A, IFoo {}
public class Y : B, IFoo {}
public class Z : C, IFoo {}
The only issue (if it is an issue) is that you can implement whatever method you want, but no properties.
If class X: Foo<A> { } needs all the functionality of Foo and A, then simply expose A as property and you will have it:
public class Foo<T> where T : new()
{
public T Bar { get; } = new T();
public void FooMethod() => Console.WriteLine("Foo method");
}
public class A
{
public void AMethod() => Console.WriteLine("A method");
}
public class X : Foo<A>
{
}
class Program
{
static void Main(string[] args)
{
var x = new X();
x.FooMethod();
x.Bar.AMethod(); // access via property
}
}
I know it sounds trivial, but is it somehow possible to return the b field when i pass an A variable to a function which expects an IMyIntercace? Then i don't have to implement the Hello() function in the class A, instead i just return b as the IMyInterface.
interface IMyInterface
{
void Hello();
}
class A : IMyInterface
{
B b = new B();
}
class B : IMyInterface
{
public void Hello()
{
Console.WriteLine("Hello");
}
}
class Program
{
static void foo(IMyInterface myInterface)
{
myInterface.Hello();
}
static void Main(string[] args)
{
A someVariable = new A();
foo(someVariable);
}
}
I suppose it cant be done, but is there any design pattern or trick that could do it?
EDIT
The reason i dont want to derive A is because maybe i want to do this
class A : IMyInterface
{
B b = new B();
B b2 = new B();
IMyInterface bPointer;
}
Then i can point to one of the b's depending on some situation
You could inherit A from B.
A will continue to implement the interface and you may override every function you need to change in the future.
interface IMyInterface
{
void Hello();
}
class A : B
{
}
class B : IMyInterface
{
public void Hello()
{
Console.WriteLine("Hello");
}
}
No. Either A implements IMyInterface, in which case you don't need to do anything, or it does not, in which case there is no way to automatically "redirect" any interested parties to the b member.
You can either expose b (and preferably make it a property) to the outside world so that they can refer to it as required, or you can make A implement IMyInterface and manually forward all calls to b like this:
class A : IMyInterface
{
B b = new B();
public void Hello()
{
b.Hello();
}
}
Just make A.b public (or internal) and then call foo(someVariable.b).
What you want to have is interface delegation and unfortunately there is nothing built into the language to help you with that.
Basically, the A class has to implement the interface.
One way it can do that is of course to derive from B:
class A : B
{
}
But if you don't want to do that, then you need to delegate. What you have to do is to implement the delegation yourself so that you can delegate the responsibility of the actual implementation to the B class, you won't get any help from the compiler to fix this.
class A : IMyInterface
{
B b = new B();
public void Hello()
{
b.Hello();
}
}
I've never encountered this issue before today and was wondering what convention/best practice for accomplish this kind of behavior would be.
Basic setup is this:
public interface IDispatch {
void Dispatch();
}
public class Foo : IDispatch {
void IDispatch.Dispatch() {
DoSomething();
}
}
public class Bar : Foo {
...
}
Bar needs to subclass Foo because it shares all the same properties as Bar plus introduces 2 new ones that I need to encounter for. The problem I have is that Foo also needs a slightly different implementation of Dispatch(). Normally it would be overridden but thats not valid for an interface method so is it fine to just have Bar implement IDispatch as well so my class definition looks like this:
public class Bar : Foo, IDispatch { .... }
and then just do an explicit implementation of that interface method in Bar as well? My compiler doesn't seem to complain when I try to do it this way but I wasn't sure if it would cause any runtime issues resolving which implementation to use down the road or if there was a better way to accomplish something like this.
Also worth mentioning that at my workplace we use code generation from UML models which enforces that all class design must be done from a model first. The code generation tool is what causes interface methods to be implemented explicitly (don't want to debate the pros and cons of this its just what I'm forced to deal with right now so having an implicit implementation is not an option)
You could, alternatively, do this one of two ways:
First, don't implement the interface explicitly:
public class Foo : IDispatch {
public virtual void Dispatch() {
whatever();
}
}
public class Bar : Foo {
public override void Dispatch() {
whateverElse();
}
}
Second, implement it explicitly but add a function that the child class can override:
public class Foo : IDispatch {
void IDispatch.Dispatch() {
this.Dispatch();
}
protected virtual void Dispatch() {
whatever();
}
}
public class Bar : Foo {
protected override void Dispatch() {
whateverElse();
}
}
Yes, you can explicitly redeclare that you want to implement IDispatch, and implement it explicitly again in Bar.
However, you won't be able to call the original implementation in Foo. If you need to do that, you'll need to change Foo either to use implicit interface implementation with a virtual method (which can be overridden and then called with base.Dispatch() in Bar) or make the Foo implementation call a protected virtual method which again you'd override in Bar.
Bar already implements IDispatch if it is subclass of Foo, no need to explicitly state that. If you want to implement only one method of interface in a different way, do sth like this:
IDispatch { void Method(); }
Foo : IDispatch { public virtual void Method() { implementation1 } }
Bar : Foo { public override void Method() { implementation2 } }
You don't have to do the IDispatch.Dispatch - so long as a method called Dispatch is in your class you will have implemented the interface.
You can do this, it builds for me:
public class Foo : IDispatch
{
public virtual void Dispatch()
{
}
}
public class Bar : Foo
{
public override void Dispatch()
{
base.Dispatch();
}
}
I do prefer to explicitly implement interfaces. It's easier for people unfamiliar with your code base to understand what's an interface vs class specific logic.
You can still accomplish class inheritance while explicitly implementing interfaces. You just need to have the base class implement the interface, and have that implementation call into a virtual function which can be extended. Here's an example:
interface Inter
{
void Call();
}
class A : Inter
{
//Explicitly implemented interface
void Inter.Call()
{
this.Call();
}
public virtual void Call() { Console.WriteLine("Base call in A"); }
}
class B : A
{
public override void Call()
{
Console.WriteLine( "Called B" );
}
}
class Program
{
static void Main( string[] args )
{
var a = new A(); //Base class
var aa = (Inter)a; //Interface only
a.Call();
aa.Call();
var b = new B(); //Child class
var bb = (Inter)b; //Interface only of Child class
b.Call();
bb.Call();
//See the output before the console program closes
Console.ReadLine();
}
}
Program output:
Base call in A
Base call in A
Called B
Called B
I have the following c# classes:
class A : Object
{
foo() {}
}
class B : Object
{
foo() {}
}
I want to write a generic method that applies to both:
void bar<T>(T t)
{
t.foo();
}
this does not compile complaining the foo() is not a member of T. I can add a constraint for T to derive from one of the classes:
void bar<T>(T t) where T : A
but how can I have it for both?
Simply put you can't. There are a couple of approaches to work around this problem though.
The most common is to use an interface. Say IMyType
interface IMyType { void foo(); }
class A : IMyType ...
class B : IMyType ...
void bar<T>(T t) where T : IMyType {
t.Foo();
}
This is a bit heavy weight though is it requires a metadata change for a solution. A cheaper approach is to provide a lambda expression which calls the appropriate function.
void bar<T>(T t, Action doFoo) {
...
doFoo();
}
var v1 = new A();
var v2 = new B();
bar(v1, () => v1.Foo());
bar(v2, () => v2.Foo());
You should define an interface:
interface IFoo
{
void foo();
}
class A : IFoo
{
public void foo() {}
}
class B : IFoo
{
public void foo() {}
}
And your generic method:
void bar<T>(T t) where T:IFoo
{
t.foo();
}
Define an interface that contains the foo method, and have classes A & B implement that interface. Then define an interface constraint on your generic type.
You can't do that unless you:
Derive from a base class
Derive from an interface
I prefer the interface because it doesn't force you to share behavior:
public interface IHasFoo
{
void foo();
}
public class B : IHasFoo // you don't need to explicitly subclass object
{
public void foo()
{
}
}
public class A : IHasFoo // you don't need to explicitly subclass object
{
public void foo()
{
}
}
void bar<T>(T t) where T : IHasFoo
{
t.foo(); // works
}
This is possible in .NET 4.0 using dynamic.
void bar(dynamic t)
{
t.foo();
}
Why are you making this generic? Just overload the method.
void bar(A a) { a.Foo(); }
void bar(B b) { b.Foo(); }
Generics are there so that you can make potentially infinite bar() methods.