$(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) ) )