{ "cells": [ { "cell_type": "markdown", "id": "oo-0", "metadata": {}, "source": "# Classes and object-oriented programming\n\nnumbl supports MATLAB's `classdef` object model: value and handle classes,\nconstructors, methods, inheritance, abstract methods, operator overloading,\nand static methods. Classes are defined in `.m` files next to the notebook\n(you can open and edit them in the file browser)." }, { "cell_type": "markdown", "id": "oo-1", "metadata": {}, "source": "## A value class with operator overloading\n\n[Vec2.m](./Vec2.m) overloads `+`, `-`, and `*` and defines `norm`." }, { "cell_type": "code", "id": "oo-2", "metadata": {}, "execution_count": null, "outputs": [], "source": "a = Vec2(3, 4);\nb = Vec2(1, 2);\nfprintf('a + b = %s\\n', char(a + b));\nfprintf('a - b = %s\\n', char(a - b));\nfprintf('3 * a = %s\\n', char(3 * a));\nfprintf('norm(a) = %g\\n', norm(a));" }, { "cell_type": "markdown", "id": "oo-3", "metadata": {}, "source": "## A handle class has reference semantics\n\n[Account.m](./Account.m) is a `handle` class, so assigning it does not copy:\nboth names refer to the same object." }, { "cell_type": "code", "id": "oo-4", "metadata": {}, "execution_count": null, "outputs": [], "source": "acct = Account(100);\ndeposit(acct, 50);\nalias = acct;\ndeposit(alias, 25);\nacct.Balance % 175: updates are seen through both names" }, { "cell_type": "markdown", "id": "oo-5", "metadata": {}, "source": "## Inheritance, abstract methods, and polymorphism\n\n[Shape.m](./Shape.m) declares an abstract `area()` and a concrete\n`describe()`. [Circle.m](./Circle.m) and [Square.m](./Square.m) implement\n`area()`." }, { "cell_type": "code", "id": "oo-6", "metadata": {}, "execution_count": null, "outputs": [], "source": "shapes = {Circle(2), Square(3)};\nareas = cellfun(@(s) s.area(), shapes)\ncellfun(@(s) isa(s, 'Shape'), shapes)" }, { "cell_type": "code", "id": "oo-7", "metadata": {}, "execution_count": null, "outputs": [], "source": "for i = 1:numel(shapes)\n shapes{i}.describe();\nend" }, { "cell_type": "markdown", "id": "oo-8", "metadata": {}, "source": "## Static methods and methods across files\n\n[MathX.m](./MathX.m) has a static method (called on the class, not an\ninstance). [@Poly/](./@Poly/Poly.m) is a class whose methods live in\nseparate files in its `@Poly` folder." }, { "cell_type": "code", "id": "oo-9", "metadata": {}, "execution_count": null, "outputs": [], "source": "MathX.hypot3(3, 4, 12)\np = Poly([1 -3 2]); % x^2 - 3x + 2\np.evalAt(5) % method from @Poly/evalAt.m\nroots(p.coeffs)'" }, { "cell_type": "markdown", "id": "oo-10", "metadata": {}, "source": "## Private helper methods\n\n[Temperature.m](./Temperature.m) keeps its conversion in a\n`methods (Access = private)` block, used internally by `fahrenheit`." }, { "cell_type": "code", "id": "oo-11", "metadata": {}, "execution_count": null, "outputs": [], "source": "t = Temperature(100);\nt.fahrenheit()" } ], "metadata": { "kernelspec": { "display_name": "numbl (MATLAB syntax)", "language": "numbl", "name": "numbl" }, "language_info": { "codemirror_mode": "octave", "file_extension": ".m", "mimetype": "text/x-octave", "name": "numbl", "nbconvert_exporter": "script", "pygments_lexer": "matlab" } }, "nbformat": 4, "nbformat_minor": 5 }