Inheritance/Multiple: Difference between revisions

Expanded D entry to cover the multiple ways to do multiple inheritance.
(Expanded D entry to cover the multiple ways to do multiple inheritance.)
Line 119:
=={{header|D}}==
 
While D doesn'tdoes allownot have multiple base class inheritance, but you can inherit afterfrom multiple interfaces.
 
<lang d>interface Camera {
Line 133:
// MobilePhone, and CameraPhone
}</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}}==
Anonymous user