# HG changeset patch
# User Markus Mützel <markus.muetzel@gmx.de>
# Date 1490987819 -7200
#      Fri Mar 31 21:16:59 2017 +0200
# Node ID bcf6b2eb25473bd201a2362f40572cfc32fb3a13
# Parent  f7460c045841dc4cf67e213ed1d953476e3a2142
oop.txi: Add documentation for classdef classes (bug #44590).

diff -r f7460c045841 -r bcf6b2eb2547 doc/interpreter/oop.txi
--- a/doc/interpreter/oop.txi	Thu Mar 30 11:08:17 2017 -0700
+++ b/doc/interpreter/oop.txi	Fri Mar 31 21:16:59 2017 +0200
@@ -4,14 +4,14 @@
 @c This file is part of Octave.
 @c
 @c Octave is free software; you can redistribute it and/or modify it
-@c under the terms of the GNU General Public License as published by
-@c the Free Software Foundation; either version 3 of the License, or
-@c (at your option) any later version.
+@c under the terms of the GNU General Public License as published by the
+@c Free Software Foundation; either version 3 of the License, or (at
+@c your option) any later version.
 @c
-@c Octave is distributed in the hope that it will be useful, but
-@c WITHOUT ANY WARRANTY; without even the implied warranty of
-@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-@c GNU General Public License for more details.
+@c Octave is distributed in the hope that it will be useful, but WITHOUT
+@c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+@c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+@c for more details.
 @c
 @c You should have received a copy of the GNU General Public License
 @c along with Octave; see the file COPYING.  If not, see
@@ -41,6 +41,7 @@
 * Indexing Objects::
 * Overloading Objects::
 * Inheritance and Aggregation::
+* New @code{classdef} Style Classes::
 @end menu
 
 @node Creating a Class
@@ -752,3 +753,405 @@
 
 For this example only the constructor needs changing, and all other class
 methods stay the same.
+
+@node New @code{classdef} Style Classes
+@section New @code{classdef} Style Classes
+
+Octave also has limited support for the new @code{classdef} style classes.  
+
+@menu
+* Main Differences to Old Style Classes::
+* Creating a @code{classdef} Class::
+* @code{classdef} Properties::
+* @code{classdef} Methods::
+* Enheriting::
+* Value Classes vs. Handle Classes::
+@end menu
+
+@node Main Differences to Old Style Classes
+@subsection Main Differences to Old Style Classes
+
+In contrast to the old style classes, @code{classdef} classes allow to set
+access rights for properties (public/private/protected) and methods (private).
+It also allows for methods to be defined static.  Only the new style classes
+can be implemented either as value classes or handle classes.  As oppossed to
+old style classes, @code{classdef} classes can (optionally) be defined in one
+single file.
+
+Other features like immutable properties, inheritance from built-in classes,
+enumeration classes, or @code{GetAccess} restrictions for properties are not yet
+working in Octave but will probably be included in future versions of Octave.
+
+@node Creating a @code{classdef} Class
+@subsection Creating a @code{classdef} Class
+
+For simplicity, the implementation of a @code{classdef} class is shown with the
+same custom class as chosen in section @pxref{Creating a Class}.
+
+A very basic class is defined by the following code in a file
+@file{polynomial2.m}:
+
+@example
+@group
+classdef polynomial2
+  properties
+  endproperties
+
+  methods
+  endmethods
+endclassdef
+@end group
+@end example
+
+The @code{properties}-@code{endproperties} block as well as the
+@code{methods}-@code{endmethods} block are optional in this case and can be
+used to define properties and methods of the class.
+
+Executing @code{p = polynomial2} creates an object of the class
+@code{polynomial2}.
+
+In contrast to old style classes, all properties of the class must be declared
+in on one or more @code{properties} blocks:
+
+@example
+@group
+classdef polynomial2
+  properties
+    poly = [0];
+  endproperties
+
+  methods
+  endmethods
+endclassdef
+@end group
+@end example
+
+The definition of a default value for each property is optional and can be
+omitted.  The default initial value for each property is @qcode{[]}.  The
+constructor of the class is declared in the @code{methods} block of the
+@code{classdef} file and must have the same name as the class and exactly one
+output argument which is an object of its class:
+
+@example
+@group
+classdef polynomial2
+  properties
+    poly = [0];
+  endproperties
+
+  methods
+    function p = polynomial2 (a)
+      if nargin > 0
+        if (strcmp (class (a), "polynomial2"))
+          p = a;
+        elseif (isreal (a) && isvector (a))
+          p.poly = a(:).'; # force row vector
+        else
+          error ("@@polynomial: A must be a real vector");
+        endif
+      endif
+    endfunction
+
+  endmethods
+endclassdef
+@end group
+@end example
+
+This constructor can be called to create an object of class @qcode{polynomial2}:
+@example
+p = polynomial ([1, 0, 1]);
+@end example
+
+Methods can be defined in the @qcode{methods} block of the same file.
+Alternatively, a folder of the same name as the class prepended with "@@" can
+be used to store the main @qcode{classdef} file as well as files with all
+methods.
+
+@node @code{classdef} Properties
+@subsection @code{classdef} Properties
+
+As mentioned above, all properties of the class must be defined in one or more
+@qcode{properties} blocks.  Additionally, @qcode{SetAccess} restrictions can be
+defined:
+
+@example
+@group
+classdef polynomial2
+  ...
+  properties (SetAccess = @var{mode})
+    ...
+  endproperties
+endclassdef
+@end group
+@end example
+
+@var{mode} can be one of the following:
+
+@table @asis
+@item @qcode{public}
+The properties can be accessed from everywhere.
+
+@item @qcode{private}
+The properties can only be accessed from methods of that class (not including
+subclasses).
+
+@item @qcode{protected}
+The properties can only be accessed from methods of that class and subclasses
+enheriting from that class.
+@end table
+
+Properties can also be defined as @qcode{Constant} in which case they can be
+initialized only once in the @qcode{properties} block:
+
+@example
+@group
+classdef polynomial2
+  ...
+  properties (Constant = true)
+    ...
+  endproperties
+endclassdef
+@end group
+@end example
+
+By default, properties are not constant.
+
+@node @code{classdef} Methods
+@subsection @code{classdef} Methods
+
+Own methods can be added to the class, or built-in or enherited methods can be
+overloaded (if the permissions for these methods allow it).  The polynomial2
+class can be extended to overload the @code{disp} function to tell Octave how
+objects of this class should be displayed:
+
+@example
+classdef polynomial2
+  properties
+    poly = [0];
+  endproperties
+
+  methods
+    function p = polynomial2 (a)
+      if nargin > 0
+        if (strcmp (class (a), "polynomial2"))
+          p = a;
+        elseif (isreal (a) && isvector (a))
+          p.poly = a(:).'; # force row vector
+        else
+          error ("@@polynomial2: A must be a real vector");
+        endif
+      endif
+    endfunction
+
+    function disp (p)
+        first = true;
+        for i = 1 : length (p.poly);
+          if (p.poly(i) != 0)
+            if (first)
+              first = false;
+            elseif (p.poly(i) > 0 || isnan (p.poly(i)))
+              printf (" +");
+            endif
+            if (p.poly(i) < 0)
+              printf (" -");
+            endif
+            if (i == 1)
+              printf (" %.5g", abs (p.poly(i)));
+            elseif (abs (p.poly(i)) != 1)
+              printf (" %.5g *", abs (p.poly(i)));
+            endif
+            if (i > 1)
+              printf (" X");
+            endif
+            if (i > 2)
+              printf (" ^ %d", i - 1);
+            endif
+          endif
+        endfor
+
+        if (first)
+          printf (" 0");
+        endif
+
+    endfunction
+
+  endmethods
+endclassdef
+@end example
+
+The first argument in a method definition is always the object that it is
+called from.  Class methods can either be called by passing the object as the
+first argument to that method
+@example
+disp (p);
+@end example
+or by calling the object followed by a dot ("@qcode{.}") and the method name
+with the subsequent arguments:
+@example
+p.disp ();
+@end example
+
+Uniquely to classdef classes, methods can be declared as private.  This is done
+with the following syntax:
+
+@example
+@group
+classdef polynomial2
+  ...
+  methods (Access = private)
+    ...
+  endmethods
+endclassdef
+@end group
+@end example
+
+Methods declared as private can only be accessed from methods of that same
+class (not including subclasses).  Private methods cannot be overloaded from
+subclasses.  The default access for methods is @code{public}.
+
+Methods can also be declared as static:
+
+@example
+@group
+classdef polynomial2
+  ...
+  methods (Static = true)
+    function my_static_method ()
+      nargin
+      disp ('Hello');
+    endfunction
+  endmethods
+endclassdef
+@end group
+@end example
+
+Static methods can be executed without initializing an object of that class by
+appending the name of the method with a dot ("@qcode{.}") to the name of the
+class.  In contrast to non-static methods, the object is not passed as first
+argument even if called using an object.
+
+@example
+@group
+>> polynomial2.my_static_method ()
+ans = 0
+Hello
+>> p = polynomial2([1 0 1])
+p =
+
+ 1 + X ^ 2
+>> p.my_static_method ()
+ans = 0
+Hello
+@end group
+@end example
+
+@node Enheriting
+@subsection Enheriting
+
+Classes can enherit from other classes.  In this case all properties and
+methods of the super-class are enherited to the sub-class.  Use this syntax to
+enherit from other classes:
+
+@example
+@group
+classdef better_polynomial < polynomial2
+  ...
+endclassdef
+@end group
+@end example
+
+@node Value Classes vs. Handle Classes
+@subsection Value Classes vs. Handle Classes
+
+There are two intrinsically different classdef classes.  They differ when it
+comes to assigning an object to another variable.
+
+Given the following value class:
+@example
+@group
+classdef value_class
+  properties
+    prop1
+  endproperties
+  methods
+    function obj = set_prop1(obj, val)
+      obj.prop1 = val;
+    endfunction
+  endmethods
+endclassdef
+@end group
+@end example
+
+Assigning an object of that class to another variable essentially duplicates
+the object:
+@example
+@group
+>> a = value_class;
+>> a.prop1 = 1;
+>> b = a;
+>> b.prop1 = 2;
+>> b.prop1
+ans =  2
+>> a.prop1
+ans =  1
+@end group
+@end example
+
+But that also means that you might have to assign the output of a method that
+changes properties back to the object manually:
+@example
+@group
+>> a = value_class;
+>> a.prop1 = 1;
+>> a.set_prop1 (3);
+ans =
+
+<object value_class>
+
+>> ans.prop1
+ans =  3
+>> a.prop1
+ans =  1
+@end group
+@end example
+
+Contrarily, handle classes behave differently:
+@example
+@group
+classdef handle_class < handle
+  properties
+    prop1
+  endproperties
+  methods
+    function set_prop1(obj, val)
+      obj.prop1 = val;
+    endfunction
+  endmethods
+endclassdef
+@end group
+@end example
+
+In the following example, @qcode{a} and @qcode{b} act as if they represent the
+same instance of the class:
+@example
+@group
+>> a = handle_class;
+>> a.prop1 = 1;
+>> b = a;
+>> b.prop1 = 2;
+>> b.prop1
+ans =  2
+>> a.prop1
+ans =  2
+@end group
+@end example
+
+Properties that are changed in a method of that handle class are changed in
+that object instantly:
+@example
+@group
+>> a.set_prop1 (3);
+>> a.prop1
+ans =  3
+@end group
+@end example
