In COM, software components communicate by means of interfaces. Interfaces are implemented by server components and used by client components. COM objects consist of one or more interfaces, usually two or more.
Interfaces consist of a number of methods. Methods are functions that client software can call to access the server's features. Note that these methods are not the same as Dylan methods: where necessary, we call them COM methods to distinguish them from Dylan methods.
Clients obtain pointers to interfaces in order to call the COM methods they contain. They do so by communicating with a COM support library. Microsoft Windows 95 and Windows NT both contain such a library. The Functional Developer OLE/COM libraries make calls to this library as necessary.
COM defines a number of standard interfaces. The fundamental COM interface, which every COM object must support, is called IUnknown. (By convention, interface names always start with an 'I'.)
When a client instantiates a COM object, it typically gets back a pointer to IUnknown. After this, the client can attempt to get pointers to the other interfaces the object provides. For example, a word processor might implement an interface called IContents that provides services for creating and manipulating a table of contents, and an interface called IPrint that provides printing services.
IUnknown provides three methods: QueryInterface, AddRef, and Release. QueryInterface is used to get pointers to other interfaces supported by the COM object, while AddRef and Release increment and decrement a reference count to enable the server to know when all clients have finished using the interface.
All COM interfaces inherit from the IUnknown interface. This does not mean they inherit the implementation of the IUnknown methods, just that they inherit the interface itself, meaning that all COM interfaces are required to implement QueryInterface, AddRef and Release themselves. Thus COM has interface inheritance but not implementation inheritance.
In the C/C++ world, COM developers would therefore have to include code for the three IUnknown methods in every interface they write, and also to repeat the code of any COM methods their interface might inherit from other interfaces.
Functional Developer represents interfaces using Dylan classes, and represents their methods using Dylan generic function methods specialized on those interface classes. All the Functional Developer OLE/COM API libraries export the Dylan class <IUnknown>, which represents the basic COM interface IUnknown.
Because COM specifies that the IUnknown interface must support QueryInterface, AddRef, and Release, the Functional Developer OLE/COM API libraries define Dylan methods for these operations on <IUnknown>.
Every COM interface in Dylan must be a subclass of <IUnknown>. This means that, through the standard Dylan generic function dispatch mechanisms, every COM interface you define will inherit the implementations of QueryInterface, AddRef, and Release that are defined on the Dylan class <IUnknown>. Thus COM's interface-inheritance-only limitation is overcome naturally.
If you prefer, you can override the inherited methods in the normal Dylan fashion, by adding Dylan methods specializing on your subclass of <IUnknown>.