Virtual inheritance
Encyclopedia : V : VI : VIR : Virtual inheritance
Virtual inheritance is a form of inheritance in object-oriented programming languages.
It allows a parent to control code elements implemented in the children which inherit from it.
By using Virtual Inheritance any polymorphic functionality, within the parent, is moved into the children (functional dispersion), and then controlled (by the parent) along the lines of inheritance between parent and child (ancestor/descendent).
This is a 'language independent' definition not constrained by syntax mechanisms in specific computer languages like Eiffel, C++, C#, and Java. The term General Virtual Inheritance (GVI) should be used to qualify the language independent meaning relative to any alternate language specific meaning.
Unless qualified otherwise Virtual Inheritance (GVI) refers to the language independent meaning. Resolution Inheritance (RI) is the language independent meaning referring to state space collision resolution in the context of Multiple Implementation Inheritance (MII) of state.
Also see the Semantics section which addresses the conceptual scope of Virtual Inheritance syntax mechanisms.
- 1 General
- 1.0.1 Specification Vs. Implementation
- 1.0.2 Abstract Method
- 1.0.3 Interfaces
- 1.0.4 Default Virtual Method Implementation
- 1.0.5 Type Polymorphism
- 1.0.6 Control Mechanism Vs. Polymorphic Mechanism
- 2 Languages
- 2.1 C++
- 2.1.1 C++ Method Override Ambiguity (MOA)
- 2.1.2 C++ Inherited Class Ambiguity (ICA)
- 2.1.3 C++ Resolution Mechanism for Diamond Problem
- 2.1.4 Stateful Diamond Point (SDP) Pattern
- 2.1.5 Coexistence of Virtual and Resolution Inheritance in C++
- 2.1.6 Summary of Virtual and Resolution Inheritance in Object-oriented Languages
- 2.2 C#
- 2.2.1 C# Method Override Ambiguity (MOA)
- 2.2.2 Simple Virtual Inheritance (SVI) via Interface Inheritance
- 2.2.3 Use Context of Virtual Code Elements
- 2.2.4 Stateful Diamond Point (SDP) Pattern in C#
- 2.2.5 Coexistence of Virtual and Interface Inheritance in C#
- 2.2.6 Summary of Virtual and Interface inheritance in Object Oriented Languages
- 2.3 Java
- 3 Semantics
- 4 See also
General
Virtual Inheritance (VI) is a fundamental feature of most object-oriented languages. Virtual Inheritance allows a parent (the base class) to use code elements in the child (the derived class). Methods, variables and other code elements are said to be implemented in the child and controlled by the parent.
Virtual inheritance is used by a parent to specify code elements that must exist (be implemented) in the child (See Function Vs. Functionality section).
Centric to virtual inheritance is the concept of a virtual control mechanism that allows the parent to control a virtual code element in the child. The virtual control mechanism is a code element specification in the parent class. Using this mechanism the parent can then assign properties, load events or call methods even though they do not yet exist (at compile time).
A common use of Virtual Inheritance is when the parent specifies a method that must exist in the child. In this case the child will do the work (perform some function) when called upon by the parent (i.e. controlled). Parents may also specify other code elements, such as primitive data types, to exist in the child which can then be assigned and used (i.e. controlled) by the parent.
From a software design point of view this functional delegation allows polymorphic functionality in the codebase to migrate (gravitate) to child classes where it can be controlled via the lines of inheritance from the parents. The result is a functional dispersion of polymorphic code to the children.
Specification Vs. Implementation
Virtual Inheritance (GVI) is a form of class inheritance and is generally contrasted with Implementation Inheritance (object-oriented programming).
In Virtual Inheritance an inherited child inherits only the specification of the code elements defined in the parent. Thus the parent can use the functionality defined in the child. As such the child is forced to implement the functionality specified by the code elements defined in the specification. This 'forcing' leads to polymorphic behavior within the operational structure (inheritance graph) of the class hierarchy created by class inheritance.
Implementation Inheritance, on the other hand, shares an implementation of functionality located in the parent. This leads to the ability to move common code in the children to parents. The common code can then be shared by all children inheriting from that parent.
Abstract Method
An abstract method is one defined by the parent with no default implementation. Abstract methods are a definitive expression of Virtual Inheritance as they embody the forced implementation in the child by the specification in the parent (a primary requirement for delegation of function via inheritance).
Abstract methods are signature only specification which leave the implementation to the child. The signature specification (of the abstract method) is the mechanism that allows the parent to call the child without knowing the details of the child's implementation of the parent's specification.
Note that abstract methods are just one of many kinds of code elements that can be specified by a parent. Assignable code elements such as events or primitive data types in interfaces distinguish Virtual Inheritance (GVI) from Virtual Functions (which are conceptual subset of GVI).
Interfaces
Virtual Inheritance is the core impetus for Interfaces. With Interfaces a child inherits only the specification and not the implementation of a set of code elements. Thus Interfaces force a child to implement code elements defined in the interface.
Note that Interfaces (language independent meaning) are more than just method specifications as they can include all types of code elements (state space code elements as well as operational elements). This is in keeping with the 'general' and 'inclusive' nature of General Virtual Inheritance (GVI).
Interfaces provide a formal specification mechanism that allows a virtual code element within the interface to be controlled by the parent.
Default Virtual Method Implementation
In some languages a parent can optionally provide a default implementation of a virtual method. The child, in turn, can provide its implementation of the virtual method. Default virtual methods are a form of implementation inheritance where the parent implemenation is shared (usable by) the children.
The parent and child implementations can coexist. In a polymorphic design some children may decide to implement their own version of the virtual method and use only that version. Other children may elect not to provide an implementation and use the default version provided by the parent.
Default versions of other code elements (beside methods) demonstrate the complementary nature of between Implementation Inheritance (II) and Virtual Inheritance (GVI)
Note the distinction between a virtual method (which can sometimes provide a default implementation) and an abstract method (which can never provide a default implementation). This, however, does not detract from the semantic meaning of Virtual Inheritance (GVI) which is the ability of the parent to control a child implementation (child code element).
Note that in cases where a default implementation is provided by the parent the current casting context will determine which implementation (child or parent implementation) is used.
Type Polymorphism
In Type Polymorphism the child may use both its implementation (defined in the child code body) and the parent's implementation (of the virtual method) in implementing the child's version of the target functionality.
The 'abstract method' and 'forced implementation' are what distinguish Virtual Inheritance (GVI) from the more general 'Type Polymorphism'.
Thus Type Polymorphism (TP) is a conceptual superset of Virtual Inheritance (GVI) in that TP functionality can be composed of child AND parent implementations while GVI functionality is (by definition) the child implementation alone.
Control Mechanism Vs. Polymorphic Mechanism
Virtual Inheritance (GVI) has both a control and polymorphic aspect to its conceptual semantics.
The virtual control aspect is the ability of a parent to control a 'virtual code element' that is ultimately implemented in the child. The word 'control' means the code element may be callable (an abstract method), assignable (a primitive data type) or both (an event). Whatever the relationship (callable, assignable, etc) the parent 'controls' a 'virtual' code element. Thus the semantic control mechanism (of virtual inheritance) is centric to the parent.
The polymorphic aspect is the ability of the child implementation to type the functionality (of its virtual implementation) to the child's specific needs (for that functionality). Thus the semantic polymorphic mechanism is centric to the child.
In articulating these two aspects the relationship of Virtual Inheritance to Type Polymorphism becomes clear. The 'virtual control' functionality of 'Virtual Inheritance' is the primary benefit to the parent class. The polymorphic 'potential' of Virtual Inheritance is the primary benefit to the child class. Note that polymorphism (in the child) is NOT a requirement of General Virtual Inheritance (GVI).
The semantic effect of 'virtual control' is that the parent can delegate responsibility for the functionality to the child. This functional delegation, in turn, leads to the polymorphic aspect of Virtual Inheritance via the actual implementation in the child.
Note that the virtual code element in the child is virtual from the parent's point of view and actual from the child's point of view.
Thus Virtual Inheritance is a control mechanism for parents that allows functional delegation to the child. If a single line of inheritance exists (between first ancestor and final descendent) with several layers of inheritance then no polymorphism exists (its just pure functional delegation).
Languages
C++
Virtual Inheritance is a term that has historically been used in three major Object-Oriented Language (OOL) contexts.
- The C++ community,
- The non C++ community
- Language independent OOL phenomena (general conceptual semantics in OOLs)
To do so the term General Virtual Inheritance (GVI - see below) is the language independent meaning (the general meaning).
In the C++ programming community the term 'virtual inheritance' is the historic
C++ Diamond problem
resolution meaning originating from the C++ virtual keyword used in inheritance.
To avoid confusion this article uses the term Resolution Inheritance (RI) to qualify syntax mechanisms
that resolve potential conflicts due to inheritance (such as the diamond problem).
Note the
Stateful Diamond Point pattern
is the basis of the
example code
that shows C++ inheritance in a language independent context.
In the general context (language independent) of other languages that support
Multiple Implementation Inheritance (MII) a better term (than the historic C++ 'virtual inheriance' meaning) would be
Resolution Inheritance (RI). In a hypothetical object-oriented language, for
example, the use of a resolve keyword, instead of the C++
virtual keyword, would be more accurate to the conceptual
semantics of state space collision resolution (see below). The conceptual
semantic of resolution is the key point to keep in mind in the context of MII.
Note that C++ has two uses for Resolution Inheritance (RI) to resolve potential ambiguity problems caused by Multiple Implementation Inheritance (MII) and virtual method overriding. Note it is impossible to produce state space collision problems (ICA) in modern C++ production compilers as a compile error will occur instead (Vs. a runtime error). Member Method Override Ambiguity (MOA - castable objects), however, is shown below.
Also see the Semantic Scope section below comparing language independent conceptual semantics with language specific syntax mechanisms.
C++ Method Override Ambiguity (MOA)
Normal method overriding is limited to the context of the object's current casting.For Example:
struct Human };struct Mutant : public Human };
int main()
Calling m->Eyes() would return 3, but calling h->Eyes() would return 2, even though they represent the same object. Simply changing the class definitions to:
struct Human };results in both calls tostruct Mutant : public Human };
m->Eyes() & h->Eyes() returning 3.Resolution Inheritance (RI), for 'Method Override Ambiguity' (MOA), is instantiated using the C++ 'virtual' keyword as shown above.
C++ Inherited Class Ambiguity (ICA)
Resolution inheritance (RI) in C++ solves a potential problem
caused Multiple Implementation Inheritance (MII) when a
child class can inherit (potentially) two instances of the same ancestor class.
To resolve the ambiguity of which instance to use C++ provides the
virtual keyword that tags a class as having only one
'version' (instance) in the binary code.
Resolution inheritance is used when the inheritance is representing
restrictions of a set (functionally orthogonal code) rather than a composition of parts (as in object containment via
embedded instance). You denote a member as
virtual by the virtual keyword.
For example:
// Bat animal example class Animal ;In the above, if// Use RI to inherit Animal (resolve ICA) via 'virtual' keyword class Mammal : public virtual Animal ;
// Use RI to inherit Animal (resolve ICA) via 'virtual' keyword class WingedAnimal : public virtual Animal ;
// RI ensures only one instance of Animal will be instantiated (no ICA problem) class Bat : public Mammal, public WingedAnimal ;
// If RI is not used (via virtual keyword) a compiler error results void main()
Mammal and WingedAnimal did not
inherit Animal virtually, then the address of my_bat could not be assigned
to animal_ptr because of Inherited Class Ambiguity (ICA).
If you remove the virtual keyword in the code above
you get the compile error.
In this case Resolution Inheritance (RI) solves the 'Inherited Class Ambiguity' (ICA) POTENTIAL problem
by 'forcing' a single copy of Animal (a single instance) to exist in the binary code.
The virtual keyword
RESOLVES the potential ambiguity (ICA) over which ancestor CLASS instances to use.
Inherited Class Ambiguity is a POTENTIAL problem because, in modern C++ compilers, you get a compile time error. An ACTUAL problem of ICA in the runtime binary code (instance of the ICA problem via two instances of Animal in the binary) is impossible.
C++ Resolution Mechanism for Diamond Problem
In the context of C++ and the Diamond problem the term 'Resolution Inheritance' (RI) is used to distinguish conceptual resolution semantics (see ICA above) from the conceptual control semantics of Virtual Inhertitance (GVI).
In this context (C++/Diamond) the C++ 'virtual' keyword (a syntax mechanism) has a resolution aspect (semantic aspect) to its 'semantic mechanism' (C++ language specification relevant to ICA). Put in simpler terms the 'virtual' keyword (in ICA) has nothing to do with 'Virtual Inheritance' (GVI).
In this context Resolution Inheritance (RI) will resolve an ambiguity (either MOA or ICA). The code below shows how RI resolves an Inherited Class Ambiguity (ICA) in which more than one instance of a base class is referenced in the inheritance structure.
For Example:
class Base; class Child1 : virtual public Base; class Child2 : virtual public Base; class Diamond: public Child1, public Child2;
void main()In the above code sample. The 'virtual' keyword for 'Base class inheritance' (by the children Child1, Child2) will resolve the Inherited Class Ambiguity (ICA) diamond problem (thus the resolution aspect/mechanism).
If the 'virtual' keyword was not present an 'ambiguous' compile time error would result because the compiler is not sure 'which base class' to use (ICA). Should it use the (potential) instance in Child1 or Child2?
The C++ syntax mechanism of the virtual keyword
gives rise to the language specific (C++) and context specific
(diamond problem) meaning of Resolution Inheritance (RI) as a conceptual semantic resoultion mechanism
(i.e. an intention to 'resolve' the ICA ambiguity).
As such, the CONCEPTUAL semantic meaning of Resolution Inheritance (RI in C++ and diamond problem context) is as
a resolution mechanism to ensure only one 'copy' of the Base state space is implemented.
The use of the virtual keyword (RI resolution aspect) does not detract from the language independent (CONCEPTUAL) meaning of General Virtual Inheritance (GVI control/polymorph aspect). Furthermore the example C++ code above exhibits potential General Virtual Inheritance (as in the control/polymorph aspect) as a major feature of its capabilities even within this context (the diamond problem).
Note, the semantic mechanisms (i.e. an ICA resolution mechanism) for the C++ language specifcation are syntactic mechanisms by definition (i.e. the syntax of C++ 'virtual' keyword for ICA resolution). This 'virtual' keyword in C++ does not detract from the conceptual semantics of General Virtual Inheritance (GVI) when used in a language independent context (as defined in this article).
The term Resolution Inheritance (RI) should be used to qualify the effect
of the 'virtual' keyword in an ICA/C++/Diamond context). This (RI) implies the
'resolution aspect' of the C++ virtual keyword syntax
mechanism. Note that even in this context (C++/Diamond) the general meaning
(control/polymorph mechanism) holds true. General Virtual Inheritance (as
defined in this article) exists within the inheritance infrastructure for the
diamond problem (as shown in the High State Tracker example below).
In C++ the GVI computing logic of control ALWAYS coexists with RI phenomena. Thus a 'Diamond' type class (as given in the code example below) may implement virtual methods that are controlled by the 'Base' parent.
Stateful Diamond Point (SDP) Pattern
A short but effective example of Virtual Inheritance in the context of other inheritance phenomena is presented below (High State Tracker). It shows how Virtual Inheritance compliments other inheritance phenomena (such as Implementation Inheritance). It also shows that Virtual Inheritance (GVI in all object-oriented languages) coexists with Resolution Inheritance (RI in C++).
This example uses a specific pattern called the
Stateful Diamond Point (SDP) pattern
to clearly articulate multiple inheritance of state without polymorphism. The
class participants are listed below.
| Pattern Role | Example Role | Class | Implementation Description |
| Foundation | State machine | Base
| Controls current system state |
| Functional Supporter | Global manager | Internet_child
| Logs high states to global office |
| Functional Supporter | Local manager | Database_child
| Logs high states to local home office |
| Execution Point | Session manager | Diamond_tracker
| Tracks high states in the current session |
The SDP pattern features a descendent (Execution Point) that is controlled by the base (Foundation) and uses a functionally orthogonal middle layer (supporters) to execute the functionality of a Virtual Method implemented in the descendent. In the inheritance tree the state machine forms the foundation, followed by functionally orthogonal support managers, which, are joined at the 'Execution point'.
The SDP pattern name is derived from the emphasis on stateful MII (Multiple Implementation Inheritance of state). The Stateful is contrasted to other similar Diamond Point patterns that would emphasize polymorphism or a combination of common state space (stateful MII) and polymorphism.
The SDP pattern name also emphasizes the Diamond Point via the design concern to deal with the surface API of the final descendent. The Execution Point class implements the Virtual Method. The Point of the design is the desired functionality (Surface API) available to any client classes that use the pattern to perform some target functionality.
In the SDP pattern the core design concern is the functionality (the Point of the design)
presented by the surface API at the Execution Point. This exposed functionality
(surface API) helps to contrast Object Aggregation and Composition design approaches
from Inheritance approaches (balanced GVI/MII for polymorphism and normalization).
Note that, in this pattern, the functional supporters should be functionally orthogonal.
The SDP pattern has a characteristic 'Arrow' data flow pattern embedded within it.
Note that the data flows;
- From the (1) execution point to the (2) foundation
- From the (2) foundation to the (3) execution point
- From the (3) execution point to the (4,5) support classes
if statements at points 1,2,3 and 4.
Expansive is additional data, such as in data structures and messages,
that is added to the original incoming datum at each point (1,2,3,4).
The High State Tracker example of the SDP pattern is more reflective of real
world production software (then the shorter C++ examples herein). It features
the following C++ Virtual Inheritance phenomena (GVI/RI).
| Code Feature | Implementation Description |
| Coexistence | GVI, RI, MII of state space, SII of state space |
| GVI Control mechanism | Virtual method specification - Base::Log_state()
|
| GVI Implementation | Virtual method implementation - Diamond_tracker::Log_state()
|
| RI Resolution mechanism | Inheritance in support layer - virtual Base
|
| MII of state | Base::Current_state
|
| SII of state | Highest_local_state, Highest_global_state
|
| No polymorphic phenomena | Only one instance of Log_state() in one child (Diamond_tracker)
|
| No polymorphic children | Diamond_tracker has no peer children in inheritance tree
|
Thus the High State Tracker example is reflective of a simple diamond problem (ICA) that exhibits Multiple Implementation of state Inheritance (MII) but without any polymorphism.
Coexistence of Virtual and Resolution Inheritance in C++
The coexistence of virtual (GVI) and resolution (RI) inheritance in C++ is demonstrated in the High State Tracker example code presented below.
Note that there is no polymorphism phenomena related to GVI in this code example
The parent (Base) only controls (control phenomena) the child (Diamond_tracker). There is no 'multiple versions of children' (peers to Diamond_tracker in the inheritance tree) with multiple versions of a virtual method (see Log_state() below).
// High_State_Tracker Example // //#------------------------------------------------------------------------------------------------# //# State machine :_: Manages state space - Ties all concerns together //# Use GVI - Specify Child 'Log_State()' and use it as Virtual Method //#------------------------------------------------------------------------------------------------# class Base // void Set_state(int next_state) // int Get_current_state() // virtual // Virtual Method (Shows GVI - General Virtual Inheritance) void Log_state(int new_state); // Specify here : Instantiate in Diamond class };//#------------------------------------------------------------------------------------------------# //# Global Manager :_: Logs high states to global office - manages global concerns //# Use RI - Virtual forces one copy of Base in Diamond_tracker //#------------------------------------------------------------------------------------------------# class Internet_child : virtual public Base protected: void Log_global_high_value(int new_state) } public: Internet_child() // Internet retrieval could go here // int Get_global_highest_state() };
//#------------------------------------------------------------------------------------------------# //# Local Manager :_: Logs high states to local home office - manages local concerns //# Use RI - Virtual forces one copy of Base in Diamond_tracker //#------------------------------------------------------------------------------------------------# class Database_child : virtual public Base protected: void Log_local_high_value(int new_state) } public: Database_child() // Database retrieval could go here // int Get_local_highest_state() };
//#------------------------------------------------------------------------------------------------# //# Session Manager :_: Tracks high states in the current session - manages immediate concerns //# Use GVI - Parent (Base) controls child (Diamond_tracker::Log_state()) //# Use RI - One copy of Base, //#------------------------------------------------------------------------------------------------# class Diamond_tracker : public Internet_child, public Database_child public: Diamond_tracker() // void New_state(int new_value) Set_state( new_value ); // Move system to new state via Base } // int Get_session_highest_state() };
//#------------------------------------------------------------------------------------------------# //# Test Driver :_: Drives the high state tracker (Diamond_Tracker) //# Show RI and GVI coexisting and working together //#------------------------------------------------------------------------------------------------# void main()
//#------------------------------------------------------------------------------------------------# //# Output :_: Show the state transitions - Highest state logged locally and globally //# Show RI produces one state space copy ( Current_State ) //# Show GVI allows parent to control child ( Log_state() ) //#------------------------------------------------------------------------------------------------# // // Start : Highest session state is : 0 // Start : Highest local state is : 30 // Start : Highest global state is : 70 // // : Current state is - 10 // : Current state is - 30 // : Current state is - 40 // // Middle : Highest session state is : 40 // Middle : Highest local state is : 40 // Middle : Highest global state is : 70 // // : Current state is - 70 // : Current state is - 10 // : Current state is - 80 // // End : Highest session state is : 80 // End : Highest local state is : 80 // End : Highest global state is : 80 //
Note the Internet and database code are not present but noted via comment
(Log_to_home_office(), Log_to_local_database()). Also note that
the key initial states (Highest_local_state/Highest_global_state)
are not initialized from a database or the Internet. This is to keep the
example as short as possible and still present features and phenomena relevant
to GVI/RI.
In the code the test driver (Main()) calls the session manager
(my_diamond) to track the highest state in a state transition
sequence. Transitions are printed to the console. The starting, middle and
ending state space is printed as well.
The focus of the design is to show how the parent (
Inheritance in C++ is seemly complex in that many semantic aspects
(control/polymorphism/resolution/etc) are in effect at the same time (as in the High
State Tracker code example). It is therefore necessary for the terminology of
object-oriented (OO) computing to articulate the phenomena of Virtual
Inheritance precisely.
By articulating the difference between virtual (GVI) and resoultion (RI) inheritance we can discuss the role of
polymorphism in C++ (without reference to other OO languages) as well as compare
inheritance phenomena in C++ to other object-oriented languages (MII Vs. SII).
Ambiguity (ICA) in state space collision (MII) MAY have polymorphic resolution aspects but it
(polymorphism) is not REQUIRED. In 'High State Tracker' no polymorphism is
selected or resolved. This example shows only a 'collision of state space' (via
the potential for Base class multiple instances) being resolved (via RI). No
resolution of virtual methods (as in the Human/Mutant example) is present
Note that the functional similarity of logging to a database or the Internet is not
polymorphism in the strict sense (dispatch VTables, etc). From a system point of
view database and Internet logging are somewhat polymorphic (conceptually similar via
persistence). From a syntax mechanism point of view, however, they have different
functionality (Internet messaging Vs. database access).
High State Tracker also shows that POLYMORPHISM (different children with different
behavior) is a separate phenomena from GVI (control) and RI (resolution). Polymorphism is child
centric. General Virtual Inheritance (GVI) and Multiple Implementation Inheritance (MII)
both allow an 'opportunity' for polymorphism to exist (i.e. they do not REQUIRE
it in children). Thus, in the case of functionally orthogonal and functionally normalized
code, polymorphic phenomena need not be present (as this example shows via Log_state() and Current_state).
The example code also shows that you can have GVI in a control only 'mode' (no
polymorphism where only the control aspect phenomena exists - Log_state()). This emphasizes
the fact that Type Polymorphism (polymorphism) IS NOT General Virtual
Inheritance (control). The example also proves that GVI has control centric
semantics as its primary phenomena (Log_state()).
From a language independent perspective RI is actually a Multiple
Implementation Inheritance (MII) phenomena of resolution. As such
the term 'Resolution Inheritance' (RI) is a more accurate rendition of
the conceputal semantics needed to resolve state space collisions.
State space collision (which instance of state) and its resolution is NOT a
problem. Current Object-Oriented Languages (OOLs) have had controversy
handling this issue. That does NOT imply that future OOL syntax will NOT correctly
permute and solve the conceptual semantics of MII state space implementation
(instance generation) options.
Virtual code elements (specifications via inheritance) are centric to the concept of virtual inheritance.
They always 'force' an implementation in the derived class (child class).
Implementation Inheritance,
on the other hand, always shares an implementation in derived classes.
The code element specification (in all forms of virtual inheritance - GVI, Interfaces) becomes a
virtual control mechanism in itself.
This means that all virtual code elements (specified via inheritance) have two important aspects to their design.
It is important to understand the difference in the use context of virtual code elements (GVI Vs. SVI).
The use context determines who can use the virtual control mechanism formed via the
inherited virtual code element specification. The 'use context' determines if the parents can directly
use the virtual code elements or not.
The sections below highlight the core aspects of virtual inheritance as it exists in the C# language.
C# uses virtual inheritance the same way C++ does for method overriding.
Differing from C++, C# requires the keyword
Normal method overriding is limited to the context of the object's current
casting.
For Example:
The Human Impersonator output compares fixed to castable behaviour.
In the case where the design intention supports impersonation, the castable design having MOA is preferred
over the fixed design without MOA. The example shows that MOA is NOT an inherent problem in design architectures.
The 'impersonation' above is a good example of the desirable functionality of MOA.
Real world examples of impersonation are evident in high security systems
where security proxies will be used to 'impersonate' clients for access requests.
In this design context security proxies improve the overall performance, implementation
and maintainability of such systems.
MOA in any language is only a problem if the program architecture was not designed correctly.
Having behaviour implemented as a castable object or a fixed object is dependent upon
the design intentions of a good software architecture.
General Virtual Inheritance (GVI) has two primary criterion for its architecture.
The second GVI criterion is that the direct parental use context allows the 'parent' to 'use' the code elements (in the child specification)
as if the implementation (of the code elements) were its own.
Interface Inheritance, on the other hand, also has two primary criterion for its architecture
The second Interface criterion is that Interfaces become a 'type' unto
themselves which allows ANY client of that type to access and 'control' (call,
assign, etc) the code elements defined in the specification of the interface.
The advantage with
Interfaces
is that the Virtual Control Mechanism (VCM) has its own type.
Another advantage is that the 'type' is a set of code elements. A disadvantage of interfaces
is that the virtual code elements ARE NOT usable by the parent (as they are in GVI).
Thus Interfaces allow for a 'Simple Virtual Inheritance' (SVI not GVI) of the specification
that does not allow direct parental use of the virtual control mechanism. Interface
usage is open to all clients of the interface as a new object type. In effect the Interface
is a contract specifcation that separates what an object (interface instance) does from
how it does it.
Both GVI and interfaces (SVI) use 'virtual inheritance' to specify a control mechanism for code elements
(specifications via inheritance).
They differ however in WHO is going to use the Virtual Control Mechanism. With GVI its the parents who use
the code elements.
With Interfaces its everyone else who uses the code elements (which MAY be a 'parent-as-client').
GVI provides parents a 'virtual' code element.
Interfaces (SVI) provide client objects a 'virtual' set of code elements (contained in the interface implementation).
The Subject Interface example below shows Virtual Inheritance (VI) in the context of
Interface Inheritance.
It demonstrates the
Virtual Control Mechanism (VCM)
aspect of Interfaces (SVI).
It shows that virtual control mechanisms can contain
assignable state space (in addition to callable code elements like methods).
Finally it shows the
client use context
of the VCM specified by the Interface.
Virtual Control Mechanism (VCM) :
The
The VCM allows different types of objects to be controlled by the same set of virtual code elements.
Any class that inherits the Interface will be forced to provide the set of 'implementation
code elements' represented by the virtual code elements.
The
Assignable State Space :
In the example above the
In Virtual Inheritance code elements are said to be 'controllable'. This means
that a code element can be called (method), assigned (bool) or loaded (event).
The conceptual semantics of the 'control aspect' do not, and should not, address
the implementation details of a particular compiler or language.
This control aspect is an important
difference between virtual inheritance and virtual functions (VTables - compiler implementation).
Client Use Context :
Note that virtual code elements, established via inheritance (in C#, C++, java or
any language), ALWAYS have a use context aspect. The use context aspect determines how
the specification can be leveraged in the software design architecture.
For example, can the parents leverage the code elements for polymorphic control
(GVI)? Can client objects leverage the 'interface aspect' and drive a target
object via the 'interface' without a concern about other 'aspects' of the object
(SVI - contract aspect as in the code above)?
The Subject Interface code shows that Simple Virtual Inheritance (SVI)
has a client use context aspect to its conceptual semantics.
In GVI the parents have control.
In SVI everyone, except the parents, has control.
Object-oriented languages may feature other use contexts for virtual
code elements besides parent/client (GVI/SVI). Thus it is important to
note that Virtual Inheritance (VI) is centric first to the specification
aspect (VI) and then to the use context aspect (GVI/SVI/etc).
Understanding the use context of virtual code elements is important in understanding
the design advantages and disadvantages of virtual inheritance. The Stateful
Diamond Point pattern (presented in the C++ section) is implemented in the
C# language below. It shows the coexistence of General and Simple virtual inheritance (GVI and SVI).
In C# the same pattern participants exist
but are connected using Single Implementation Inheritance (SII) and object aggregation.
Virtual inheritance (VI), in the context of the C# design approach (GVI/SII), can be
compared to VI in the C++ design approach using functional normalization,
aggregation and dispersion along the lines of inheritance (GVI/MII).
The comparison shows how VI (GVI/SVI) effects the internal functionality of the SPD pattern.
In the C# SPD pattern implementation the core design concern is still
the functionality (the Point of the design)
presented by the surface API at the Execution Point.
With C# Interfaces the pattern surface API can be formalized
as the execution point interface.
Relative to Virtual Inheritance (GVI/SVI)
the C# implementation of the SPD pattern differs from the C++ implementation
in several important ways. A comparative examination of the code reveals
these differences stem from the difference between GVI/MII and GVI/SII.
This difference is relevant to SVI and its role in pattern functionality.
It is important to note that the Interface SVI adds nothing to the functionality of the pattern itself.
Thus SVI is not responsible for the key differences in the two designs (C++ Vs. C#).
This highlights the contractual mechanism aspect of SVI in Interfaces
brought about by the virtual code element use context (as explained above).
It also allows SVI to be factored out in any functional partitioning
design issues (as explained below).
The coexistence of
Virtual Inheritance (GVI)
and
Interfaces (SVI)
in C# is demonstrated in the High State Tracker example code presented below.
The code is basically a port to C# from the C++ example (above).
Since C# lacks
Multiple Implementation Inheritance (MII)
the design of the C# code uses Single Implementation Inheritance and
object aggregation. The functionality (the output) of the SPD pattern C# implementation is identical to the C++ example.
SVI Parent :
Note that the contract (
SVI Child :
Note that the Interface (SVI) has nothing to do with the pattern functionality.
An identical functionality exists in the C++ SPD pattern unit without the SVI specification.
This shows that the effects of Simple Virtual Inheritance (SVI) can be factored
out in any functional partitioning issues (via inheritance) within the pattern unit.
Only GVI, because of its parent use context (of the virtual code elements), can
effect pattern functionality via inheritance (as is shown in the C# SPD example
above).
Execution Point Contract :
Note that the contract for the surface API of the SPD pattern unit is NOT the same
as a contract for the target functionality (within the pattern unit).
Interfaces, a form of virtual inheritance (SVI virtual code elements),
only provide an 'interface specification'. No specification of the actual functionality
(provided by the interface) of the pattern is provided.
Object Aggregation :
Since C# does not have Multiple Implementation Inheritance the example must
contain, create and 'surface replicate' functional support members
(such as methods that exist at the pattern surface API).
Aggregate Construction :
Unlike MII in C++ the
Surface API Replication :
Unlike MII in C++ the
The code features of the C# SPD implementation above combine to
form a single functional unit abstracted at the execution point surface.
The functional system, formed by the pattern
participants, can be seen as a 'single balanced unit of functionality' which is the pattern
implementation (pattern unit). Balance is achieved via
Functional Normalization
among the participants.
The example above shows a common use of Virtual Inheritance (VI - code element
specification via inheritance) in the form of GVI (parent use context) and SVI (client
use context). The most important aspect presented in the example is
that SVI is external to the pattern (external contract) while GVI is internal to the pattern (internal plumbing).
Virtual Inheritance (VI) is the specification of code elements via inheritance. The virtual code elements
produced by the specification have either a parent use context (GVI) or a client use context (SVI).
The use of SVI and GVI is presented in the context of Class based functional units.
In this case (class based design) the following hold true.
GVI is an intra-pattern mechanism : It provides parental control of virtual code elements (parental use context).
GVI can leverage the features of MII more than it can SII. This is because SII based
designs use object aggregation/composition which lacks the lines of inheritance needed
for GVI functionality.
SVI is an inter-pattern mechanism : It provides client control of virtual code elements (client use context).
SVI has no effects via inheritance other than the forced implementation of the specification. As such it can not
be used within the pattern unit for parental control (no parent use context).
The internal/external comparison of GVI/SVI in pattern unit design is valid for class based functional units like
High State Tracker. System level component design patterns, on the other hand, use component based participants
to form functional pattern units.
Component level patterns, which bind together complex pattern participants, may use SVI internally
as contracts between participants. These types of systems are generally loosely coupled and non-performant
in comparison with tightly coupled high performance pattern units like High State Tracker.
Use context, lines of inheritance and participant bindings (class/component) are
important foundation concepts in understanding the role Virtual Inheritance (VI)
takes in the object oriented design process.
The coexistence of GVI as internal plumbing
compliments SVI as external contract.
It is clear from the example that virtual code element design (the specification
process) starts with WHO will be using the elements. Internal parents, external
clients and participant binding are the three perspectives to keep in mind to
distinguish the architectural benefits of GVI and SVI.
public class Mutant extends Human
}
public class Program
}
It is necessary for the terminology of object-oriented (OO) computing to
articulate the phenomena of
Virtual Inheritance
precisely. The terminology should reflect the conceptual semantics of the core
computing phenomena rather than the syntactic mechanisms of any one object-oriented
language.
Ideally the conceptual semantics and syntax mechanisms of OO code elements are
identical but this is not always the case. The rapid evolution of computer
science has accelerated the semantic evolution of its core terminology.
It has become a common industry practice, therefore, to
provide qualifiers and acronyms (if needed) for terms that vary in their
conceptual meaning due to use in a specific context (generally a particular
computer language syntax).
In
Implementation inheritance (II), for example,
there is
A case in point,
Virtual Inheritance (VI)
as distinguished from
Resolution Inheritance (RI)
within this WikiPedia article (see
C++ Resolution Mechanism).
In order to better articulate this difference the conceptual semantic scope and history
of object-oriented language syntactic mechanisms is briefly addressed.
The
semantic scope
and
history
of Virtual Inheritance is articulated in the sections below.
This articulation helps to clarify the 'General' aspect (GVI) of 'Virtual Inheritance' from subjugated concepts
such as Virtual Functions (as subset of GVI) and language specific meanings (i.e. C++ RI, etc)
This 'See Also' topic map provides links to articles related to Virtual Inheritance (VI).
Virtual Inheritance is best understood within the context of class inheritance
(all forms of inheritance). In the same way, Class Inheritance (CI) is best
understood in the context of relevant design approaches (for combining computing
functionality), issues and problems in software architecture.
The sections listed below help to distinguish the concepts of 'functional
dispersion/aggregation along lines of inheritance' (as in Virtual/Implementation
Inheritance) from 'object aggregation/composition' as embedded/referential
members in a class (embedded/referential containment).
Note the interesting semantic distinction between
the AGGREGATION of 'self reliant' objects from the COMPOSITION of 'object parts' (from
the English language - 'composition' semantics infers 'composed of parts').
Similar subtle but important distinctions (semantic aspects) exist between
virtual, implementation, multiple (MII) and interface inheritance.
This section contains links to articles relevant to
the general concept of inheritance.
This section contains links to articles explaining
the conceptual details of inheritance.
This section contains links to other ways of combining
computing functionality (object aggregation/composition). Links to these concepts are
listed to contrast inheritance from other approaches to functional
design in object-oriented languages.
Many design problems in inheritance occur not because a mechanism (VI, II, MI, Interface) is 'bad' but
because the right tool (mechanism) wasn't used for the right job (like using a hammer for a screwdriver).
The problems below are not inherent to semantic mechanisms (which define the MEANING of a lanuage specification). These problems ARE, however, inherent to poor software design (actual language mechanism misuse in jave, C#, C++ etc.) or poor language
implementations (bad compiler architecture/language specification/language design).
Note also that syntax mechanisms should not be confused with conceptual semantics. You can not take a specific language specficiation and reverse engineer its syntactic mechanisms (what the compiler SHOULD generate) into the conceptual semantics expressed in the English (Human) lanaguage.
The supposion that inherently difficult and complex processing
should suddenly become simple and trivial is also incorrect (i.e. an automobile is NOT
as complex as a nut and bolt).
In the same way, each inheritance mechanism (VI, II, MII, etc) has logical
semantic aspects that pre-exist ANY particular language implementation generated
by a compiler (cause/semantics precedes effect/implementation). This
perspective is important in distinguishing a poor software design (expression
mechanism misuse) from a poor mechansim specification/implementation (language specification problem, compiler design problem).
Virtual Inheritance (VI) is one of many object-oriented mechanisms used to achieve a design intention.
Object-oriented software design intentions are generally guided by the principles listed below.
Functional normalization is the removal of needlessly replicated code.
This section contains links to articles related to concepts relevant to
this process.
Virtual Inheritance may be categorized and classified under the following headings.
From Wikipedia, the Free Encyclopedia. Original article here. Support Wikipedia by contributing or donating.Base) controls the
child (my_diamond) using GVI (log_State()). It shows that
GVI coexists and operates with RI (virtual Base inheritance). It
shows that RI resolves ambiguity (ICA) in C++. Each state transition also
shows Multiple Inheritance of state Implementation (MII of state -
Current_state) which is the primary basis for RI (which instance
of state - state space collision) existence.Summary of Virtual and Resolution Inheritance in Object-oriented Languages
C#
Since C# does not have Multiple Implementation Inheritance (MII) it can not have multiple sources (parents)
of virtual code elements (via GVI). C# offers Single Implementation Inheritance (SII) with Multiple Interface Inheritance (SVI - see below).
This creates significant differences in the use context when compared to other languages.C# Method Override Ambiguity (MOA)
override modifier to produce a fixed behaviour in the
derived class (fixed object Vs. castable object - see below).using System;
//
public class Human
}
public class Mutant : Human
}
public class Test_driver
}
// Test_driver output
//
// WITH - 'override' keyword for Mutant : Output is 'Fixed'
//
// Eye color is : Yellow
// Eye color is : Blue
// Eye color is : Yellow
//
// WITHOUT - 'override' keyword for Mutant : Output is 'Castable'
//
// Eye color is : Yellow
// Eye color is : Blue
// Eye color is : Blue
//
Resolution Inheritance (RI), for 'Method Override Ambiguity' (MOA), is instantiated using the C# 'override'
keyword as shown above.Simple Virtual Inheritance (SVI) via Interface Inheritance
The first GVI criterion is that the Virtual Control Mechanism is an abstract specification mechanism that can then
be used to control the target code element (as a 'virtual code element').
The specification is virtually inherited
and will force the implementation to exist in the derived class.
The first Interface criterion (just like GVI) is that the Virtual Control Mechanism (i.e. the
interface) is an abstract specification mechanism that can then be used to
control the target code element (as a type).
The specification is virtually inherited
(no implementation passing into the child via inheritance)
and will force the implementation to exist in the derived class.Use Context of Virtual Code Elements
using System;
//
// Subject Interface Example
//
//#------------------------------------------------------------------------------------------------#
//# Binding Mechanism :_: Delegate for event binding between subject and observer
//# Use_SVI(4) an Interface event shows a loadable virtual control element
//#------------------------------------------------------------------------------------------------#
public delegate void Delegate_signature( string p_notification_message );
//#------------------------------------------------------------------------------------------------#
//# Pattern Manager :_: Binds the observer to the subject and fires subject events
//#------------------------------------------------------------------------------------------------#
class Observer_manager
}
//#------------------------------------------------------------------------------------------------#
//# Subject Binder :_: Binds the manager to a preexistent subject defined outside the manager
//# Use object composition for external pattern participants
//#------------------------------------------------------------------------------------------------#
//
public Observer_manager( Subject_API_surface p_subject )
//
//#------------------------------------------------------------------------------------------------#
//# Pattern Driver :_: Creates pattern participants, binds participants, fires subject events
//# Use object aggregation for internal pattern participants
//# Use_SVI(2) to drive different subjects via the Contract aspect of VCM
//#------------------------------------------------------------------------------------------------#
public
void Main_process()
}
//#------------------------------------------------------------------------------------------------#
//# Subject_A :_: Contains events that notify any observers (notification targets)
//# Use_SVI(3) do not have a notification count for this subject type
//#------------------------------------------------------------------------------------------------#
class Subject_A : Observer_manager.Subject_API_surface
bool notification_gate_flag;
//
public bool Fire_event( string p_event_identity )
//
public event Delegate_signature notification_targets;
//
public bool Notification_gate_flag
set
}
}
//#------------------------------------------------------------------------------------------------#
//# Subject_B :_: Contains events that notify any observers (notification targets)
//# Use_SVI(3) have a notification count for this subject type
//#------------------------------------------------------------------------------------------------#
class Subject_B : Observer_manager.Subject_API_surface
bool notification_gate_flag;
//
public bool Fire_event( string p_event_identity )
//
public event Delegate_signature notification_targets;
//
public bool Notification_gate_flag
set
}
}
//#------------------------------------------------------------------------------------------------#
//# Observer :_: A 'notification target' - waits for notification - prints notification
//#------------------------------------------------------------------------------------------------#
public class Observer
//
public void Notify_me(string p_notification_message )
: Notification message - ",
my_identity,
p_notification_message
);
}
} // End_of_class
//#------------------------------------------------------------------------------------------------#
//# Test Driver :_: Main entry point for console application - Creates, runs binder/manager
//#------------------------------------------------------------------------------------------------#
class Test_driver
}
//#------------------------------------------------------------------------------------------------#
//# Output :_: Show pattern binding via interface contract specification
//#
//# Conceptual aspect 1 Show_SVI(1) as a 'client use context' VCM (manager VCM for subject)
//# Conceptual aspect 2 Show_SVI(2) contract aspect, driving different type objects (Subject A,B)
//# Conceptual aspect 3 Show_SVI(3) contract does not specify behaviour (polymorphic output A,B)
//# Conceptual aspect 4 Show_SVI(4) virtual code elements are 'controllable'
//#------------------------------------------------------------------------------------------------#
//
// Observer Instance Number One : Notification message - Notification : System A : Event_1
// Observer Instance Number Two : Notification message - Notification : System A : Event_1
// Observer Instance Number One : Notification message - Notification : System A : Event_3
// Observer Instance Number Two : Notification message - Notification : System A : Event_3
//
// Observer Instance Number One : Notification message - Notification 1 : System B : Event_1
// Observer Instance Number Two : Notification message - Notification 1 : System B : Event_1
// Observer Instance Number One : Notification message - Notification 2 : System B : Event_3
// Observer Instance Number Two : Notification message - Notification 2 : System B : Event_3
//
Subject_API_surface interface defines the set of virtual code elements
needed by the manager to control the subject. The specification, via the Interface,
forces the child to implement the code elements it defines. The elements are
'virtual' because they are controlled through the specification (not an implementation)
defined by the interface.Observer_Manager class displays this capability
by being able to control the Subject_A and Subject_B object types (classes).Main_process of the Observer_manager contains
the Notification_gate_flag code element which is an assignable code element (single value assignment).
The notification_targets code element is a loadable code element (multi-value assignment).Stateful Diamond Point (SDP) Pattern in C#
The SPD pattern in C# has the same 'Arrow' data flow pattern as found in the
C++ example. In the C# example the data flows;
In the C++ example the data flows;
The functional result, at the execution point surface, is the same for both the
C++ and the C# examples. The output of both implementations is identical.
The High State Tracker example of the SPD pattern is more reflective of real
world production software (then the shorter C# examples herein). It features
the following C# Virtual Inheritance phenomena (GVI/SVI-Interfaces).
Code Feature
Implementation Description
Coexistence
GVI, SVI, Interfaces, object aggregation (embedded members)
GVI Control mechanism
Virtual method specification - Base::Log_state()
GVI Implementation
Virtual method implementation - Diamond_tracker::Log_state()
SVI Specification
Interface inheritance - Execution_point_interface
SVI Parent
Test_driver::Execution_point_interface
SVI Child
Diamond_tracker
Execution Point Contract
C# Interface for the surface API of the SPD pattern used by the test driver
Object Aggregation
Via embedded members Internet_child, Database_child
Aggregate Construction
Construction code for Internet_child, Database_child
Surface API Replication
Diamond_tracker must replicate Get_local_highest_state(), Get_global_highest_state() API surface
The C# and C++ examples help to distinguish the concepts;
Comparing the architecture of virtual inheritance in both these contexts helps to understand
what benefits GVI and Interfaces (SVI) bring to the pattern functionality.
It also helps to clarify how the code element use context of virtual (VI) and implementation (II) inheritance
differs.Coexistence of Virtual and Interface Inheritance in C#
using System;
//
// High_State_Tracker Example
//
//#------------------------------------------------------------------------------------------------#
//# State machine :_: Manages state space - Ties all concerns together
//# Use GVI - Specify Child 'Log_State()' and use it as Virtual Method
//#------------------------------------------------------------------------------------------------#
internal abstract
class Base
//
protected void Set_state(int next_state)
", Current_state );
Log_state( Current_state ); // Use GVI : Control children and keep history of state changes
}
//
public int Get_current_state()
//
public abstract // Virtual Method (Shows GVI - General Virtual Inheritance)
void Log_state(int new_state); // Specify here : Instantiate in Diamond class
} // End of class
//#------------------------------------------------------------------------------------------------#
//# Global Manager :_: Logs high states to global office - manages global concerns
//# Use object aggregation to incorporate functionality in SII child class
//#------------------------------------------------------------------------------------------------#
class Internet_child
//
public void Log_global_high_value(int new_state)
}
//
public Internet_child() // Internet retrieval could go here
//
public int Get_global_highest_state()
} // End of class
//#------------------------------------------------------------------------------------------------#
//# Local Manager :_: Logs high states to local home office - manages local concerns
//# Use object aggregation to incorporate functionality in SII child class
//#------------------------------------------------------------------------------------------------#
class Database_child
//
public void Log_local_high_value(int new_state)
}
//
public Database_child() // Database retrieval could go here
//
public int Get_local_highest_state()
};
//#------------------------------------------------------------------------------------------------#
//# Session Manager :_: Tracks high states in the current session - manages immediate concerns
//# Use GVI - Parent (Base) controls child (Diamond_tracker::Log_state())
//# Use SVI - Force child to implement surface API needed by test driver (Test_API_surface)
//# Use object aggregation to bring in local and global manager functionality
//#------------------------------------------------------------------------------------------------#
class Diamond_tracker : Base, Test_driver.Execution_point_interface
//
public Diamond_tracker()
//
public void New_state(int new_value)
Set_state( new_value ); // Move system to new state via Base
}
//
public int Get_session_highest_state()
//
public int Get_local_highest_state()
//
public int Get_global_highest_state()
};
//#------------------------------------------------------------------------------------------------#
//# Test Driver :_: Drives the high state tracker (Diamond_Tracker)
//# Show SVI as execution point contract via the C# Interface
//#------------------------------------------------------------------------------------------------#
class Test_driver
//
public static void Main()
", parent_as_client_API.Get_session_highest_state() );
Console.WriteLine(" Start : Highest local state is : ", parent_as_client_API.Get_local_highest_state() );
Console.WriteLine(" Start : Highest global state is : ", parent_as_client_API.Get_global_highest_state() );
Console.WriteLine();
//
my_diamond.New_state( 10 );
my_diamond.New_state( 30 ); // Highest local state at start
my_diamond.New_state( 40 );
//
Console.WriteLine();
Console.WriteLine(" End : Highest session state is : ", my_diamond.Get_session_highest_state() );
Console.WriteLine(" Middle : Highest local state is : ", my_diamond.Get_local_highest_state() );
Console.WriteLine(" Middle : Highest global state is : ", my_diamond.Get_global_highest_state() );
Console.WriteLine();
//
my_diamond.New_state( 70 ); // Highest global state at start
my_diamond.New_state( 10 );
my_diamond.New_state( 80 );
//
Console.WriteLine();
Console.WriteLine(" End : Highest session state is : ", parent_as_client_API.Get_session_highest_state() );
Console.WriteLine(" End : Highest local state is : ", parent_as_client_API.Get_local_highest_state() );
Console.WriteLine(" End : Highest global state is : ", parent_as_client_API.Get_global_highest_state() );
Console.WriteLine();
}
} // End_of_class
//#------------------------------------------------------------------------------------------------#
//# Output :_: Show the state transitions - Highest state logged locally and globally
//# Show GVI as an internal pattern unit mechanism - Parent use context
//# Show SVI as an external pattern unit mechanism - Client use context
//#------------------------------------------------------------------------------------------------#
//
// Start : Highest session state is : 0
// Start : Highest local state is : 30
// Start : Highest global state is : 70
//
// : Current state is - 10
// : Current state is - 30
// : Current state is - 40
//
// Middle : Highest session state is : 40
// Middle : Highest local state is : 40
// Middle : Highest global state is : 70
//
// : Current state is - 70
// : Current state is - 10
// : Current state is - 80
//
// End : Highest session state is : 80
// End : Highest local state is : 80
// End : Highest global state is : 80
//
SVI Specification :
For Virtual Inheritance (VI) the pattern interface
(Execution_point_interface) functions just like a class. The child
inherits the interface. In this example the interface is the specification of
the 'parent' (Test_driver) to the child
(Diamond_tracker). This shows how an interface can be used to
consolidate a set of virtual code elements (specifications via inheritance) as a
single contract between the client and
the pattern unit (SVI - client use context).Execution_point_interface) is in the namespace of the
test driver. Syntactically the contract is the parent, not the test driver. Conceptually,
however, the interface is a specification mechanism in the design architecture that
binds the test driver to the target (Diamond_tracer).
This design architecture is named 'parent-as-client' to note that the interface specification is located in the client class namespace.Internet_child and Database_child require
construction code at the execution point (Construction burden of aggregates).Get_local_highest_state() and Get_global_highest_state()
support methods must be replicated at the execution point (surface burden of aggregates).Summary of Virtual and Interface inheritance in Object Oriented Languages
Java
In Java, all class methods are virtual: no keyword is necessary. The Java translation of the C++ is:
public class Human
}
The result of this program running is the output 3,3.Semantics
Note that MI (Multiple Inheritance)
can technically include Interfaces as in C#.
Thus the impetus to clarify the conceptual semantics of core terminology in the face of industrial obsolescence.See also
Fundamental Inheritance Concepts
Detailed Inheritance Concepts
Other Design Approaches
Inheritance Issues and Problems
Note that the semantics of a poorly designed 'expression mechanism IMPLEMENTATION'
(in a language specification or design) do not 'redefine' the SEMANTICS of an expression mechanism
(the inherent semantic meaning across all past, present, future and hypothetical language specifications). The 'CONCEPTUAL expression semantics' exist prior to and beyond any one language SYNTAX specification (C++, C#, Java, etc.). Most language mechanism specifications (SYNTAX EXPRESSIONS) are formalizations of previous programming practices in an earlier language (thus an evolution in expression formalization and understanding).Design Intentions in Inheritance
Functional Normalization
Logical Context of Virtual Inheritance
All text is available under the terms of the GNU Free Documentation License See Wikipedia Copyrights for details.
