Форум программистов, компьютерный форум, киберфорум
Наши страницы
letete
Войти
Регистрация
Восстановить пароль
Несколько сообщений о МАТЛАБ и о том, как им пользоваться.

Комментарии, критика и восторженное рукоплескание приветствуются в самой категоричной форме.
Рейтинг: 5.00. Голосов: 1.

ООП в МАТЛАБ. Раздел 3. Наследование.

Запись от letete размещена 17.07.2014 в 19:16
Обновил(-а) letete 13.07.2015 в 16:08
Метки matlab, ооп

Наследование предполагает создание некоторой иерархии классов для описания некоторого взаимодействия между их экземплярами. Как и в предыдущих разделах, наследованием управляет определенная группа атрибутов.

Часть 1. Атрибут Sealed.
Атрибут Sealed означает "запечатанный", "герметичный" и может применяться к классу или к его методам. Этот атрибут означает запрет на наследование. Т.е. класс, определенный как Sealed не может иметь потомков.
Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
% файл c31.m
classdef (Sealed) c31
    methods
    function m1(~), disp('c31 -> m1'), end
    end
end
% ---------------------------------------------------
% файл c32.m
classdef c32 < c31           % при попытке создания экземпляра этого класса 
    methods                  % произойдет ошибка:
        function m1(this)    % "Class 'c31' is Sealed and may not be used as a superclass."
            disp('c32 -> m1')
        end
    end
end
Методы с этим атрибутом не передаются по наследству. Это почти то же самое, что Access = private, но не совсем. Свойство быть приватным лишь означает, что метод не доступен ниоткуда, кроме как изнутри класса. Свойство быть запечатанным же означает, что метод может быть доступен (при условии, конечно, что одновременно с Sealed не указан приватный Access), но не может быть наследован (переопределен).
Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
% файл c33.m
classdef c33
    methods (Sealed)
    function m1(~), disp('c33 -> m1'), end
    end
end
% ---------------------------------------------------
% файл c34.m
classdef c34 < c33            % при попытке создания экземпляра этого класса 
    methods                   % произойдет ошибка:
        function m1(this)     % "Method 'm1' in class 'c34' conflicts with the Sealed method 
            disp('c34 -> m1') % from the superclass definition in 'c33'."
        end                   % если же атрибут в 'c33' был бы Access = private, то ошибки
    end                       % не было б никакой, т.к. этот метод всего лишь переопределился бы
end
% ---------------------------------------------------
% файл c35.m
classdef c35 < c33            % с другой стороны, если в наследуемом классе
    methods                   % не использовать для метода имя 'm1', то
        function m2(this)     % все работает и даже доступен вызов функции 'm1'
            disp('c35 -> m2') % из класса 'c33'
            this.m1
            % m1@c33(this)    % однако такой вызов уже не доступен - если его раскомментировать,
        end                   % возникнет ошибка, потому что нельзя вызывать наследуемые методы
    end                       % когда не совпадают имена (т.е. из m2 нельзя вызвать m1)
end
По сути атрибут Sealed нужен, чтобы другие пользователи не имели возможности расширять созданный Вами класс. Ну или для себя - защита от дурака. В случае же, если Вами создается разветвленная схема классов с наследованиями, то можно напрямую указать все возможные связи "потомок-родитель", используя атрибут AllowedSubClasses.


Часть 2. Атрибут AllowedSubClasses.
Такой атрибут может иметь только сам класс. В нем перечисляются один или несколько классов, которые могут наследоваться от данного класса. В случае, если классов указывается несколько, то они объединяются с помощью ячеистой структуры:
Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
% файл с36.m
classdef (AllowedSubclasses = ?c37) c36
    methods 
    function m1(~), disp('c36 -> m1'), end
    end
end
% ---------------------------------------------------
% файл c37.m
classdef (AllowedSubclasses = {?c38 ?c39}) c37 < c36
    methods 
        function m1(this)      
            disp('c37 -> m1')  
            m1@c36(this)       % здесь стоит напомнить, что передавать 
        end                    % объект в аргументе обязательно
    end
end
И еще парочку классов, наследуемых с ошибкой, для примера:
Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
% файл c38.m                            ошибка!      
classdef (Sealed) c38 < c37 & handle % класс должен наследоваться или только 
    methods                          % от value классов или только от handle классов
    function m1(this), disp('c38 -> m1'), m1@c37(this), end
    end
end
% файл c39.m                                         ошибка! 
classdef (AllowedSubclasses = {}) c39 < c37 & c36 % в списке разрешений у класса с36
    methods                                       % нет класса с39
    function m1(this), disp('c39 -> m1'), m1@c36(this), end
    end
end
Однако, если в с38 убрать & handle, а в с39 убрать & c36, все будет работать. При это обратите внимание на вывод: в первом случае вызывается m1@c37(this), а во втором m1@c36(this).
Очевидно, что если указать AllowedSubClasses = {}, т.е. указать пустой список разрешенных наследований, то это равносильно указанию атрибута Sealed, т.е. оба примера выше в плане разрешений на дальнейшее наследование идентичны.


Часть 3. Атрибут Abstract.
Атрибут Abstract может иметь сам класс, свойство или метод – указывается непосредственно после соответствующего ключевого слова classdef, properties или methods. При этом важно помнить, что класс становится автоматически абстрактным, как только у него появляется хотя бы одно абстрактное свойство или хотя бы один абстрактный метод.
Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
% файл s1.m
classdef (Abstract) s1
 
    properties (Abstract)
        p1
    end
 
    methods
        function m1(~)
            disp('s1 -> m1')
        end
    end
    methods (Abstract)
        m2(~)
    end
    
end
% ---------------------------------------------------
% файл s2.m
classdef s2 < s1
    
    properties
        p1
    end
    methods 
        function m1(this)
            disp( 's2 -> m1' )
            m1@s1(this)
        end
        function m2(~)
            disp( 's2 -> m2' )
        end
    end
    
end
Абстрактность как таковая подразумевает в обязательном порядке наследование, поэтому чтобы лучше разбираться в этом вопросе, настоятельно рекомендую провести несколько экспериментов: попробуйте «поиграть» с атрибутами и посмотреть, что из этого получится.

Понятно, что создавать объекты абстрактных классов не возможно – они существуют лишь для того, чтобы быть наследуемыми и инкапсулировать в себе некоторые общие свойства и методы для всех наследников.

Абстрактный метод – это аналог чисто виртуальной функции, у него нет реализации, он лишь указывает на то, что наследники могут определить эту функцию – каждый по своему усмотрению (пардон, обязаны определить). По сути, абстрактные методы можно вообще не указывать – от этого ничего не изменится.

Абстрактное свойство обязано быть переопределенным в наследниках. Обязательно. Поскольку абстрактного свойства не существует, то и использование функций set/get для него запрещено, запрещено также и задавать значения по умолчанию для них.

Небольшое замечание: атрибуты Abstract и Sealed не совместимы по определению.

Часть 4. Наследование конструкторов.
Для конструкторов устанавливаются несколько правил наследования, самое важное из которых: все конструкторы родителей должны быть вызваны в конструкторе наследника в первую очередь:
Matlab M
1
2
3
4
5
6
7
8
9
classdef parent
end
classdef child
    methods
        function this = child
            this = this@parent
        end
    end
end
Размещено в МАТЛАБ
Просмотров 2008 Комментарии 0
Всего комментариев 0
Комментарии
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru