Простое наследование
С версии компилятора 0.24, у программистов на языке Freebasic появилась возможность использовать в текстах своих программ простое наследование. Данная возможность дает некоторое сокращение кода в больших программах и делает код , скажем так , более современным...
Чаще всего данную возможность применяют в создании игр. Я попробую показать это на простом примере. К примеру у вас в игре есть три типа объектов: планеты, астероиды, корабли. Каждый из этих объектов имеет некоторые одинаковые свойства и методы:
Type SharedType ID As Integer ' идентификатор объекта Handle As Any Ptr ' хендл изображения Width_ As Integer ' ширина объекта Height As Integer ' высота объекта Declare Constructor() ' инициализация объекта Declare Destructor() ' деинициализация объекта Declare Sub Explosion() ' взрыв объекта End Type Constructor SharedType() ' инициализация всех свойств объекта End Constructor Destructor SharedType() 'подчищение всех данных объекта End Destructor Sub SharedType.Explosion() 'реализация взрыва End Sub
Однако каждый из этих объектов может иметь свои отдельные свойства и методы, которые реализуются в своем отдельном классе. Этот класс будет потомком от класса SharedType и будет наследовать все его свойства и методы. В итоге кроме своих собственных ресурсов, потомок может пользоваться и ресурсами родителя. С другой стороны родителю закрыт доступ к ресурсам потомка. Так например маленький ребенок может надеть одежду родителя, но родитель в одежду ребенка просто не влезет :)
Но если возвратиться к объектам, планеты могут вращаться , иметь оружие и радары, но скажем в игре не могут перемещаться. Астероиды могут перемещаться, но не имеют ни оружия , ни радаров. А корабли могут и имеют все перечисленное. Эта разность как раз и подталкивает к созданию наследуемых классов:
' Класс планет Type Planets Extends SharedType IDRadar As Integer ' идентификатор радара IDWeapon As Integer ' идентификатор оружия Declare Sub Rotate() End Type ' Класс астероидов Type Asteroids Extends SharedType Declare Sub Move() End Type ' Класс кораблей Type Ships Extends SharedType IDRadar As Integer IDWeapon As Integer Declare Sub Rotate() Declare Sub Move() End Type ' метод вращения планет Sub Planets.Rotate() End Sub ' метод движения астероидов Sub Asteroids.Move() End Sub ' метод вращения кораблей Sub Ships.Rotate() End Sub ' метод движения кораблей Sub Ships.Move() End Sub
Как можно заметить в Freebasic появилось новое ключевое слово EXTENDS , которое как раз указывает классу, что он является расширенным(дополненным). За этим ключевым словом идет имя класса, от которого наследуется содержимое класса-родителя. Вся прелесть дочернего (наследующего) класса в том, что в его методах есть возможность напрямую обращаться к свойствам и методам класса-родителя(ей) . Это избавляет программиста от лишних ссылок и указателей.
При том даже допускается использование одинаковых имен свойств и методов для родителя и потомка. Но если писать в таком стиле, придется для доступа к ресурсам класса-родителя(ей) использовать ключевое слово BASE (базовый). Пример:
Type SharedType ID As Integer ' идентификатор объекта Declare Sub Explosion() ' взрыв объекта End Type Sub SharedType.Explosion() Print "Main class" End Sub ' Класс планет Type Planets Extends SharedType ID As Integer ' идентификатор планеты Declare Sub Explosion() End Type ' метод вращения планет Sub Planets.Explosion() Base.Explosion()' вызываем метод родителя Print Base.ID ' Узнаем идентификатор объекта Print ID ' Узнаем идентификатор планеты End Sub Dim Obj As Planets = Type(10)' указываем идентификатор объекта при создании Obj.ID = 20 ' указываем идентификатор планеты Obj.Explosion ' вызываем метод потомка Sleep
Наследование может быть многоуровневым и при таком раскладе для доступа к
разным ступеням родителей можно использовать цепочку из ключевых BASE:
Base.Base.ID
Чем больше ключевых слов BASE, тем ближе к самому верхнему родителю в
иерархии.
Благодаря ключевому слову BASE , есть возможность довольно простой инициализации свойств главного родителя (стоящего на самом верху иерархии). Пример из справки:
Type SimpleParent As Integer a, b, c End Type Type Child extends SimpleParent Declare Constructor( ) End Type Constructor Child( ) Base( 1, 2, 3 ) End Constructor Dim Obj As Child ? Obj.a,Obj.b,Obj.c Sleep
Если вернуться к ключевому слову EXTENDS, то благодаря ему есть
возможность создавать классы на базе встроенного "нулевого" класса OBJECT. Это
дает свои преимущества:
1) Есть возможность создать класс и в нем указать декларацию метода без дополнительной переменной. То есть в версии ниже 0.24 , создать такой класс было нельзя:
Type MyClass Declare Sub Plus() End Type
Компилятор выдаст ошибку о том что тип пустой и чтобы исправить ошибку,
надо указать хоть одну переменную. Но используя наследование от типа OBJECT ,
можно создать вообще пустой класс:
Type MyClass Extends Object End Type
Нет необходимости в лишней переменной.
2) Появляется возможность определить тип объекта, используя ключевое слово IS. Пример:
Type MyClass Extends Object End Type Type Round Extends MyClass End Type Type Box Extends MyClass End Type Sub init(Obj As OBJECT Ptr) If *Obj Is Round Then Print "ROUND" Elseif *Obj Is Box Then Print "BOX" Else Print "PARENT" Endif End Sub ' Создаем главный объект Dim Obj As MyClass ' Создаем объект круг Dim R As Round ' Создаем объект прямоугольник Dim B As Box ' Проверяем init(@Obj) init(@R) init(@B) Sleep
Примечание:
И хоть в версии компилятора 0.24 допускается использование имен сходных с именами базовых классов (пример: Dim MyClass as MyClass) , привыкать к этому лучше не нужно. В версии 0.25 компилятор такой вольности уже не позволит. Для справки, в версии 0.25 заявлены новые возможности ООП: абстрактные и виртуальные методы. Но пока я даже не вижу их применения в реальных программах (просто не хватает опыта). Удачи!