Иерархия классов. Наследование и полиморфизм
Иерархия классов. Наследование и полиморфизм
В Смолтоке существует возможность введения иерархии классов с целью получения более компактных описаний и облегчения понимания отношений между классами.
Как уже говорилось, каждый класс имеет одного предка (суперкласс) и может иметь несколько потомков, называемых подклассами.
Классы в Смолтоке организованы иерархически в виде дерева. Иерархия классов устанавливается объявлением суперкласса внутри описания класса. Если объявлено, что класс A является суперкласом класса B, то это означает, что спецификация класса B включает в себя как спецификацию класса B, так и спецификацию класса A. При этом говорят, что класс B наследует спецификации из класса A (переменные экземпляра и методы своего суперкласса).
Кроме того, он может содержать новые переменные экземпляра и методы, может переопределять унаследованные.
Например:
В данном примере класс A является суперклассом класса B. Реализация класса B будет содержать в качестве переменных класса переменные a, b, c, в качестве переменных экземпляра – переменные h, x, y, в качестве методов класса - процедуры f1, f2, f3, а в качестве методов экземпляра - процедуры g1, g2, g3.
Одним из положительных эффектов иерархии классов является возможность объединения совпадающих по лексике объявлений методов, встречающихся в разных местах. При этом программы становятся более ясными и легко читаемыми.
Например, пусть имеются классы Integer и Float, описывающие целые и действительные числа соответственно. Если при этом создать класс Number, являющийся суперклассом для них обоих, то те методы, которые определены в классах Integer и Float и при этом совпадают лексически, могут быть определены в классе Number, после чего их можно удалить как из класса Integer, так и из класса Float. Например, ³ можно описать в виде
³ y
^(self<y) not
и включить в класс Number (напомним, что здесь ключевым словом self обозначена псевдопеременная, указывающая на получателя сообщения вида ³e). Сообщение <y вызывает два разных метода в зависимости от того, на что указывает псевдопеременная self: на экземпляр класса Integer или на экземпляр класса Float:
Во многих случаях иерархия классов позволяет также легко объявлять новые классы. Это связано с тем, что часто новые классы можно создавать как подклассы уже созданных классов с введением в них лишь особенностей, присущих данному подклассу. Рассмотрим, например, класс "поток", используемый для ввода-вывода информации. Будем считать, что уже определен класс WriteStream, используемый только для выходного потока. При этом класс ReadWriteStream, используемый и для выходного, и входного потоков, можно создать как подкласс класса WriteStream, определив при этом еще лишь метод чтения.