forked from dlang/dlang.org
-
Notifications
You must be signed in to change notification settings - Fork 0
/
interface.dd
335 lines (261 loc) · 7.5 KB
/
interface.dd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
Ddoc
$(SPEC_S Interfaces,
$(GRAMMAR
$(GNAME InterfaceDeclaration):
$(D interface) $(I Identifier) $(D ;)
$(D interface) $(I Identifier) $(GLINK BaseInterfaceList)$(OPT) $(GLINK2 struct, AggregateBody)
$(GLINK2 template, InterfaceTemplateDeclaration)
$(GNAME BaseInterfaceList):
$(D :) $(GLINK2 class, Interfaces)
)
$(P Interfaces describe a list of functions that a class that inherits
from the interface must implement.
A class that implements an interface can be converted to a reference
to that interface.)
$(P Some operating system objects, like COM/OLE/ActiveX for Win32,
have specialized interfaces. D interfaces that are compatible with
COM/OLE/ActiveX are called $(RELATIVE_LINK2 com-interfaces, $(I COM Interfaces)).
)
$(P $(RELATIVE_LINK2 cpp-interfaces, $(I C++ Interfaces)) are another
form of interfaces, meant to be binary compatible with C++.
)
$(P Interfaces cannot derive from classes; only from other interfaces.
Classes cannot derive from an interface multiple times.
)
------
interface D
{
void foo();
}
class A : D, D // error, duplicate interface
{
}
------
An instance of an interface cannot be created.
------
interface D
{
void foo();
}
...
D d = new D(); // error, cannot create instance of interface
------
$(P Virtual interface member functions do not have implementations.
Interfaces are expected to implement static or final functions.
)
------
interface D
{
void bar() { } // error, implementation not allowed
static void foo() { } // ok
final void abc() { } // ok
}
------
$(P Classes that inherit from an interface may not override final or
static interface member functions.)
------
interface D
{
void bar();
static void foo() { }
final void abc() { }
}
class C : D
{
void bar() { } // ok
void foo() { } // error, cannot override static D.foo()
void abc() { } // error, cannot override final D.abc()
}
------
$(P All interface functions must be defined in a class that inherits
from that interface:
)
------
interface D
{
void foo();
}
class A : D
{
void foo() { } // ok, provides implementation
}
class B : D
{
int foo() { } // error, no void foo() implementation
}
------
Interfaces can be inherited and functions overridden:
------
interface D
{
int foo();
}
class A : D
{
int foo() { return 1; }
}
class B : A
{
int foo() { return 2; }
}
...
B b = new B();
b.foo(); // returns 2
D d = cast(D) b; // ok since B inherits A's D implementation
d.foo(); // returns 2;
------
$(P Interfaces can be reimplemented in derived classes:)
------
interface D
{
int foo();
}
class A : D
{
int foo() { return 1; }
}
class B : A, D
{
int foo() { return 2; }
}
...
B b = new B();
b.foo(); // returns 2
D d = cast(D) b;
d.foo(); // returns 2
A a = cast(A) b;
D d2 = cast(D) a;
d2.foo(); // returns 2, even though it is A's D, not B's D
------
$(P A reimplemented interface must implement all the interface
functions, it does not inherit them from a super class:
)
------
interface D
{
int foo();
}
class A : D
{
int foo() { return 1; }
}
class B : A, D
{
} // error, no foo() for interface D
------
$(SECTION2 $(LEGACY_LNAME2 InterfaceContracts, interface-contracts, Interfaces with Contracts),
$(P Interface member functions can have contracts even though there
is no body for the function. The contracts are inherited by any
class member function that implements that interface member function.
)
---
interface I
{
int foo(int i)
in { assert(i > 7); }
out (result) { assert(result & 1); }
void bar();
}
---
)
$(SECTION2 $(LEGACY_LNAME2 ConstInterface, const-interface, Const and Immutable Interfaces),
$(P If an interface has $(CODE const) or $(CODE immutable) storage
class, then all members of the interface are
$(CODE const) or $(CODE immutable).
This storage class is not inherited.
)
)
$(SECTION2 $(LEGACY_LNAME2 COM-Interfaces, com-interfaces, COM Interfaces),
$(P A variant on interfaces is the COM interface. A COM interface is
designed to map directly onto a Windows COM object. Any COM object
can be represented by a COM interface, and any D object with
a COM interface can be used by external COM clients.
)
$(P A COM interface is defined as one that derives from the interface
$(D core.stdc.win)$(SHY)$(D dows.com.IUnknown). A COM interface differs from
a regular D interface in that:
)
$(UL
$(LI It derives from the interface $(D core.stdc.windows.com.IUnknown).)
$(LI It cannot be the argument of a $(I DeleteExpression).)
$(LI References cannot be upcast to the enclosing class object, nor
can they be downcast to a derived interface. To accomplish this,
an appropriate $(D QueryInterface()) would have to be implemented
for that interface in standard COM fashion.)
$(LI Classes derived from COM interfaces are COM classes.)
$(LI The default linkage for member functions of COM classes
is $(D extern(System)).
Note that if you want to implement or override any base-class methods of
D interfaces or classes (ones which do not inherit from $(D IUnknown)),
you have to explicitly mark them as having the $(D extern(D)) linkage:
---
import core.sys.windows.windows;
import core.stdc.windows.com;
interface IText
{
void write();
}
abstract class Printer : IText
{
void print() { }
}
class C : Printer, IUnknown
{
// Implements the IText $(D write) class method.
extern(D) void write() { }
// Overrides the Printer $(D print) class method.
extern(D) override void print() { }
// Overrides the Object base class $(D toString) method.
extern(D) override string toString() { return "Class C"; }
// Methods of class implementing the IUnknown interface have
// the extern(System) calling convention by default.
HRESULT QueryInterface(const(IID)*, void**);
uint AddRef();
uint Release();
}
---
The same applies to other $(D Object) methods such as $(D opCmp), $(D toHash), etc.
)
$(LI The first member of the $(D vtbl[]) is not the pointer
to the InterfaceInfo, but the first virtual function pointer.)
)
$(P For more information, see
$(LINK2 http://lunesu.com/uploads/ModernCOMProgramminginD.pdf, Modern COM Programming in D)
)
)
$(SECTION2 $(LEGACY_LNAME2 CPP-Interfaces, cpp-interfaces, C++ Interfaces),
$(P C++ interfaces are interfaces declared with C++ linkage:
)
---
extern (C++) interface Ifoo
{
void foo();
void bar();
}
---
$(P which is meant to correspond with the following C++ declaration:)
$(CPPLISTING
class Ifoo
{
virtual void foo();
virtual void bar();
};
)
$(P Any interface that derives from a C++ interface is also
a C++ interface.
A C++ interface differs from a D interface in that:
)
$(UL
$(LI It cannot be the argument of a $(I DeleteExpression).)
$(LI References cannot be upcast to the enclosing class object, nor
can they be downcast to a derived interface.)
$(LI The C++ calling convention is the default convention
for its member functions, rather than the D calling convention.)
$(LI The first member of the $(D vtbl[]) is not the pointer
to the $(D Interface), but the first virtual function pointer.)
)
)
)
Macros:
TITLE=Interfaces
WIKI=Interface