<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <!-- Created by GNU Texinfo 6.5, http://www.gnu.org/software/texinfo/ --> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Inheritance and Aggregation (GNU Octave (version 5.1.0))</title> <meta name="description" content="Inheritance and Aggregation (GNU Octave (version 5.1.0))"> <meta name="keywords" content="Inheritance and Aggregation (GNU Octave (version 5.1.0))"> <meta name="resource-type" content="document"> <meta name="distribution" content="global"> <meta name="Generator" content="makeinfo"> <link href="index.html#Top" rel="start" title="Top"> <link href="Concept-Index.html#Concept-Index" rel="index" title="Concept Index"> <link href="index.html#SEC_Contents" rel="contents" title="Table of Contents"> <link href="Object-Oriented-Programming.html#Object-Oriented-Programming" rel="up" title="Object Oriented Programming"> <link href="classdef-Classes.html#classdef-Classes" rel="next" title="classdef Classes"> <link href="Precedence-of-Objects.html#Precedence-of-Objects" rel="prev" title="Precedence of Objects"> <style type="text/css"> <!-- a.summary-letter {text-decoration: none} blockquote.indentedblock {margin-right: 0em} blockquote.smallindentedblock {margin-right: 0em; font-size: smaller} blockquote.smallquotation {font-size: smaller} div.display {margin-left: 3.2em} div.example {margin-left: 3.2em} div.lisp {margin-left: 3.2em} div.smalldisplay {margin-left: 3.2em} div.smallexample {margin-left: 3.2em} div.smalllisp {margin-left: 3.2em} kbd {font-style: oblique} pre.display {font-family: inherit} pre.format {font-family: inherit} pre.menu-comment {font-family: serif} pre.menu-preformatted {font-family: serif} pre.smalldisplay {font-family: inherit; font-size: smaller} pre.smallexample {font-size: smaller} pre.smallformat {font-family: inherit; font-size: smaller} pre.smalllisp {font-size: smaller} span.nolinebreak {white-space: nowrap} span.roman {font-family: initial; font-weight: normal} span.sansserif {font-family: sans-serif; font-weight: normal} ul.no-bullet {list-style: none} --> </style> <link rel="stylesheet" type="text/css" href="octave.css"> </head> <body lang="en"> <a name="Inheritance-and-Aggregation"></a> <div class="header"> <p> Next: <a href="classdef-Classes.html#classdef-Classes" accesskey="n" rel="next">classdef Classes</a>, Previous: <a href="Overloading-Objects.html#Overloading-Objects" accesskey="p" rel="prev">Overloading Objects</a>, Up: <a href="Object-Oriented-Programming.html#Object-Oriented-Programming" accesskey="u" rel="up">Object Oriented Programming</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p> </div> <hr> <a name="Inheritance-and-Aggregation-1"></a> <h3 class="section">34.5 Inheritance and Aggregation</h3> <p>Using classes to build new classes is supported by Octave through the use of both inheritance and aggregation. </p> <p>Class inheritance is provided by Octave using the <code>class</code> function in the class constructor. As in the case of the polynomial class, the Octave programmer will create a structure that contains the data fields required by the class, and then call the <code>class</code> function to indicate that an object is to be created from the structure. Creating a child of an existing object is done by creating an object of the parent class and providing that object as the third argument of the class function. </p> <p>This is most easily demonstrated by example. Suppose the programmer needs a FIR filter, i.e., a filter with a numerator polynomial but a denominator of 1. In traditional Octave programming this would be performed as follows. </p> <div class="example"> <pre class="example">>> x = [some data vector]; >> n = [some coefficient vector]; >> y = filter (n, 1, x); </pre></div> <p>The equivalent behavior can be implemented as a class <code>@FIRfilter</code>. The constructor for this class is the file <samp>FIRfilter.m</samp> in the class directory <samp>@FIRfilter</samp>. </p> <div class="example"> <pre class="verbatim">## -*- texinfo -*- ## @deftypefn {} {} FIRfilter () ## @deftypefnx {} {} FIRfilter (@var{p}) ## Create a FIR filter with polynomial @var{p} as coefficient vector. ## @end deftypefn function f = FIRfilter (p) if (nargin > 1) print_usage (); endif if (nargin == 0) p = @polynomial ([1]); elseif (! isa (p, "polynomial")) error ("@FIRfilter: P must be a polynomial object"); endif f.polynomial = []; f = class (f, "FIRfilter", p); endfunction </pre></div> <p>As before, the leading comments provide documentation for the class constructor. This constructor is very similar to the polynomial class constructor, except that a polynomial object is passed as the third argument to the <code>class</code> function, telling Octave that the <code>FIRfilter</code> class will be derived from the polynomial class. The FIR filter class itself does not have any data fields, but it must provide a struct to the <code>class</code> function. Given that the <code>@polynomial</code> constructor will add an element named <var>polynomial</var> to the object struct, the <code>@FIRfilter</code> just initializes a struct with a dummy field <var>polynomial</var> which will later be overwritten. </p> <p>Note that the sample code always provides for the case in which no arguments are supplied. This is important because Octave will call a constructor with no arguments when loading objects from saved files in order to determine the inheritance structure. </p> <p>A class may be a child of more than one class (see <a href="Built_002din-Data-Types.html#XREFclass">class</a>), and inheritance may be nested. There is no limitation to the number of parents or the level of nesting other than memory or other physical issues. </p> <p>For the <code>FIRfilter</code> class, more control about the object display is desired. Therefore, the <code>display</code> method rather than the <code>disp</code> method is overloaded (see <a href="Class-Methods.html#Class-Methods">Class Methods</a>). A simple example might be </p> <div class="example"> <pre class="verbatim">function display (f) printf ("%s.polynomial", inputname (1)); disp (f.polynomial); endfunction </pre></div> <p>Note that the <code>FIRfilter</code>’s display method relies on the <code>disp</code> method from the <code>polynomial</code> class to actually display the filter coefficients. Furthermore, note that in the <code>display</code> method it makes sense to start the method with the line <code><code>printf ("%s =", inputname (1))</code></code> to be consistent with the rest of Octave which prints the variable name to be displayed followed by the value. In general it is not recommended to overload the <code>display</code> function. </p> <a name="XREFdisplay"></a><dl> <dt><a name="index-display"></a><em></em> <strong>display</strong> <em>(<var>obj</var>)</em></dt> <dd><p>Display the contents of the object <var>obj</var> prepended by its name. </p> <p>The Octave interpreter calls the <code>display</code> function whenever it needs to present a class on-screen. Typically, this would be a statement which does not end in a semicolon to suppress output. For example: </p> <div class="example"> <pre class="example">myclass (…) </pre></div> <p>Or: </p> <div class="example"> <pre class="example">myobj = myclass (…) </pre></div> <p>In general, user-defined classes should overload the <code>disp</code> method to avoid the default output: </p> <div class="example"> <pre class="example">myobj = myclass (…) ⇒ myobj = <class myclass> </pre></div> <p>When overloading the <code>display</code> method instead, one has to take care of properly displaying the object’s name. This can be done by using the <code>inputname</code> function. </p> <p><strong>See also:</strong> <a href="Terminal-Output.html#XREFdisp">disp</a>, <a href="Built_002din-Data-Types.html#XREFclass">class</a>, <a href="Defining-Indexing-And-Indexed-Assignment.html#XREFsubsref">subsref</a>, <a href="Defining-Indexing-And-Indexed-Assignment.html#XREFsubsasgn">subsasgn</a>. </p></dd></dl> <p>Once a constructor and display method exist, it is possible to create an instance of the class. It is also possible to check the class type and examine the underlying structure. </p> <div class="example"> <pre class="example">octave:1> f = FIRfilter (polynomial ([1 1 1]/3)) f.polynomial = 0.33333 + 0.33333 * X + 0.33333 * X ^ 2 octave:2> class (f) ans = FIRfilter octave:3> isa (f, "FIRfilter") ans = 1 octave:4> isa (f, "polynomial") ans = 1 octave:5> struct (f) ans = scalar structure containing the fields: polynomial = 0.33333 + 0.33333 * X + 0.33333 * X ^ 2 </pre></div> <p>The only thing remaining to make this class usable is a method for processing data. But before that, it is usually desirable to also have a way of changing the data stored in a class. Since the fields in the underlying struct are private by default, it is necessary to provide a mechanism to access the fields. The <code>subsref</code> method may be used for both tasks. </p> <div class="example"> <pre class="verbatim">function r = subsref (f, x) switch (x.type) case "()" n = f.polynomial; r = filter (n.poly, 1, x.subs{1}); case "." fld = x.subs; if (! strcmp (fld, "polynomial")) error ('@FIRfilter/subsref: invalid property "%s"', fld); endif r = f.polynomial; otherwise error ("@FIRfilter/subsref: invalid subscript type for FIR filter"); endswitch endfunction </pre></div> <p>The <code>"()"</code> case allows us to filter data using the polynomial provided to the constructor. </p> <div class="example"> <pre class="example">octave:2> f = FIRfilter (polynomial ([1 1 1]/3)); octave:3> x = ones (5,1); octave:4> y = f(x) y = 0.33333 0.66667 1.00000 1.00000 1.00000 </pre></div> <p>The <code>"."</code> case allows us to view the contents of the polynomial field. </p> <div class="example"> <pre class="example">octave:1> f = FIRfilter (polynomial ([1 1 1]/3)); octave:2> f.polynomial ans = 0.33333 + 0.33333 * X + 0.33333 * X ^ 2 </pre></div> <p>In order to change the contents of the object a <code>subsasgn</code> method is needed. For example, the following code makes the polynomial field publicly writable </p> <div class="example"> <pre class="verbatim">function fout = subsasgn (f, index, val) switch (index.type) case "." fld = index.subs; if (! strcmp (fld, "polynomial")) error ('@FIRfilter/subsasgn: invalid property "%s"', fld); endif fout = f; fout.polynomial = val; otherwise error ("@FIRfilter/subsasgn: Invalid index type") endswitch endfunction </pre></div> <p>so that </p> <div class="example"> <pre class="example">octave:1> f = FIRfilter (); octave:2> f.polynomial = polynomial ([1 2 3]) f.polynomial = 1 + 2 * X + 3 * X ^ 2 </pre></div> <p>Defining the FIRfilter<!-- /@w --> class as a child of the polynomial class implies that a FIRfilter<!-- /@w --> object may be used any place that a polynomial object may be used. This is not a normal use of a filter. It may be a more sensible design approach to use aggregation rather than inheritance. In this case, the polynomial is simply a field in the class structure. A class constructor for the aggregation case might be </p> <div class="example"> <pre class="verbatim">## -*- texinfo -*- ## @deftypefn {} {} FIRfilter () ## @deftypefnx {} {} FIRfilter (@var{p}) ## Create a FIR filter with polynomial @var{p} as coefficient vector. ## @end deftypefn function f = FIRfilter (p) if (nargin > 1) print_usage (); endif if (nargin == 0) f.polynomial = @polynomial ([1]); else if (! isa (p, "polynomial")) error ("@FIRfilter: P must be a polynomial object"); endif f.polynomial = p; endif f = class (f, "FIRfilter"); endfunction </pre></div> <p>For this example only the constructor needs changing, and all other class methods stay the same. </p> <hr> <div class="header"> <p> Next: <a href="classdef-Classes.html#classdef-Classes" accesskey="n" rel="next">classdef Classes</a>, Previous: <a href="Overloading-Objects.html#Overloading-Objects" accesskey="p" rel="prev">Overloading Objects</a>, Up: <a href="Object-Oriented-Programming.html#Object-Oriented-Programming" accesskey="u" rel="up">Object Oriented Programming</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p> </div> </body> </html>