Sunday, July 24, 2005
Multiple Inheritance
"Modern" languages like Java and C# don't have multiple inheritance. The funny thing is that most programmers don't like multiple inheritance not because of the technical difficulties that it brings into the internal object model, or because some of those difficulties tend to emerge at the language level (e.g. the difference between regular multiple inheritance and virtual multiple inheritance in C++). They don't like it because they have been told so in the huge Java propaganda, just like some have been convinced that all implementation inheritance is/was bad during the huge COM propaganda.
Anyway, in these days I was playing a little with Context Attributes under .NET. Context Attributes are very powerful and possibly the only creative contribution of the .NET platform. However, to apply a Context Attribute to a class, that class must derive from ContextBoundObject. Some of you may be more familiar with ServicedComponent, that is derived from ContextBoundObject and provides the base class for all classes using COM+ services. ContextBoundObject is an abstract class, not an interface.
Unfortunately, I wanted to apply some Context Attributes to a class derived from Form. Now, this is one of those catch-22 situations. Given the .NET library as it is, I just can't. Using wrappers and adapters is not the answer: the whole point of Context Attributes is to write less code using AOP-like features. If you have to write wrappers, you can just as well avoid the attributes altogether.
Sure, the library is not perfect: Form and ContextBoundObject have a common ancestor (MarshalByRefObject). Moreover, it seems like ContextBoundObject is not adding any intelligence to MarshalByRefObject, except a [Serializable()] attribute and possibly playing a marker class role. Most likely, they could have done that using a [ContextBound] pseudo-attribute implying a [Serializable], so that any class derived from MarshalByRefObject could have been activated in a context if desired. Too late, I guess.
And here we have it: when we put strong limits into the language, we need perfect libraries. We need libraries where all classes fit nicely together. This is wishful thinking when a single large library is concerned, and ridiculous when you find yourself integrating code from different libraries or frameworks.
Give me Multiple Inheritance back :-).
Meanwhile, the weather is nice out here, and it's time to get into the sun :-).
Anyway, in these days I was playing a little with Context Attributes under .NET. Context Attributes are very powerful and possibly the only creative contribution of the .NET platform. However, to apply a Context Attribute to a class, that class must derive from ContextBoundObject. Some of you may be more familiar with ServicedComponent, that is derived from ContextBoundObject and provides the base class for all classes using COM+ services. ContextBoundObject is an abstract class, not an interface.
Unfortunately, I wanted to apply some Context Attributes to a class derived from Form. Now, this is one of those catch-22 situations. Given the .NET library as it is, I just can't. Using wrappers and adapters is not the answer: the whole point of Context Attributes is to write less code using AOP-like features. If you have to write wrappers, you can just as well avoid the attributes altogether.
Sure, the library is not perfect: Form and ContextBoundObject have a common ancestor (MarshalByRefObject). Moreover, it seems like ContextBoundObject is not adding any intelligence to MarshalByRefObject, except a [Serializable()] attribute and possibly playing a marker class role. Most likely, they could have done that using a [ContextBound] pseudo-attribute implying a [Serializable], so that any class derived from MarshalByRefObject could have been activated in a context if desired. Too late, I guess.
And here we have it: when we put strong limits into the language, we need perfect libraries. We need libraries where all classes fit nicely together. This is wishful thinking when a single large library is concerned, and ridiculous when you find yourself integrating code from different libraries or frameworks.
Give me Multiple Inheritance back :-).
Meanwhile, the weather is nice out here, and it's time to get into the sun :-).
Comments:
<< Home
Volevo farti i complimenti per il Blog: offre davvero un sacco di spunti di riflessione e link ad articoli interessanti.
come promesso ecco qua il link al mio (molto modesto) blog
http://spaces.msn.com/members/vigj/
come promesso ecco qua il link al mio (molto modesto) blog
http://spaces.msn.com/members/vigj/
Devo dire di non aver mai capito questo rifiuto ad avere in un linguaggio l'ereditarietà multipla. Se qualcuno pensa che sia difficile, può semplicemente non usarla. Perchè addirittura eliminarla? Restringere poi anche l'ereditarietà singola alla sola equivalente di quella public C++ mi sembra poi accessivo, anche se immagino che ci siano ragioni di design (posso provare ad immaginarne una, anche se non so quanto sia esatta). Io trovo spesso utilissimo poter derivare pubblicamente da una classe e privatamente da una/tante altre, soprattutto quando i meccanismi di riutilizzo forniti da diverse librerie utilizzate si basano tutti sull'ereditarietà!!!
"anonymous": certo ora ho capito il giusto :-) riserbo nel darmi il link.
Certo potrei usarlo come dimostrazione che passare mesi nei cantieri sperduti a seguire le installazioni fa male :-))) e che qualunque cosa si possa fare per diminuire i tempi di permanenza va perseguita a fondo :-).
PS
Non sapevo fossi un fan di tekkaman :-).
Certo potrei usarlo come dimostrazione che passare mesi nei cantieri sperduti a seguire le installazioni fa male :-))) e che qualunque cosa si possa fare per diminuire i tempi di permanenza va perseguita a fondo :-).
PS
Non sapevo fossi un fan di tekkaman :-).
Fulvio: il problema tecnico maggiore sta ovviamente nel conciliare l'idea di un linguaggio con gerarchia unica (e fino a che non ci si mettono i generic e' fondamentale, per qualcuno lo e' anche dopo) con l'ereditarieta' multipla, che a quel punto di default dovrebbe essere virtuale, e le complicazioni che questa porta (in C++, dati virtuali con performance hit nell'accesso, chiamata al costruttore della classe base virtuale da parte della classe piu' derivata).
Da qui a buttarla via ce ne passa, ma al solito non e' facile costruire un linguaggio potente senza esporre parte della complessita' a chi lo usa...
Post a Comment
Da qui a buttarla via ce ne passa, ma al solito non e' facile costruire un linguaggio potente senza esporre parte della complessita' a chi lo usa...
<< Home





