Автор rdc
Полиморфизм в объектно-ориентированном программировании является мощным
инструментом. Полиморфные метод (Sub или Function) ведут себя по-разному в
зависимости от определения объекта. Например объект животного может иметь
метод speak, который будет выдавать лай для собаки и мяуканье для кошки.
FreeBasic пока не поддерживает истинный полиморфизм; Это будет добавлено,
когда классы будут реализованы. Однако вы можете смоделировать полиморфные
методы, с использованием метода указателей.
Полиморфные методы являются подпрограммами или функциями, которые имеют тот
же тип и список параметров, но ведут себя по-разному при привязке к разным
объектам.
В следующем листинге показаны 2 определения и расширенный тип:
#define isdog 1
#define iscat 2
Type animal
Public:
speak As Sub()
Declare Constructor (anid As Integer)
End Type
#defines
передается в конструктор, чтобы сигнализировать, какой тип объекта
создается. speak As Sub() определяет указатель метода. Как вы увидите, адрес двух
различных подпрограмм будет передан по указателю в метод speak. Следующий
листинг
показывает, что
speak получает разные адреса в
конструкторе:
'Speak метод для объекта
dog(собаки)
Sub Bark()
Print "Woof!"
End Sub
'Speak метод для объекта cat(кошки)
Sub Meow()
Print "Meow!"
End Sub
'Установим указатель правильного метода, основанный на id
животного
Constructor animal(anid As Integer)
If anid = isdog Then
this.speak = @Bark
ElseIf anid = iscat Then
this.speak = @Meow
End If
End Constructor
Подпрограмма Bark
будет вызываться, если объект является
dog , а
подпрограмма
Meow будет
вызываться, если объект является
cat. Вы можете быть удивлены, почему
нельзя просто перегрузить метод? Для перегруженных методов тип и список
параметров должны быть уникальными, а в полиморфных методах тип и список параметров
должны быть одинаковыми. Поскольку Bark and Meow имеют такой же список
параметров, т.е. без параметров, невозможно перегрузить метод.
Код конструктора определяет, какой метод использовать. Если anid равно isdog,
то указатель метода Speak установится на адрес подпрограммы
Bark. Если anid равно iscat , то будет присвоен
адрес
Meow. Оператор @ (адрес из) используется для
передачи адреса
Bark и
Meow
методу
Speak.
Объектная ссылка
this - это скрытый
параметр, который передается в конструктор, который ссылается на тип, в
данном случае
animal. Вы можете использовать
this для ссылки на внутренние переменные
внутри типа
Единственное, что осталось сделать, это создать и инициализировать объекты:
'Создание объектов dog и cat
Dim myDog As animal = isdog
Dim mycat As animal = iscat
Здесь myDog и myCat создаются с соответствующими флагами, передаваемыми
конструктору. После создания объекта можно вызвать метод speak для каждого
объекта.
'Вывод того, что произносят животные
Print "My dog says ";
myDog.speak()
Print "My cat says ";
myCat.speak()
Обратите внимание, что вызывается один и тот же метод, но вывод отличается:
My dog says Woof!
My cat says Meow!
Это суть полиморфных методов.
Вот полный листинг:
'Имитация полиморфизма с помощью
метода указателей
'Richard D. Clark
'Требуется версия CVS FreeBasic
'**********************************************
#define isdog 1
#define iscat 2
Type animal
Public:
speak As Sub()
Declare Constructor (anid As Integer)
End Type
'Speak метод для
объекта dog(собаки)
Sub Bark()
Print "Woof!"
End Sub
'Speak метод для объекта cat(кошки)
Sub Meow()
Print "Meow!"
End Sub
'Установим указатель правильного метода, основанный на id
животного
Constructor animal(anid As Integer)
If anid = isdog Then
this.speak = @Bark
ElseIf anid = iscat Then
this.speak = @Meow
End If
End Constructor
'Создание объектов dog и cat
Dim myDog As animal = isdog
Dim mycat As animal = iscat
'Вывод того, что произносят животные
Print "My dog says ";
myDog.speak()
Print "My cat says ";
myCat.speak()
Sleep
End