Classes with classdef: the Basics

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The reference material consulted while preparing these pages is listed in the section bibliography.

Written against MATLAB R2026b. The classdef keyword is the way to define classes in current MATLAB; the section index (MATLAB) holds the version baseline used on every page. Octave 11.3.0 runs a simplified version of the first class on this page (see "Trying the class in Octave"), and every other listing is labelled "not run here". This page introduces the building blocks; the next pages go deeper: Value and Handle Classes, Properties and Methods, Inheritance and Abstract Classes, Events and Listeners, Enumerations, Namespaces and Class Folders and Object Arrays, Customization and Introspection.

Why write classes

The documentation contrasts two designs. In procedural programs the design focuses on the steps that must run; data lives in variables or structure fields and operations are functions that take the data as arguments. In object-oriented programs the design focuses on the components of the system: you identify them, look for what they share, classify them by similarities and differences, and then define classes that describe them. A class describes a set of objects with common characteristics; an object is one instance of it. The values held in an object’s properties make one object differ from another; the functions the class defines, its methods, implement the behaviour all objects of the class share.

The documentation does not ask you to use classes everywhere. Simple tasks can be simple functions. As tasks grow, functions grow, and passing data from function to function becomes difficult and error prone; that is the point where it suggests considering a move to objects. Its heuristic for finding classes is to treat the nouns of the problem statement as objects and the verbs as operations.

According to the same page, objects offer several things that structures and cell arrays cannot:

  • constrain the values that can be assigned to a property;

  • calculate a property value only when it is queried;

  • broadcast notices when a property is queried or changed;

  • restrict access to properties and methods (public, protected or private);

  • hide implementation details behind an interface, so the designer can change the internals without changing the callers;

  • overload existing functions and operators, such as eq or plus, for the new type.

In the heatflow scenario (The heatflow scenario) the noun "plate" is a natural class: it owns a temperature matrix and the grid constants that give the matrix its meaning, and "find the hottest point" is one of its verbs. Earlier pages kept the same data in a structure (Structures); the class adds validation and a place to attach behaviour.

The classdef file and its blocks

A class is defined in a file named after the class, with extension .m, that starts with the classdef keyword. Only blank lines and comments may precede classdef. The general form is:

classdef (ClassAttributes) ClassName < SuperclassName1 & SuperclassName2
    properties (PropertyAttributes)
        PropertyName size class {validators} = DefaultValue
    end
    methods (MethodAttributes)
        function obj = MethodName(obj,arg1,...)
            ...
        end
    end
    events (EventAttributes)
        EventName
    end
    enumeration
        MemberName (arguments)
    end
end

Not run here (syntax summary built from the classdef reference and Components of a Class pages). The class name must start with a letter and may contain letters, numbers and underscores. Superclasses are separated by &. Within the classdef block, the keywords properties, methods, events and enumeration are keywords only there; everywhere else they are ordinary identifiers.

Block What it holds

properties

Property names, their attributes, optional size, class and validators, and default values. Use one block per distinct set of attributes.

methods

Method declarations and bodies, including the constructor. One block per distinct set of method attributes.

events

Event names that the class declares, with event attributes such as ListenAccess. See Events and Listeners.

enumeration

The members of an enumeration class, optionally with constructor arguments. See Enumerations.

Attributes

Attributes modify the behaviour of the class or of every component in the block that carries them. They go in parentheses after the keyword, separated by commas: properties (SetAccess = private, Hidden = true). Attributes that take a logical value can be written by name alone (methods (Static) equals methods (Static = true)) and negated with ~ (methods (~Static)); the default of every logical attribute is false. Specify a given attribute only once per block. To give properties different attribute settings, use several properties blocks. The lists of supported attributes are on the class, property, method and event attribute pages, treated in Properties and Methods.

The first class: heatflow.Plate

The scenario uses a class Plate that lives in a namespace called heatflow, so its full name is heatflow.Plate. It stores the grid size, the cell spacing, the diffusivity and the temperature matrix, and offers one method. The file is +heatflow/Plate.m, where the leading + folder makes heatflow a namespace (full treatment in Namespaces and Class Folders).

% File: +heatflow/Plate.m   (not run here: uses property validation)
classdef Plate
    % Plate  A rectangular plate with a uniform grid and a temperature field.
    properties
        Nx (1,1) double {mustBePositive, mustBeInteger}
        Ny (1,1) double {mustBePositive, mustBeInteger}
        Dx (1,1) double {mustBePositive} = 1      % cell size
        Alpha (1,1) double {mustBePositive} = 1e-4 % diffusivity
        T double                                   % Ny-by-Nx temperature
    end
    methods
        function obj = Plate(nx,ny,dx,alpha)
            if nargin > 0
                obj.Nx = nx;
                obj.Ny = ny;
                obj.Dx = dx;
                obj.Alpha = alpha;
                obj.T = 20*ones(ny,nx);   % start at 20 degrees
            end
        end
        function m = maxTemperature(obj)
            m = max(obj.T,[],"all");
        end
    end
end

Reading it against the documentation:

  • Default values and validation. The syntax Name size class {validators} = Default declares an optional size, class and validator functions. They are checked on every assignment, including inside the constructor, and the documentation says default property values are set and validated before any assignments in the constructor runs. A property with a declared size and class but no default gets one that fits both: for (1,1) double that is 0, so a Plate created without arguments has Nx and Ny equal to 0, T empty (it declares no size, so the default is []) and the defaults of Dx and Alpha. Give an explicit default when 0 is not a sensible value, as the fuller Plate on Properties and Methods does.

  • The constructor. It has the same name as the class, returns the new object as its first output, and should be callable with no input arguments, which is why the body is guarded with if nargin > 0. The documentation gives the same rule: if you create a constructor, make sure it can be called with no inputs, because MATLAB can call it that way, for example when it builds object arrays.

  • No self. The object is an explicit first argument of maxTemperature. The documentation lists this as a difference from C++ and Java, where one object parameter is implicit.

  • Value class. Plate does not derive from handle, so it is a value class: copying a variable copies the data. That choice, and its alternative, are the subject of Value and Handle Classes.

  • Help text. The comment directly under classdef is the class help; see Help Text and Documenting Code.

Using it (not run here; the display layout is the one the documentation shows for a simple class, adapted to these properties):

p = heatflow.Plate(4,3,0.01,1.2e-4);
p.T(2,2) = 95;          % assign into a property with ordinary indexing
p.maxTemperature()      % returns 95

Constructors

Without a constructor, MATLAB supplies a default one. For a class with no superclass it takes no arguments and returns a scalar object. For a class with superclasses it passes the arguments it receives to the first declared superclass constructor and calls the other superclass constructors with none, so a subclass needs no constructor just to forward inputs.

Define a constructor when creating an object needs input arguments, initial state or superclass arguments computed by the subclass. The documentation divides its body into three parts:

Part What may happen there

Pre-initialization

Compute the arguments for superclass constructors; code that does not use the output object.

Object initialization

The call obj = obj@BaseClass(args{:}). It must come before any other reference to the object, cannot follow a return, and cannot be conditional: not in a loop, if, switch, try/catch or nested function.

Post-initialization

Anything, including assigning properties, calling methods and passing the object to functions.

The first output must be the object. A constructor that can run with no arguments is a requirement, as noted above. Inheritance details are on Inheritance and Abstract Classes.

How an object is displayed

Typing an object name without a semicolon shows the class name and the properties with their values. For the BasicClass example of the documentation the layout is:

a =
  BasicClass with properties:

    Value: 1.0472

That is the documentation’s output for its own class (MATLAB R2026b layout, not run here); heatflow.Plate shows the same pattern with its five properties. The display can be customized (disp, matlab.mixin.CustomDisplay), covered in Object Arrays, Customization and Introspection.

Calling methods: dot and function syntax

MATLAB supports two equivalent forms for a non-static method with one argument:

obj.methodName(arg)     % dot syntax
methodName(obj,arg)     % function syntax

The two are the same call; with dot syntax the object to the left of the dot is passed as the first argument, so you do not repeat it. For a value class the method returns the modified object, and you must assign it back (a = a.newDataSet([1 2 3 4]) in the documentation’s example), because the method received a copy. Rules worth knowing:

  • Dispatch with dot syntax. MATLAB calls the method defined by the class of the object to the left of the dot, and no other argument is considered.

  • Dispatch with function syntax and operators. By default the leftmost object selects the method (plus(a,b) and a + b call the plus method of the class of a), unless one class has been declared superior. Dispatch is not based on the signature as in C++ and Java.

  • Dynamic method names. obj.("methodName") calls a method by a string name; it does not work with function syntax.

  • Indexing into a result. A method result can be indexed directly, as in a.returnSummary.Median.

  • Method name collisions. A function with the same name in a path folder that is earlier on the path can change what methodName(obj) means; see Function Precedence and Name Resolution.

For heatflow.Plate, p.maxTemperature() and maxTemperature(p) return the same number. The empty parentheses after a method name that takes no further arguments are optional when calling with dot syntax; writing them makes it obvious that the name is a method rather than a property.

Where the class files live

The documentation distinguishes three kinds of folder:

Folder Rule Use it when

Path folder

On the MATLAB path; name does not begin with + or @. Each class is one file, ClassName.m, with every method inside it.

Several classes and functions can share one folder. This is the normal choice.

Class folder

Name is @ClassName; the folder is not on the path but its parent is. It holds ClassName.m and may hold one file per method. One class per class folder; every function file in the folder is a method.

You want a method in a separate file of its own.

Namespace folder

Name begins with +; it can hold classes, functions, class folders and further namespaces. The folder name becomes part of the class name.

You want fully qualified names such as heatflow.Plate.

A class folder can contain a private folder whose functions are visible only to the methods of that class; those functions are not methods and are called with function notation. Class precedence follows path order: the definition found first on the path wins, and a function with the same name as a class in a path folder wins if its folder is earlier on the path. The documentation states that as of R2025b MATLAB gives precedence by path position alone, where earlier releases always preferred a class in an @-folder; R2025a already warned about this. After a path change MATLAB updates class definitions as the page describes (the details differ for releases before R2024b).

Classes defined with function syntax

Before classdef existed, a class was defined by a constructor function in an @ClassName folder, using class(s,"ClassName") and one file per method. The release notes carry this notice, under "Functionality being removed or changed" in R2025a and again in R2026a, with the status "Still runs": "Support for defining classes using function syntax will be removed in a future release", with the instruction to replace function-based classes with classdef classes. Schema classes (schema.m) were announced for removal in R2025a (status "Warns") and the R2026a notes state that defining classes with schema.m is no longer supported. A related R2026b notice says that for function-syntax classes on Windows the names of the function and the class folder will in a future release have to match in case exactly.

Two corrections to a common assumption: the notice is not new in R2026a (it appears first in R2025a and is repeated in R2026a), and it announces a future removal, so code of this kind still runs in R2026b. No removal release is stated. New code should use classdef only; maintain old @folder classes only until you can port them.

MATLAB compared with other OO languages

The documentation page "Comparison of MATLAB and Other OO Languages" lists these differences from C++ and Java:

Topic In MATLAB

Public properties

Properties can present a public interface that is separate from storage: set.Name and get.Name methods run automatically on assignment and query, and the Access attributes give public, protected or private access.

Implicit parameters

None. The object is always an explicit parameter of the method.

Dispatch

Not by method signature. The leftmost object of equal precedence selects the method; a superior class wins whatever its position.

Calling a superclass method

method@superclass(obj,...), where C++ writes superclass::method and Java super.method.

Templates, generics, overloading

No templates or generics (MATLAB is weakly typed, so a class can handle different types), and no overloading by signature under one name.

Static data

No static properties. Constant properties act like public final static fields in Java. For mutable shared data, the documentation recommends avoiding static data and suggests persistent variables in private or protected methods or local functions.

Object modification

Everything is passed by value. For a value class a function changes only its copy; for a handle class the copy of the handle refers to the same object. A handle is itself passed by value, so assigning a new object to the handle variable inside a function does not affect the caller.

The reason given for having no static properties is name resolution: variables take precedence over classes, so A.B = C must always create a structure variable A, and a class property reading A.B would break that rule and old code.

The heatflow classes at a glance

The scenario uses three classes, all in the heatflow namespace. Plate is a value class, Simulation a handle class that owns a plate and advances it in time, and BoundaryKind is an enumeration of boundary conditions. The diagram shows the planned design; Simulation and BoundaryKind are built on the pages that follow.

classDiagram class Plate { <<value>> +Nx +Ny +Dx +Alpha +T +Plate(nx, ny, dx, alpha) +maxTemperature() double } class Simulation { <<handle>> +Plate +Boundary +Dt +Time +step(n) StepCompleted event } class BoundaryKind { <<enumeration>> Dirichlet Neumann Periodic } Simulation *-- Plate : holds a copy Simulation --> BoundaryKind : uses

Trying the class in Octave

GNU Octave 11.3.0 implements classdef only partially, and the first run on this page showed it. Octave accepted the namespace folder and the class, but it does not yet support size, class and validation function specifications on properties: it printed the warning "size, class, and validation function specifications are not yet supported for classdef properties; INCORRECT RESULTS ARE POSSIBLE!" and then failed with a syntax error on the line T double, a property with a class but no default. The version below has the validators removed and defaults added, and runs. It uses max(obj.T(:)) because the "all" option is not assumed here.

% File: +heatflow/Plate.m  (Octave-compatible version)
classdef Plate
    properties
        Nx = 1
        Ny = 1
        Dx = 1
        Alpha = 1e-4
        T = 20
    end
    methods
        function obj = Plate(nx,ny,dx,alpha)
            if nargin > 0
                obj.Nx = nx;
                obj.Ny = ny;
                obj.Dx = dx;
                obj.Alpha = alpha;
                obj.T = 20*ones(ny,nx);
            end
        end
        function m = maxTemperature(obj)
            m = max(obj.T(:));
        end
    end
end
p = heatflow.Plate(4,3,0.01,1.2e-4);
disp(class(p))
disp(size(p.T))
p.T(2,2) = 95;
disp(p.maxTemperature())    % dot syntax
disp(maxTemperature(p))     % function syntax
q = p;                      % value class: q is an independent copy
q.T(1,1) = 500;
disp([p.T(1,1) q.T(1,1)])
q0 = heatflow.Plate;        % no-argument constructor
disp(size(q0.T))

Octave 11.3.0 output (MATLAB layout may differ):

heatflow.Plate
   3   4
95
95
    20   500
   1   1

It confirms the namespaced class, both call syntaxes, the copy behaviour of a value class and the no-argument constructor. Octave does not give a check on assigned values, so heatflow.Plate(-1,3,0.01,1e-4) would not be rejected there while MATLAB would raise a validation error; wording of such errors varies by release (not run here).

Where the books are outdated

Older MATLAB books may present object-oriented MATLAB as a recent addition or describe classes through the older @folder constructor style. Points to correct:

  • The classdef syntax is the only form to write today. Function-syntax classes still run in R2026b but are announced for removal, and schema.m classes are no longer supported.

  • Classes are normally kept in one file per class in a path folder; @folders are for splitting methods across files.

  • Property validation (size, class, validators) in the properties block and Name=Value arguments are newer than the older books; see Argument Validation.

  • The meta.* metadata classes were renamed matlab.metadata.* and "packages" are now called namespaces (R2024a); see Namespaces and Class Folders.

  • Precedence between a class in an @-folder and a function of the same name changed as of R2025b (see above), which older books assume the other way round.

The books are listed in the bibliography.

Learning more: the Object-Oriented Programming Onramp

MathWorks offers a free, self-paced course, the Object-Oriented Programming Onramp, in MATLAB Academy. According to its page it has hands-on exercises with automated feedback, covers creating custom classes and controlling access and behaviour (input validation and property storage), and uses a data type for an orienteering system as its running example. It needs a MathWorks account; this page did not sign in or check content beyond the course description. The general MATLAB Onramp is mentioned in Getting Help and Documentation.