$(DDOC $(DDOC_BLANKLINE )
$(DDOC_BLANKLINE )
$(SPEC_S Interfaces,
$(DDOC_BLANKLINE )
$(HEADERNAV_TOC $(HEADERNAV_SUBITEMS declarations, Interface Declarations,
$(HEADERNAV_ITEM method-bodies, Interface Method Bodies)
$(HEADERNAV_ITEM implementing-interfaces, Implementing Interfaces)
$(HEADERNAV_ITEM interface-contracts, Interface Method Contracts)
$(HEADERNAV_ITEM const-interface, Const and Immutable Interfaces)
)
$(HEADERNAV_ITEM com-interfaces, COM Interfaces)
$(HEADERNAV_ITEM cpp-interfaces, C++ Interfaces)
)
$(DDOC_BLANKLINE )
$(LNAME2 declarations, Interface Declarations)
$(DDOC_BLANKLINE )
$(P An $(I Interface) describes a list of functions that a class which inherits
from the interface must implement.)
$(DDOC_BLANKLINE )
$(GRAMMAR $(GNAME InterfaceDeclaration):
$(D interface) $(GLINK_LEX Identifier) $(D ;)
$(D interface) $(GLINK_LEX Identifier) $(GLINK BaseInterfaceList)$(OPT ) $(GLINK2 struct, AggregateBody)
$(GLINK2 template, InterfaceTemplateDeclaration)
$(DDOC_BLANKLINE )
$(GNAME BaseInterfaceList):
$(D :) $(GLINK2 class, Interfaces)
)
$(DDOC_BLANKLINE )
$(IMPLEMENTATION_DEFINED $(P Specialized interfaces may be supported:)
$(DDOC_BLANKLINE )
$(OL $(LI $(RELATIVE_LINK2 com-interfaces, $(I COM Interfaces))
are binary compatible with COM/OLE/ActiveX objects for Windows.
)
$(DDOC_BLANKLINE )
$(LI $(RELATIVE_LINK2 cpp-interfaces, $(I C++ Interfaces))
are binary compatible with C++ abstract classes.
)
$(DDOC_BLANKLINE )
$(LI $(LINK2 objc_interface.html#protocols, Objective-C Interfaces)
are binary compatible with Objective-C protocols.
)
)
)
$(DDOC_BLANKLINE )
$(DDOC_BLANKLINE )
$(P A class that implements an interface can be implicitly converted to a reference
to that interface.)
$(DDOC_BLANKLINE )
$(P Interfaces cannot derive from classes; only from other interfaces.
Classes cannot derive from an interface multiple times.
)
$(DDOC_BLANKLINE )
$(D_CODE $(D_KEYWORD interface) I
{
$(D_KEYWORD void) foo();
}
$(D_KEYWORD class) A : I, I $(D_COMMENT // error, duplicate interface
){
}
)
$(DDOC_BLANKLINE )
$(P An instance of an interface cannot be created.)
$(DDOC_BLANKLINE )
$(D_CODE $(D_KEYWORD interface) I
{
$(D_KEYWORD void) foo();
}
...
I iface = $(D_KEYWORD new) I(); $(D_COMMENT // error, cannot create instance of interface
))
$(DDOC_BLANKLINE )
$(LNAME2 method-bodies, Interface Method Bodies)
$(DDOC_BLANKLINE )
$(P Virtual interface member functions do not have implementations.
Interfaces are expected to implement static or final functions.
)
$(DDOC_BLANKLINE )
$(D_CODE $(D_KEYWORD interface) I
{
$(D_KEYWORD void) bar() { } $(D_COMMENT // error, implementation not allowed
) $(D_KEYWORD static) $(D_KEYWORD void) foo() { } $(D_COMMENT // ok
) $(D_KEYWORD final) $(D_KEYWORD void) abc() { } $(D_COMMENT // ok
)}
)
$(DDOC_BLANKLINE )
$(P Interfaces can have function templates in the members.
All instantiated functions are implicitly final
.
)
$(DDOC_BLANKLINE )
$(D_CODE $(D_KEYWORD interface) I
{
$(D_KEYWORD void) foo(T)() { } $(D_COMMENT // ok, it's implicitly final
)}
)
$(DDOC_BLANKLINE )
$(P Classes that inherit from an interface may not override final or
static interface member functions.)
$(DDOC_BLANKLINE )
$(D_CODE $(D_KEYWORD interface) I
{
$(D_KEYWORD void) bar();
$(D_KEYWORD static) $(D_KEYWORD void) foo() { }
$(D_KEYWORD final) $(D_KEYWORD void) abc() { }
}
$(D_KEYWORD class) C : I
{
$(D_KEYWORD void) bar() { } $(D_COMMENT // ok
) $(D_KEYWORD void) foo() { } $(D_COMMENT // error, cannot override static I.foo$(LPAREN)$(RPAREN )
) $(D_KEYWORD void) abc() { } $(D_COMMENT // error, cannot override final I.abc$(LPAREN)$(RPAREN )
)}
)
$(DDOC_BLANKLINE )
$(LNAME2 implementing-interfaces, Implementing Interfaces)
$(DDOC_BLANKLINE )
$(P All virtual interface functions must be defined in a class that inherits
from that interface:
)
$(D_CODE $(D_KEYWORD interface) I
{
$(D_KEYWORD void) foo();
}
$(D_KEYWORD class) A : I
{
$(D_KEYWORD void) foo() { } $(D_COMMENT // ok, provides implementation
)}
$(D_KEYWORD class) B : I
{
$(D_KEYWORD int) foo() { } $(D_COMMENT // error, no `void foo$(LPAREN)$(RPAREN )` implementation
)}
)
$(DDOC_BLANKLINE )
$(P Interfaces can be inherited from a base class, and interface functions overridden:)
$(DDOC_BLANKLINE )
$(SPEC_RUNNABLE_EXAMPLE_RUN $(D_CODE $(D_KEYWORD interface) I
{
$(D_KEYWORD int) foo();
}
$(D_KEYWORD class) A : I
{
$(D_KEYWORD int) foo() { $(D_KEYWORD return) 1; }
}
$(D_KEYWORD class) B : A
{
$(D_KEYWORD override) $(D_KEYWORD int) foo() { $(D_KEYWORD return) 2; }
}
B b = $(D_KEYWORD new) B();
$(D_KEYWORD assert)(b.foo() == 2);
I i = b; $(D_COMMENT // ok since B inherits A's I implementation
)$(D_KEYWORD assert)(i.foo() == 2);
)
)
$(DDOC_BLANKLINE )
$(LNAME2 reimplementing-interfaces, Reimplementing Interfaces)
$(DDOC_BLANKLINE )
$(P Interfaces can be reimplemented in derived classes:)
$(DDOC_BLANKLINE )
$(SPEC_RUNNABLE_EXAMPLE_RUN $(D_CODE $(D_KEYWORD interface) I
{
$(D_KEYWORD int) foo();
}
$(D_KEYWORD class) A : I
{
$(D_KEYWORD int) foo() { $(D_KEYWORD return) 1; }
}
$(D_KEYWORD class) B : A, I
{
$(D_KEYWORD override) $(D_KEYWORD int) foo() { $(D_KEYWORD return) 2; }
}
B b = $(D_KEYWORD new) B();
$(D_KEYWORD assert)(b.foo() == 2);
I i = b;
$(D_KEYWORD assert)(i.foo() == 2);
A a = b;
I i2 = a;
$(D_KEYWORD assert)(i2.foo() == 2); $(D_COMMENT // i2 has A's virtual pointer for foo which points to B.foo
))
)
$(DDOC_BLANKLINE )
$(P A reimplemented interface must implement all the interface
functions, it does not inherit them from a super class:
)
$(DDOC_BLANKLINE )
$(D_CODE $(D_KEYWORD interface) I
{
$(D_KEYWORD int) foo();
}
$(D_KEYWORD class) A : I
{
$(D_KEYWORD int) foo() { $(D_KEYWORD return) 1; }
}
$(D_KEYWORD class) B : A, I
{
} $(D_COMMENT // error, no foo$(LPAREN)$(RPAREN ) for interface I
))
$(DDOC_BLANKLINE )
$(SECTION3 $(LEGACY_LNAME2 InterfaceContracts, interface-contracts, Interface Method Contracts),
$(DDOC_BLANKLINE )
$(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.
)
$(DDOC_BLANKLINE )
$(D_CODE $(D_KEYWORD interface) I
{
$(D_KEYWORD int) foo($(D_KEYWORD int) i)
$(D_KEYWORD in) { $(D_KEYWORD assert)(i > 7); }
$(D_KEYWORD out) (result) { $(D_KEYWORD assert)(result & 1); }
$(D_KEYWORD void) bar();
}
)
)
$(DDOC_BLANKLINE )
$(SECTION3 $(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.
)
)
$(DDOC_BLANKLINE )
$(DDOC_BLANKLINE )
$(SECTION2 $(LEGACY_LNAME2 COM-Interfaces, com-interfaces, COM Interfaces),
$(DDOC_BLANKLINE )
$(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.
)
$(DDOC_BLANKLINE )
$(P A COM interface is defined as one that derives from the interface
$(D core.sys.win)$(SHY )$(D dows.com.IUnknown). A COM interface differs from
a regular D interface in that:
)
$(DDOC_BLANKLINE )
$(UL $(LI It derives from the interface $(D core.sys.windows.com.IUnknown).)
$(LI It cannot be the argument to $(REF1 destroy, object).)
$(LI References cannot be upcast to the enclosing class object, nor
can they be downcast to a derived interface.
Implement $(D QueryInterface())
for that interface in standard COM fashion to convert to another COM interface.)
$(LI Classes derived from COM interfaces are COM classes.)
$(LI The default linkage for member functions of COM classes
is $(D extern(System)).
$(DDOC_BLANKLINE )
$(NOTE To implement or override any base-class methods of
D interfaces or classes (ones which do not inherit from $(D IUnknown)),
explicitly mark them as having the $(D extern(D)) linkage.)
$(DDOC_BLANKLINE )
$(D_CODE $(D_KEYWORD import) core.sys.windows.windows;
$(D_KEYWORD import) core.sys.windows.com;
$(D_KEYWORD interface) IText
{
$(D_KEYWORD void) write();
}
$(D_KEYWORD abstract) $(D_KEYWORD class) Printer : IText
{
$(D_KEYWORD void) print() { }
}
$(D_KEYWORD class) C : Printer, IUnknown
{
$(D_COMMENT // Implements the IText `write` class method.
) $(D_KEYWORD extern)(D) $(D_KEYWORD void) write() { }
$(D_COMMENT // Overrides the Printer `print` class method.
) $(D_KEYWORD extern)(D) $(D_KEYWORD override) $(D_KEYWORD void) print() { }
$(D_COMMENT // Overrides the Object base class `toString` method.
) $(D_KEYWORD extern)(D) $(D_KEYWORD override) string toString() { $(D_KEYWORD return) $(D_STRING "Class C"); }
$(D_COMMENT // Methods of class implementing the IUnknown interface have
) $(D_COMMENT // the extern$(LPAREN)System$(RPAREN ) calling convention by default.
) HRESULT QueryInterface($(D_KEYWORD const)(IID)*, $(D_KEYWORD void)**);
$(D_KEYWORD uint) AddRef();
$(D_KEYWORD uint) Release();
}
)
$(DDOC_BLANKLINE )
$(P The same applies to other $(D Object) methods such as $(D opCmp), $(D toHash), etc.)
$(DDOC_BLANKLINE )
)
$(LI The first member of the COM $(D vtbl[]) is not the pointer
to the InterfaceInfo, but the first virtual function pointer.)
)
$(DDOC_BLANKLINE )
$(P See also
$(LINK2 http://www.lunesu.com/uploads/ModernCOMProgramminginD.pdf, Modern COM Programming in D)
)
$(DDOC_BLANKLINE )
)
$(DDOC_BLANKLINE )
$(SECTION2 $(LEGACY_LNAME2 CPP-Interfaces, cpp-interfaces, C++ Interfaces),
$(DDOC_BLANKLINE )
$(P C++ interfaces are interfaces declared with C++ linkage:
)
$(DDOC_BLANKLINE )
$(D_CODE $(D_KEYWORD extern) (C++) $(D_KEYWORD interface) Ifoo
{
$(D_KEYWORD void) foo();
$(D_KEYWORD void) bar();
}
)
$(DDOC_BLANKLINE )
which is meant to correspond with the following C++ declaration:
$(DDOC_BLANKLINE )
$(CPPLISTING class Ifoo
{
virtual void foo();
virtual void bar();
};
)
$(DDOC_BLANKLINE )
$(P Any interface that derives from a C++ interface is also
a C++ interface.
A C++ interface differs from a D interface in that:
)
$(DDOC_BLANKLINE )
$(UL $(LI It cannot be the argument to $(REF1 destroy, object).)
$(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.)
)
)
$(DDOC_BLANKLINE )
$(DDOC_BLANKLINE )
$(SPEC_SUBNAV_PREV_NEXT class, Classes, enum, Enums)
)
)