Inheritance/Multiple: Difference between revisions

Content added Content deleted
(Expanded D entry to cover the multiple ways to do multiple inheritance.)
Line 119: Line 119:
=={{header|D}}==
=={{header|D}}==


D doesn't allow multiple inheritance, but you can inherit after multiple interfaces.
While D does not have multiple base class inheritance, you can inherit from multiple interfaces.


<lang d>interface Camera {
<lang d>interface Camera {
Line 133: Line 133:
// MobilePhone, and CameraPhone
// MobilePhone, and CameraPhone
}</lang>
}</lang>

D also supports template mixins and alias this (multiple alias this are planned)
D also supports the [[non-virtual interface]] pattern, where an interface may have non-virtual methods with defined implementations.
that allows various forms of static composition.

<lang d>interface Camera {
// A virtual function.
Image takePhoto();

// A non-virtual function.
final Image[] takeSeveralPhotos(int count) {
auto result = new Image[count];
foreach (ref img; result) {
img = takePhoto();
}
}
}</lang>

In addition, D's alias this feature allows one to create a type that, while it does not technically derive from two different classes, behaves as if it was.

<lang d>class A {
string foo() {
return "I am an A.";
}
}
class B {
string foo() {
return "I am a B.";
}
}

class C : A {
string className = "C";
override string foo() {
return "I am a "~className~", and thus an A.";
}
@property
BWrapper asB() {
return new BWrapper();
}
alias asB this;
class BWrapper : B {
override string foo() {
return "I am a "~className~", disguised as a B.";
}
}
}

unittest {
import std.stdio : writeln;
auto c = new C();
A a = c;
B b = c;
writeln(a.foo());
writeln(b.foo());
}</lang>

You can currently only have a single alias this, but multiple alias this is planned. Nested alias this works today, but is somewhat finicky.

Lastly, D has template and string mixins. These can be used for static polymorphism, where a piece of code is written once and has a single definition, but is used in multiple places. It does not enable any sort of dynamic polymorphism that is not covered above.

<lang d>template registerable() {
void register() { /* implementation */ }
}

string makeFunction(string s) {
return `string `~s~`(){ return "`~s~`";}`;
}

class Foo {
mixin registerable!();
mixin(makeFunction("myFunction"));
}

unittest {
import std.stdio : writeln;
Foo foo = new Foo;
foo.register();
writeln(foo.myFunction());
}</lang>

Using D's [[Compile-time calculation|CTFE]] and [[reflection]] capabilities, string mixins can copy the interface of other types , and thus be used for proxies and mocks.


=={{header|Delphi}}==
=={{header|Delphi}}==