Aztec® Programming Language
Version 1.1 Alpha 2

Copyright © 2010-2017, Aztec Development Group, All Rights Reserved

Download Aztec

Search        Contact Us

As truth is gathered...

I rearrange.

- Jon Anderson and Chris Squire


Inheritance and Polymorphism

Two of the key concepts in object oriented programming are Inheritance and Polymorphism. When a class is created, it can derive/inherit functionality from one or more parent classes. Every Aztec class must be derived from at least one class. If the class statement does not specify one or more parent classes in the 'from<>' keyword, the new class is automatically derived from the Base class.

Aztec uses the term "derived from" when a class inherits its behavior from one or more other classes, and those classes are referred to as base classes. Thus the class statement uses the 'from<>' keyword to designate the base classes, and the Aztec Base class is ultimately the base/parent of all other classes. Some programming languages use the term superclass and subclass for this relationship. For the discussion below and other pages that discuss inheritance topics, Aztec also uses the terms "parent" class and "child" class for this relationship. When a class is created and is derived from another class, the new class is considered the child and the class that its behavior is derived from is considered the parent. With multiple inheritance, a child can have more than one parent. This parent/child terminology also works well with the "family" concept that drives visibility of data and methods within a class hierarchy, which is described below.

Inheritance is a powerful concept which a well designed script/application can use to minimize or eliminate redundant logic or business rules. Common funtionality within a family of Aztec classes should be moved as far as up in the class hierarchy as makes sense, so all child classes in the family can potentially benefit from the same logic. When a child class needs special behavior, it can override a virtual method from one of the base/parent classes to modify the logic as needed for the child class and its children.

The key to this type of design is the "virtual" method, which allows a method in a child class to override the method that is already defined in one or more of the parent classes. Each child class has the opportunity to use the functionality provided by the parents, or to override the method. Inside the override method, the child still has the option of calling the parent version of the method, if it makes sense. When a child class overrides the virtual method, it has some options to consider. Any changes that are made at one level in the class hierarchy will also affect all of the child classes below that level.

♦ Provide different logic as a complete replacement for the logic provided in the parent class implementation.

♦ The derived/child class method may likely choose not to call the base/parent class version of the method in this case.

♦ Make some changes or add some functionality to the existing logic provided by the parent(s).

♦ The derived/child class method will likely call the base/parent class method in this case. Depending on the logic changes needed, the child has the option of calling the parent version of the method first, and then performing the new logic, or performing the new logic first, and then calling the parent method.

There are likely several schools of thought on the best way to handle the syntax for a method that can be overridden in a derived class. It basically comes down to what is used for the default, and it does end up having some interesting consequences that should be considered when designing an OO script/application.

♦ Aztec purposefully chose the OO model that requires a method to be specifically marked if it is to allow a child class to override the method. In other words, the default is that a method cannot be overridden in a child class. The 'abstract' or 'virtual' keywords must be used to indicate that the method can be overridden. If neither of those keywords are used, the method cannot be overridden.

♦ The override method in the child class must also be specifically marked as 'virtual', which will continue to allow this method to be overridden by its child classes, or 'final', which means that this is the end of the line. Child classes will not be allowed to override the 'final' method.

The important part of this OO model is not the naming of the keywords, though they were chosen with a lot of thought. The important thing is that the OO designer should think carefully about the design, and decide which family of methods really should be available for overriding, and which ones should not. If a class designer develops a method that is important or critical to the behavior in a class, and then allows that method to be overridden by a child class, that child class is being handed the keys to the kingdom. If the child class overrides a critical method, and does not handle it correctly (such as not calling the base class implementation when it should), the behavior of the parent class can be put in jeapordy.

♦ This may be exactly what the designer intends, but maybe not. Aztec's philosophy is that this decision should be made thoughtfully for each method, and only turn it on when it makes sense. The language tries to help by requiring it to be marked accordingly.

Polymorphism provides the system with the ability to work with an object at the "base class" level, and not really know or care what type of object it is actually working with. When an "abstract" or "virtual" method is called at the base class level, and that method has been overridden in the child class, the Virtual Machine automatically determines the actual method which needs to be executed, based on the actual object type, and the virtual method hierarchy for the family of classes. Of course, it is always possible to query the type of object one is dealing with in a base class (ObjectClass() method), but in most situations, using polymorphism provides a much cleaner and more maintainable design.

The Aztec programming language provides a rich set of keywords and embedded functionality in the Virtual Machine to fully support support inheritance and polymorphism.

♦ During class definition, the ‘from<>’ keyword is used to define a list of base classes.

♦ Aztec supports inheritance from multiple instance classes. Instance data can be used in each of the base classes.

♦ If no base class is provided, the class is derived from ‘Base’.

♦ For a data item or method defined within a base class, the visibility keyword(s) the item is defined with determines if a derived/child class can use it.

♦ If ‘family’, the hierarchy provides access to the item in this class and in all derived classes, as well as in any "adopted" classes (of this class only).

♦ If ‘private’, derived/adopted classes can not use it. The item is only visible to data or methods within this class.

♦ If a method in a base class is defined as ‘virtual’ or 'abstract', the derived class can override it by providing the exact same method signature.

♦ If the base class method is 'abstract', the derived class must override the method, or the derived class will remain abstract.

♦ The ‘virtual’ or ‘final’ keyword must be used for the overriding method.

♦ If marked as ‘virtual’, any new class derived from this derived class can also override the method.
♦ If marked as ‘final’, further derived classes can not override it.

♦ As mentioned above, the fact that the overriding method requires a virtual/final keyword may seem draconian or cumbersome, but there is some rationale for this model:

♦ The designer of the base class should think carefully about which methods can be overridden by derived classes. This is the reason that the default setting is 'final', meaning that the method can not be overridden. The designer of the method must decide which methods can be overridden and explicitely mark each of them as abstract or virtual.
♦ Likewise, the designer of the derived class should understand the methods of its base class(es), and consciously decide what to do with each abstract or virtual method. If a virtual method is overridden in the derived class, one must then decide whether further derived classes can also override it (mark it as virtual) or if this class is the last one which can override it (mark it as final). Requiring one of them forces the designer of the class to think about it.

♦ Several rules for constructors and destructors as they apply to inheritance. Refer to the Constructors and Destructors page for more information.

♦ Inside the constructor of a class, a method call must be made to a constructor for each of the defined base classes. A default constructor (no arguments) for the base class will be handled automatically by the system if it is not manually called. The compiler will flag an error if all base class constructors are not handled, either manually or automatically.

♦ When on object is no longer referenced, the Virtual Machine analyzes the class hierarchy for the object, and it manually sets up calls to the destructor for each class in the hierarchy, if one exists. The destructor for any class is only responsible for handling data or resources that apply to the level. The destructor of the derived class does not (and cannot) try to invoke the destructors of the base classes. Their execution is performed automatically by the VM.

♦ The Aztec Virtual Machine keeps track of the actual data type of an object and understands the inheritance relationship between classes.

♦ If a reference to a base class is assigned the reference of a derived class, and that base class calls one of its own virtual methods which is overridden in the derived class, the VM will automatically invoke the method in the derived class (polymorphism).

♦ When inside an instance method in a derived class, a member of a base classes can be accessed using “ClassName.IdentifierName”.

♦ This is useful when inside a virtual method in a derived class to call the same virtual method in the base class. For instance, if ‘NewClass’ has two base classes ‘ClassB’ and ‘ClassD’, and we’re inside a virtual method named ‘ProcessEvent’ in 'ClassB, then “ClassB.ProcessEvent()” will invoke the method in the ClassB class. This is also useful for handling duplicate names in each branch of the class hierarchy. “ClassD.ProcessEvent()” will invoke the same method in the ClassD class.

Sample Multiple Inheritance Hierarchy


Adopted Classes

When defining an Aztec class, one or more classes can be entered in the 'adopt<>' keyword. An "adopted" class is treated as a member of the class hierarchy family relative to visibility of items within this class only. Source code in a method of an adopted class can see data items and methods in the defining class if they are marked as 'family'. The scope of this 'family' visibility is limited, and it only pertains to members of the class that adopts it. It does not pertain to 'family' members of a base class of the class that adopts it, and it also does not pertain to derived/child classes of the class that adopts it.

♦ An adopted class is considered part of the “family” for that class which adopts it. Source code in the Adopted Class can access items in this defined class (the class that adopts it) that are marked as 'family'.

♦ A child class does not automatically adopt a class just because a parent class happens to adopt it. This limits the enhanced visibility of the adopted class to just the class that actually adopts it.

♦ A child class must manually adopt the class if that behavior is necessary.

♦ This can be useful for providing controlled visibility of class items to another class.

♦ An adopted class does not need to be defined in the same module as the class which adopts it.


Page UpPage DownCopyright © 2010-2017
Aztec Development Group
All Rights Reserved

Download Aztec