A Class Hierarchy for Heterogeneous Arrays
Interfaces Based on Heterogeneous Arrays
A heterogeneous class hierarchy lets you create arrays containing objects of different classes that are related though inheritance. You can define class methods that operate on these heterogeneous arrays as a whole.
A class design based on heterogeneous arrays provides a more convenient interface than, for example, extracting elements from a cell array and operating on these elements individually. For more information on the design of class hierarchies that support heterogeneous arrays, see Designing Heterogeneous Class Hierarchies.
All heterogeneous hierarchies derive from matlab.mixin.Heterogeneous
.
Define Heterogeneous Hierarchy
Note
This example does not use valid terminology or techniques for managing financial assets. The purpose of this example is only to illustrate techniques for defining heterogeneous class hierarchies.
This example implements a system of classes to represent financial assets, such as stocks, bonds, and cash. Classes to represent categories of assets have certain common requirements. Each instance has one of the following:
Textual description
Type (stock, bond, or cash)
Means to determine the current value of the asset
Heterogeneous arrays of these objects need methods that can operate on the whole array. These operations include:
Creating a table of information about all assets contained in the array
Graphing the relative contribution of each asset type contained in the array
These requirements are factored into the class that is the root of the hierarchy. The root class derives from matlab.mixin.Heterogeneous
. In the following diagram, the Assets
class is the root of the hierarchy. The Stocks
, Bonds
, and Cash
classes provide the specialization required for each type of asset.
Assets Class
The Assets
class:
Derives directly from
matlab.mixin.Heterogeneous
Is the root of the heterogeneous hierarchy
Is abstract
Is the class of heterogeneous arrays composed of any mixture of
Stock
,Bond
, andCash
objects
Properties
The Assets
class defines two properties:
Description
— A general description of the individual asset constrained to be of classchar
.Type
— The type of asset defined as an abstract property that each subclass implements.
Methods
The Assets
class defines these methods:
pie
— A sealed method that creates a pie chart showing the relative mix of asset types.makeReport
— A sealed method that creates a report listing the assets.getCurrentValue
— An abstract method that each concrete subclass must implement to return the current value of the asset.getDefaultScalarElement
—matlab.mixin.Heterogeneous
class method overridden in theAssets
class to specify a default object. TheAssets
class is abstract so it cannot be used as the default object. For more information, see Default Object.
Methods in Heterogeneous Hierarchies
Methods defined by the Assets
class are either:
Concrete methods (fully implemented) that subclasses do not override
Abstract methods (signatures only) that subclasses implement
Concrete methods defined by superclasses in a heterogeneous hierarchy must specify the Sealed
attribute. Sealing these methods prevents subclasses from overriding methods implemented by the superclass. When calling methods on a heterogeneous array, MATLAB® calls the methods defined by the class of the array (Assets
in this example).
The pie
and makeReport
methods are examples of sealed methods that operate on heterogeneous arrays composed of Stock
, Bond
, and Cash
objects.
Abstract methods defined by the superclasses in a heterogeneous hierarchy must specify the Abstract
attribute. Defining an abstract method in a superclass ensures that concrete subclasses have an implementation for that exact method name. Use these methods element-wise so that each object calls its own method.
The getCurrentValue
method is an example of an abstract method that is implemented by each subclass to get the current value of each asset.
Each type of subclass object calculates its current value in a different way. If you add another category of asset by adding another subclass to the hierarchy, this class must implement its own version of a getCurrentValue
method. Because all subclasses implement a getCurrentValue
method, the pie
and makeReport
methods work with newly added subclasses.
For more information on the Sealed
and Abstract
method attributes, see Method Attributes.
Assets Class Code
The Assets
class and other classes in the hierarchy are
contained in a namespace called financial
.
classdef Assets < matlab.mixin.Heterogeneous % file: +financial/@Assets/Assets.m properties Description char = 'Assets' end properties (Abstract, SetAccess = private) Type end methods (Abstract) % Not implemented by Assets class value = getCurrentValue(obj) end methods (Static, Sealed, Access = protected) function defaultObject = getDefaultScalarElement defaultObject = financial.DefaultAsset; end end methods (Sealed) % Implemented in separate files % +financial/@Assets/pie.m % +financial/@Assets/makeReport.m pie(assetArray) makeReport(assetArray) end end
For code listings for pie
and makeReport
, see Operating on an Assets Array.
Stocks Class
The Stocks
class represents a specific type of financial asset. It is a concrete class that implements the abstract members defined by the Assets
class, and defines class properties and methods specific to this type of asset.
Properties
The Stocks
class defines these properties:
NumShares
— The number of shares held for this asset.Symbol
— The ticker symbol corresponding to this stock.Type
—Stocks
class implementation of the abstract property defined by theAssets
class. This concrete property must use the same attributes as the abstract version (that is,SetAccess private
).SharePrice
— Dependent property for the price per share. Theget.SharePrice
method obtains the current share price from web services when this property is queried.
Methods
The Stocks class defines these methods:
Stocks
— The constructor assigns property values and supports a default constructor called with no input arguments.getCurrentValue
— This method is theStocks
class implementation of the abstract method defined by theAssets
class. It returns the current value of this asset.get.SharePrice
— The property get method for the dependentSharePrice
property returns the current share price of this stock. For information on how to access web services from MATLAB, see thewebread
function.
Stocks Class Code
classdef Stocks < financial.Assets properties NumShares double = 0 Symbol string end properties (SetAccess = private) Type = "Stocks" end properties (Dependent) SharePrice double end methods function sk = Stocks(description,numshares,symbol) if nargin == 0 description = ''; numshares = 0; symbol = ''; end sk.Description = description; sk.NumShares = numshares; sk.Symbol = symbol; end function value = getCurrentValue(sk) value = sk.NumShares*sk.SharePrice; end function pps = get.SharePrice(sk) % Implement web access to obtain % Current price per share % Returning dummy value pps = 1; end end end
Bonds Class
The Bonds
class represents a specific type of financial asset. It is a concrete class that implements the abstract members defined by the Assets
class and defines class properties and methods specific to this type of asset.
Properties
The Bonds
class defines these properties:
FaceValue
— Face value of the bond.Yield
— Annual interest rate of the bond.Type
—Bonds
class implementation of the abstract property defined by theAssets
class. This concrete property must use the same attributes as the abstract version (that is,SetAccess private
).CurrentYield
— Dependent property for the current yield, Theget.CurrentYield
property get method obtains the value from web services.
Methods
The Bonds
class defines these methods:
Bonds
— The constructor assigns property values and supports a default constructor called with no input arguments.getCurrentVlaue
— This method is theBonds
class implementation of the abstract method defined by theAssets
class. It returns the current value of this asset.get.CurrentYield
— The property get method for the dependentCurrentYield
property returns the current yield on this bond. For information on how to access web serviced from MATLAB, see thewebread
function.
Bonds Class Code
classdef Bonds < financial.Assets properties FaceValue double = 0 Yield double = 0 end properties (SetAccess = private) Type = "Bonds" end properties (Dependent) CurrentYield double end methods function b = Bonds(description,facevalue,yield) if nargin == 0 description = ''; facevalue = 0; yield = 0; end b.Description = description; b.FaceValue = facevalue; b.Yield = yield; end function mv = getCurrentValue(b) y = b.Yield; cy = b.CurrentYield; if cy <= 0 || y <= 0 mv = b.FaceValue; else mv = b.FaceValue*y/cy; end end function r = get.CurrentYield(b) % Implement web access to obtain % Current yield for this bond % Returning dummy value r = 0.24; end end end
Cash Class
The Cash
class represents a specific type of financial asset. It is a concrete class that implements the abstract members defined by the Assets
class and defines class properties and methods specific to this type of asset.
Properties
The Cash
class defines these properties:
Amount
— The amount of cash held in this asset.Type
—Cash
class implementation of the abstract property defined by theAssets
class. This concrete property must use the same attributes as the abstract version (that is,SetAccess private
).
Methods
The Cash
class defines these methods:
Cash
— The constructor assigns property values and supports a default constructor called with no input arguments.getCurrentValue
— This method is theCash
class implementation of the abstract method defined by theAssets
class. It returns the current value of this asset.save
— This method adds the specified amount of cash to the existing amount and returns a newCash
object with the current amount.spend
— This method deducts the specified amount from the current amount and returns a newCash
object with the current amount.
Cash Class Code
classdef Cash < financial.Assets properties Amount double = 0 end properties (SetAccess = private) Type = "Cash" end methods function c = Cash(description,amount) if nargin == 0 description = ''; amount = 0; end c.Description = description; c.Amount = amount; end function value = getCurrentValue(c) value = c.Amount; end function c = save(c,amount) newValue = c.Amount + amount; c.Amount = newValue; end function c = spend(c,amount) newValue = c.Amount - amount; if newValue < 0 c.Amount = 0; disp('Your balance is $0.00') else c.Amount = newValue; end end end end
Default Object
The design of this class hierarchy uses an abstract root class (Assets
). Therefore, the Assets
class must specify a concrete class to use as a default object by overriding getDefaultScalarElement
. In this case, options include:
Use one of the existing concrete classes for the default object.
Define a concrete class in the hierarchy to use for the default object.
This implementation adds the DefaultAsset
class to the hierarchy as a subclass of the Assets
class. MATLAB creates objects of this class when:
Creating arrays using indexed assignment with gaps in index numbers
Loading heterogeneous arrays from MAT-files when MATLAB cannot find the class of an array element.
This diagram shows the addition of the DefaultAsset
class:
DefaultAsset Class Code
classdef DefaultAsset < financial.Assets % file: +financial/@DefaultAsset/DefaultAsset.m properties (SetAccess = private) Type = "DefaultAsset" end methods function obj = DefaultAsset obj.Description = 'Place holder'; end function value = getCurrentValue(~) value = 0; end end end
Operating on an Assets Array
The Assets
class defines these methods to operate on heterogeneous arrays of asset objects:
pie
— Creates a pie chart showing the mix of asset types in the array.makeReport
— Uses the MATLABtable
object to display a table of asset information.
To operate on a heterogeneous array, a method must be defined for the class of the heterogeneous array and must be sealed. In this case, the class of heterogeneous arrays is always the Assets
class. MATLAB does not use the class of the individual elements of the heterogeneous array when dispatching to methods.
makeReport Method Code
The Assets
class makeReport
method builds a table using the common properties and getCurrentValue
method for each object in the array.
function makeReport(obj) numMembers = length(obj); descs = cell(1,numMembers); types(numMembers) = ""; values(numMembers) = 0; for k = 1:numMembers descs{k} = obj(k).Description; types(k) = obj(k).Type; values(k) = obj(k).getCurrentValue; end t = table; t.Description = descs'; t.Type = types'; t.Value = values'; disp(t) end
The Assets
class pie
method calls the getCurrentValue
method element-wise on objects in the array to obtain the data for the pie chart.
pie Method Code
function pie(assetArray) stockAmt = 0; bondAmt = 0; cashAmt = 0; for k=1:length(assetArray) if isa(assetArray(k),'financial.Stocks') stockAmt = stockAmt + assetArray(k).getCurrentValue; elseif isa(assetArray(k),'financial.Bonds') bondAmt = bondAmt + assetArray(k).getCurrentValue; elseif isa(assetArray(k),'financial.Cash') cashAmt = cashAmt + assetArray(k).getCurrentValue; end end k = 1; if stockAmt ~= 0 label(k) = {'Stocks'}; pieVector(k) = stockAmt; k = k +1; end if bondAmt ~= 0 label(k) = {'Bonds'}; pieVector(k) = bondAmt; k = k +1; end if cashAmt ~= 0 label(k) = {'Cash'}; pieVector(k) = cashAmt; end pie(pieVector,label) tv = stockAmt + bondAmt + cashAmt; stg = {['Total Value of Assets: $',num2str(tv,'%0.2f')]}; title(stg,'FontSize',10) end
Folders and Files
Asset
class:
+financial/@Assets/Assets.m +financial/@Assets/makeReport.m +financial/@Assets/pie.m
Stocks
class:
+financial/@Stocks/Stocks.m
Bonds
class:
+financial/@Bonds/Bonds.m
Cash
class:
+financial/@Cash/Cash.m
DefaultAsset
class:
+financial/@DefaultAsset/DefaultAsset.m
Create an Assets Array
These statements create a heterogeneous array by concatenating the Stocks
, Bonds
, and Cash
objects. Calling the makeReport
and pie
methods creates the output shown.
s = financial.Stocks('Acme Motor Company',100,string('A')); b = financial.Bonds('3 Month T',700,0.3); c(1) = financial.Cash('Bank Account',500); c(2) = financial.Cash('Gold',500); assetArray = [s,b,c]; makeReport(assetArray) pie(assetArray)
Description Type Value ______________________ _______ ______ {'Acme Motor Company'} "Stock" 1232.5 {'3 Month T' } "Bonds" 875 {'Bank Account' } "Cash" 500 {'Gold' } "Cash" 500