Создание экземпляра из выбранного класса.

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Создание экземпляра из выбранного класса.

Сообщение Don Leno » 23.12.2018 (Вс) 20:51

Вопрос как реализовать создание экземпляра класса из подмножества, что-то вроде этого:

Код: Выделить всё
Dim spr as clsEngine.Sprite
Dim snd as clsEngine.Sound

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Создание экземпляра из выбранного класса.

Сообщение Mikle » 24.12.2018 (Пн) 10:54

То есть вложенное объявление классов у тебя уже есть, ты это сделал, а нужно только как-то создать экземпляр?
Или речь о vb.net?

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Создание экземпляра из выбранного класса.

Сообщение Don Leno » 24.12.2018 (Пн) 12:07

Нет готового вложения классов у меня нет, я об этом и спрашиваю как это сделать?
Прошу прощения за неправильную формулировку и терминологию. Все только vb6!

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Создание экземпляра из выбранного класса.

Сообщение alibek » 24.12.2018 (Пн) 12:12

Называешь проект (библиотеку) clsEngine, в нем создаешь публичные классы Sprite и Sound.
clsEngine классом быть не может.
Lasciate ogni speranza, voi ch'entrate.

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Создание экземпляра из выбранного класса.

Сообщение Don Leno » 24.12.2018 (Пн) 12:22

А нельзя ли создать класс clsEngine в нем например написать свойство или метод которые будут создавать новый экземпляр класса Sprite и передавать его ссылку или что то вроде этого. Я не силен в этом.
То есть класс в классе сделать никак нельзя или может все таки есть альтернативы?
To alibek
Тогда что мне мешать обратиться к ним напрямую минуя clsEngine ( как проект) :

Код: Выделить всё
Dim spr as Sprite


Суть в том не просто красоты ради использовать данную фичу, а для того чтобы создать единую структуру к которой удобно было бы обращаться. К примеру:
Имеем общий класс clsEngine в котором содержатся все сабдвижки clsGraphics и clsSound.
Теперь к примеру пишу я процедуру анимации планеты в классе clsPlanet и при необходимости могу обращаться к функциям движка таким вот образом:

Код: Выделить всё
Dim gr as clsEngine.Graphics
Dim snd as clsEngine.Sound

Public sub planet_anim()
Gr.animation " planet.bmp"
Snd.play "plabet.wav"
End sub
Последний раз редактировалось Don Leno 24.12.2018 (Пн) 12:48, всего редактировалось 1 раз.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Создание экземпляра из выбранного класса.

Сообщение Mikle » 24.12.2018 (Пн) 12:41

Don Leno писал(а):А нельзя ли создать класс clsEngine в нем например написать свойство или метод которые будут создавать новый экземпляр класса Sprite и передавать его ссылку или что то вроде этого.

Можно. Но класс Sprite не может быть объявлен внутри класса clsEngine, и объявление переменных типа Sprite будет таким: Dim spr as Sprite а не таким: Dim spr as clsEngine.Sprite.
Ну или работать с отдельной ActiveX DLL, как написал alibek.

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Создание экземпляра из выбранного класса.

Сообщение Don Leno » 24.12.2018 (Пн) 12:51

Спс Mikle and alibek.

Появился вопрос: как из одного класса обратиться к другому, к его сабам, функциям и свойствам?

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Создание экземпляра из выбранного класса.

Сообщение Don Leno » 24.12.2018 (Пн) 19:09

Но класс Sprite не может быть объявлен внутри класса clsEngine

Mikle, а почему я тогда в классе пишу так:

код класса E:
Код: Выделить всё
Dim snd as New seSND 'seSND - класс
Public sub E_Sub()
snd.se_sub
end sub


код класса seSND
Код: Выделить всё
Public Sub se_sub()
msgbox "SE_SUB"
End
end sub


И все прекрасно объявляется и работает!
В итоге для себя нашел лишь использование через свойство:
Код: Выделить всё
Dim snd as New seSND

Property Get My() As seSnd
Set My = snd
End Property


Получается запись в таком виде:

Код: Выделить всё
Dim e as clsE

e.My.se_sub


То есть я передал через свойство ссылку на созданный экземпляр. Таким образом можно разделить устройство движка:

Код: Выделить всё
Engine.Sound.Play
Engine.Sprite.Draw


То есть будет три класса Engine, Sound и Sprite. Sound и Sprite будут хранить все необходимые функции и сабы. Конечно получил не то что хотел но удобство в записи конечно есть))

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Создание экземпляра из выбранного класса.

Сообщение Хакер » 24.12.2018 (Пн) 22:19

Don Leno писал(а):Суть в том не просто красоты ради использовать данную фичу,

Don Leno, судя по написанному, пока что выходит, что всё-таки это делается для красоты, причём делается крайне противоестественным и неумелым образом.

А самое главное, похоже, ты вообще не врубаешься в суть ООП в целом и суть того ООП, который есть в VB. Ты понимаешь, что класс — это контейнер для процедур и переменных, а своего рода шаблон для создания тиражируемых сущностей, объединяемых общим кодом?

На стуле сидят, соковыжималкой готовят сок, в стиральной машине стирают. Можно стул перевернуть вверх ногами, примотать изолентой к нему соковыжималку и шурупами прибить к стиральной машине, всё это в самых неестественных позах и взаиморасположениях, и, в целом, так, чтобы вращающиеся части соковыжималки и стиральной машинки выступали и кое-как зацеплялись за пол. В итоге получится корявое транспортное средство, какая-то невнятная самоходная коляска, которая ездить будет кругами, потому что у стиральной машинки барабан и соковыжималки соответствующая часть крутятся с разной скоростью и имеют разное сцепление с полом, и центр тяжести получился где-то сбоку. Сделать это можно, не спорю, но получится какая-то убогая дикость.

Вот что-то такое ты пытаешься соорудить из классов.

Don Leno писал(а):Sound и Sprite будут хранить все необходимые функции и сабы.

И всё-таки я читал это с мыслью найти какое-то разумное зерно, но под конец увидел всё тот же порочный способ мыслить о вещах. Ты о классах думаешь как о хранилищах сабов и функций. А это вообще не так. Они вообще не для этого придуманы. Если тебе нужен лишь контейнер для функций, то достаточно обычного модуля.

Тетрадка в клеточку имеет шаг клеточек в 5 мм — прикладывая тетрадку к разным объектам, можно, считая клеточки, замерять размер разных предметов. Но театрадка вообще не для этого придумана. Хочешь замерять — купи линейку. Карандашом можно в принципе и зубы почистить, но он вообще не с этой целью придуман. Хочешь чистить зубы — купи зубную щётку.

Пока что я вижу, что ты где-то во взрослых движках увидел как бы тенденцию или стилевой приём в виде иерархической объектной модели, увидел записи вида RootObject.Subobject.AnotherObject.Action и хочешь любой ценой повторить такое у себя, при этом не понимая, зачем и почему. Очень похоже на культ карго в программировании.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Создание экземпляра из выбранного класса.

Сообщение Don Leno » 25.12.2018 (Вт) 5:14

Хакер, ты во всем прав кроме последнего я нигде ничего не видел. Просто думал так будет удобнее программить и разобрать все функции и сабы по полочкам. Если класс не является контейнером то тогда для чего он нужен? Функции сабы свойства служат для создания объекта, как я понимаю. То есть они нужны для создания объектов (раз ООП)

Но ведь я и преследую ту же суть. Мне необходимо создавать внутреигровые объекты (корабль, планета и т.п.). Я об этом писал ранее про анимацию планеты. Мне просто необходимо создать упорядоченную структуру движка, чтобы уже программируя внутрение объекты не путаться в куче сабов и функций.

Вот примера ради:

Будут существовать несколько объектов:

Код: Выделить всё
Dim Ship as clsShip
Dim Planet as clsPlanet

Ship.move 500,500
Planet.anim()


Так видно что они используются как объекты. Но по сути внутри будут описаны сабами и функциями из моей структуры движка:

Код: Выделить всё
Dim e as clsEngine
Public sub move(x, y)
E.sprite.x= x+1
E.sprite.y =y+1
E.sound.play "start_move.wav"
End sub


Если я не верно понял чтото, объясните пжлста!

P.S. хотя сам класс clsEngine тоже объект, который Является неким контейнером для более мелких объектов как clsSound и clsSprite. Всего лишь смотря с какой стороны на это смотреть...
Ведь, к примеру, в vb есть объект frame, который может содержать в себе другие объекты которые оч разные между собой такие как Label и Button. Но он для того и создан чтобы вмещать в себя объекты. Тоже самое и с моим движком.

Хотя я догадываюсь почему Хакер говорит что лучше использовать модуль. Я попытаюсь рассказать, а вы если что поправьте.

Итак, если класс является как бы объектом, то наш движок будет создаваться единожды в объекте, скажем, планета ( clsPlanet) и использоваться. Но тогда допустим что у меня целая солнечная система и я создам 10 таких планет. То класс clsEngine будет уже объявлен не один, а 10 раз! В итоге получаем множество объектов с одинаковыми функциями и сабами. Но тогда как быть?

Можно ли из класса вызывать функции и сабы из модуля? Чтобы можно всем объектам движка обращаться к одному модулю со всеми функциями и сабами.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Создание экземпляра из выбранного класса.

Сообщение Mikle » 25.12.2018 (Вт) 9:54

Don Leno писал(а):Итак, если класс является как бы объектом

Класс не является объектом, у тебя может быть много объектов спрайтов, но класс спрайта будет один. Класс - это описание того, как создавать объект, что он может.
VB6 IDE заставляет каждый класс описывать в отдельном модуле (файле), это может вводить в заблуждение. Это не модуль, это больше похоже на структуру (Type). Те самые "сабы и функции" предназначены для работы с данными именно данного ЭКЗЕМПЛЯРА класса (не класса!) и называются методами. Экземпляр класса - это объект, объектов много, класс один, это надо понять. Контейнером одного объекта может быть другой объект, но это не относится к классам.
Теперь ещё одно понятие - объектная переменная. Если ты написал:
Код: Выделить всё
Dim Ship As Sprite

ты ещё не создал объект. Если потом написать:
Код: Выделить всё
Set Ship = New Sprite

тут уже создаётся объект, экземпляр класса Sprite. Но Ship - это НЕ ОБЪЕКТ, а переменная, ссылающаяся на него, это тоже очень важно понять. У объекта НЕТ имени. Можно написать:
Код: Выделить всё
Dim Ship1 As Sprite
Dim Ship2 As Sprite
Set Ship1 = New Sprite
Set Ship2 = Ship1

У тебя по-прежнему только один объект типа Sprite, есть две ссылки на него, в этом ещё одна разница со структурами, структуры было бы два экземпляра, ключевое слово Set помогает не путать это с обычным приравниванием.
Если дальше написать:
Код: Выделить всё
Set Ship1 = Nothing

объект не будет уничтожен, просто на него останется одна ссылка Ship2. Чтобы уничтожить объект, нужно занулить все ссылки на него.

Вывод: есть три разных понятия: класс, объект (экземпяр класса) и объектная переменная-ссылка.
Ссылки могут быть не только на объект, а на обычные переменные, это помогает понять то, как две ссылки ссылаются на одну сущность.
Сделай такой простой тест:
Код: Выделить всё
Option Explicit

Dim x As Long

Private Sub Form_Click()
  Test x
End Sub

Private Sub Test(ByRef v As Long)
  v = 3
  MsgBox Str(v) & Str(x)
  x = 5
  MsgBox Str(v) & Str(x)
End Sub

Внутри Sub Test у тебя v, это не переменная, а ссылка на переданную переменную, в данном случае x. Меняя значение по ссылке - мы меняем значение самой переменной, меняя саму переменную - мы меняем и значение по ссылке.

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Создание экземпляра из выбранного класса.

Сообщение Don Leno » 25.12.2018 (Вт) 11:04

Ох как все сложно! Так же совсем можно запутаться! :?

В итоге понимаю так:
Класс описывает объект. Какие свойства методы у него есть, ах да и события же тоже! По этому описанию создается объект.

Код: Выделить всё
Dim Ship1 As Sprite
Dim Ship2 As Sprite
Set Ship1 = New Sprite
Set Ship2 = Ship1


То есть в начале объявления ship1,ship2 ссылается на класс. Но после установки set и new ship1 ссылается уже на новосозданный объект, а не на класс. Так? После ship2=ship1 обе переменные ссылаются на созданный объект. Верно?
То есть чтобы получить ссылку на класс мне нужно объявить (в моих примерах) переменную без слова new?

Код: Выделить всё
Dim snd as seSND

Property Get My() As seSnd
Set My = snd
End Property


Вот так? Хотя не понимаю зачем тогда вообще было объявлять snd и присваивать его my, когда она и так имеет ссылку на seSnd или я не прав?
Теперь я не пойму как сделать свою структуру

P.S. пишу с мобильного на работе так что проверить сейчас не могу.
Последний раз редактировалось Don Leno 25.12.2018 (Вт) 12:01, всего редактировалось 1 раз.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Создание экземпляра из выбранного класса.

Сообщение Mikle » 25.12.2018 (Вт) 12:00

Don Leno писал(а):То есть в начале объявления ship1,ship2 ссылается на класс. Но после установки set и new ship1 ссылается уже на новосозданный объект, а не на класс. Так? После ship2=ship1 обе переменные ссылаются на созданный объект. Верно?

Не верно. На класс ссылаться нельзя, в начале переменные ссылаются на Nothing. После кода - верно.

Второй код возвращает в My ссылку на snd, если snd ещё не инициализирована - будет Nothing.

Don Leno писал(а):не пойму как сделать свою структуру

Не понял, в чём проблема. Структура - это Type, в классе примерно аналогичную роль играют переменные, объявленные в заголовке кода класса.

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Создание экземпляра из выбранного класса.

Сообщение Don Leno » 25.12.2018 (Вт) 12:05

Мне кажись это надо по полочкам сейчас разложить. Позжешь отпишусь. А как с типами, также как и в обычных:

Код: Выделить всё
Private type
  S as long
  P as string
End type


Разве их объявить нельзя?

Одного не понял мой код выше рабочий так? Что в нем не правильно? Объясните мне пжлста!

Вот это:

Код: Выделить всё
Dim e as clsE

e.My.se_sub


alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Создание экземпляра из выбранного класса.

Сообщение alibek » 25.12.2018 (Вт) 18:48

Don Leno писал(а):E.sprite.x

Это вообще не имеет никакого отношения к тому, как организованы (распределены по файлам) классы.
Lasciate ogni speranza, voi ch'entrate.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Создание экземпляра из выбранного класса.

Сообщение alibek » 25.12.2018 (Вт) 18:51

Don Leno писал(а):Разве их объявить нельзя?

С объектами и типами работают по разному.
Lasciate ogni speranza, voi ch'entrate.

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Создание экземпляра из выбранного класса.

Сообщение Don Leno » 25.12.2018 (Вт) 19:41

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

Кстати на многие вопросы ответов так и не дождался. Поэтому решил немного упростить и пронумеровать каждый чтобы на них могли ответить и не пропустить, а то получаются ответы совсем частичными. Итак:

1.
Don Leno, судя по написанному, пока что выходит, что всё-таки это делается для красоты, причём делается крайне противоестественным и неумелым образом.

Как тогда реализовать это умело и естественно? Дайте исходник чтобы увидеть красу эту!)

2. Из того что мне писали выше ставлю вопросы на утверждение:
а. Класс - это файл описания объекта, а точнее его свойств методов событий и тп. Верно?
б. Класс не может быть создан через слово New в нескольких экземплярах. Класс только один. Правильно?
в. При таком объявлении
Код: Выделить всё
Dim spr as Sprite

переменная spr равна Nothing
г. При объявлении
Код: Выделить всё
Dim spr as New Sprite

или
Код: Выделить всё
Dim spr as Sprite

Set spr = New Sprite


Переменая spr ссылается на созданый объект словом New. Я не ошибся?
д. Чтобы уничтожить созданный объект (по выше описаному объявлению в пункте "г") нужно занулить все ссылающиеся на этот объект переменные:
Код: Выделить всё
Set spr=Nothing

Verify please)
е. Могу ли я в классе создать объект:
Например, в классе Engine написать так:
Код: Выделить всё
Dim spr as New Sprite

Правильно ли так делать или нет?
ё. Можно ли из класса вызывать функции и сабы из модуля? И как правильно это все делается, коли возможно?
ж. Про типы объясните, не понял я как ими пользоваться в классе. В модуле встречал такие как BITMAPINFOHEADER и ARGB и прекрасно с ними работал. Можно и свои такие же создавать. Но в классах они как то по иному работают, али нет?

3. Альтернативы для решения моей задачи (создание структуры для удобства программирования процедур и функций) - есть?!

Пока на этом все, жду ваших пожеланий ответов!))
Вложения
ClassTest.rar
Здесь создана та структура которую описывал в этой теме
(1.75 Кб) Скачиваний: 194

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Создание экземпляра из выбранного класса.

Сообщение Mikle » 25.12.2018 (Вт) 19:52

Отвечу позже, наверное, завтра после обеда.

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Создание экземпляра из выбранного класса.

Сообщение The trick » 25.12.2018 (Вт) 22:20

В VB6 модуль класса описывает интерфейс и реализацию. Когда ты пишешь что-то типа Dim Z As SomeClass - SomeClass в данном контексте означает интерфейс. В COM вообще нет такого понятия как ссылка на объект, а есть только ссылка на интерфейс. Поскольку VB6 живет по правилам COM то это к нему также относится. Один класс может реализовывать несколько интерфейсов (как минимум любой VB-класс реализует IDispatch (Object), IUnknown и другие). Интерфейс - это контракт взаимодействия с внешним миром. Класс же в свою очередь однозначно определяет реализацию. К примеру несколько разных классов могут реализовывать один и тот же интерфейс (самый простой случай - As Object реализуется всеми VB объектами, но также можно любой пользовательский интерфейс "прикрутить"). Мы обращаемся к классу только в момент создания конкретного экземпляра объекта (либо после ключевого слова New, либо после CreateObject). Дальше мы работаем уже с конкретным экземпляром класса посредством ссылки на интерфейс. Поведение конкретного метода этого интерфейса определяется кодом класса. В VB6 модуль класса описывает как интерфейс так и реализацию сразу, но есть возможность к примеру описать интерфейс через MIDL а реализацию сделать на VB6 (если к примеру хочется запретить создание пустых классов интерфейсов). Также для публичных проектов (ActiveX Dll, ActiveX EXE и т.д.) есть возможность экспортировать интерфейс описанный в VB6 посредством указания атрибута PublicNotCreatable.
Конкретный пример (Standard EXE). Добавляем класс CSomeClass:
Код: Выделить всё
Private mlVar As Long

Public Property Let Var( _
                    ByVal lValue As Long)
    mlVar = lValue
End Property

Public Property Get Var() As Long
    Var = mlVar
End Property

Public Sub Show()
    MsgBox mlVar
End Sub

В данном случае мы имеем описание интерфейса CSomeClass, а также реализацию этого интерфейса с таким же именем. Теперь мы можем определить любую переменную как Dim c As CSomeClass и в данном случае CSomeClass обозначает ссылку на интерфейс. Однако при написании Set c = New CSomeClass мы уже в этой строчке обращаемся именно к классу (реализации интерфейса). Описание интерфейса включает в себя описание публичных методов, а также публичных переменных. Т.е. если требуется описать интерфейс без реализации то можно просто описать все публичные сущности, а код оставить пустым:
Код: Выделить всё
Public Property Let Var( _
                    ByVal lValue As Long)
End Property

Public Property Get Var() As Long
End Property

Public Sub Show()
End Sub

Но как я написал что в VB6 модуль класса описывает как и интерфейс (по умолчанию) так и реализацию, то просто будет создана пустая реализация и мы все еще можем написать Set c = New CSomeClass. Чтобы избежать этого можно создать описание на языке описания интерфейсов:
Код: Выделить всё
interface CSomeClass : IDispatch {
      
   [propput]
   HRESULT Var(long lValue);
      
   [propget]
   HRESULT Var([out, retval]long *lValue);

   HRESULT Show();

}

В этом случае мы имеем только описание интерфейса и не можем писать Set c = New CSomeClass, но можем писать Dim c As CSomeClass. Также мы можем обойтись только средствами VB6, создав ActiveX dll и описав пустые классы в ней с атрибутом PublicNotCreatable; далее подключив эту DLL в проект иметь только описание.
Для того чтобы реализовать интерфейс который не является интерфейсом по умолчанию как в примере, нужно использовать ключевое слово Implements. Т.е. если мы имеем описание интерфейса в любом варианте из указанных выше, мы можем к примеру добавить модуль класса CSecondClass и написать там Implements CSomeClass и уже непосредственно реализовывать методы интерфейса для этого класса (в списке Object появится элемент CSomeClass при выборе которого можно будет выбрать автоматически созданные прототипы для методов данного интерфейса:
Код: Выделить всё
Implements CSomeClass

Private mlVal   As Long

Private Sub CSomeClass_Show()
    MsgBox mlVal * 2
End Sub

Private Property Get CSomeClass_Var() As Long
    CSomeObject_Var = mlVal
End Property

Private Property Let CSomeClass_Var( _
                     ByVal RHS As Long)
    mlVal = RHS
End Property

Теперь мы можем написать Dim c As CSomeClass, а дальше уже писать как Set c = New CSomeClass (в этом случае CSomeClass указывает на класс) так и Set c = New CSecondClass, т.к. у нас оба класса реализуют интерфейс CSomeClass. Мы можем присвоить свойству Var какое-нибудь значение (к примеру 5), а реализация метода Show будет уже зависеть от класса которому принадлежит объект. Т.е. для класса CSomeClass это выведет 5, а для CSecondClass это выведет 10. Тут как раз и видно всю мощь полиморфизма на основе интерфейсов. Для вызывающей стороны абсолютно все-рано как реализован метод, ей важен только правильный контракт (интерфейс). К примеру очень удобно какие-то интерфейсы скрыть от внешнего мира (например какой-нибудь IParent который предоставляет возможность хранить слабую ссылку на объект-родитель, а также получать от родителя уведомления если он больше недоступен; для внешнего потребителя мы предоставляем только Get свойство). Обычно интерфейсам дают имена начинающиеся с префикса I (IUnknown/IDispatch и т.д.) чтобы отличать их от классов.
Что касается объявления Dim c As New CSomeClass. В данном случае средствами VB6 всегда обеспечивается существование экземпляра объекта класса CSomeClass со ссылкой на него посредством интерфейса CSomeClass. Т.е. фактически при каждом обращении к этой ссылке проверяется указывает ли ссылка на какой-либо экземпляр объекта (и необязательно именно класса CSomeClass) и если ссылка не указывает на какой-либо объект то автоматически создается экземпляр объекта класса CSomeClass, и присваивается этой ссылке указатель на интерфейс CSomeClass.
Также есть такое понятие как PredeclaredId классы. Добавив атрибут Attribute VB_PredeclaredId = True VB6 позволит обращаться к экземпляру объекта класса
CSomeClass так как-будто где-то в пространстве имен проекта есть описание Dim CSomeClass As New CSomeClass (аналогично как идет обращение к форме без явного создания экземпляра формы).
UA6527P

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Создание экземпляра из выбранного класса.

Сообщение Mikle » 26.12.2018 (Ср) 20:00

1.
Don Leno писал(а):Как тогда реализовать это умело и естественно? Дайте исходник чтобы увидеть красу эту!)

Можно сказать так, что красота в сокрытии ненужных сущностей от внешнего мира, если переменную можно объявить Private, то её нужно объявлять Private, а не Public; если её можно объявить внутри функции, а не на уровне модуля, то так и стоит поступать. Каждый модуль, а тем более класс, делает внутри себя как можно больше, предоставляя внешнему миру только нужное этому самому миру.
Ещё красота в отсутствии лишних вложенностей. Вот у тебя есть Sprite, есть Sound, Ship и т.п., но зачем нужна сущность Engine? Чтобы лишний раз греть себе душу, что ты пишешь движок?
Ещё красота в единообразии. Если класс Ship имеет для перемещения метод Move, с параметрами x и y, то желательно чтобы и класс Bullet перемещался таким же методом с такими же параметрами в таком же порядке.
The trick в предыдущую дискуссию внёс важную поправку - класс, это интерфейс и реализация, просто боюсь, сразу это тебе будет сложно, но это позволяет добавить той самой красоты - Ship, Bullet и прочие физически-графические сущности, например, Stone, могут быть унаследованы от общего интерфейса, это даёт не только однообразие во внешнем виде программы, но и, например, возможность их содержания в одном массиве и многое другое.

2.
а. Класс - это файл описания объекта, а точнее его свойств методов событий и тп. Верно?

Не совсем. Это не обязательно файл, в других языках классы объявляются в тексте в любом месте, так же, как функции или структуры. А может быть класс вообще не в виде текста, например:
Код: Выделить всё
Option Explicit

Private Sub Form_Click()
  Dim f As Form
  Set f = New Form1
  f.Show
End Sub

Есть класс Form, но нигде нет его текста.

б. Класс не может быть создан через слово New в нескольких экземплярах. Класс только один. Правильно?

Один в том смысле, что если у тебя 10 спрайтов, то это десять экземпляров класса Sprite, но сам класс только один. Но, естественно, могут быть и другие классы, для объектов другого типа.
И вообще, словом New не создают классы, создают экземпляры классов, то есть объекты.

в. При таком объявлении
Dim spr as Sprite
переменная spr равна Nothing

Да.

г. При объявлении
Dim spr as New Sprite

или
Dim spr as Sprite
Set spr = New Sprite

Переменая spr ссылается на созданый объект словом New. Я не ошибся?

Не верно, слово New создаёт новый экземпляр класса Sprite, а за присвоение переменной ссылки на этот объект отвечает слово Set.

д. Чтобы уничтожить созданный объект (по выше описаному объявлению в пункте "г") нужно занулить все ссылающиеся на этот объект переменные:
Set spr=Nothing

Верно.

е. Могу ли я в классе создать объект:
Например, в классе Engine написать так:
Dim spr as New Sprite
Правильно ли так делать или нет?

Это корректный код.

ё. Можно ли из класса вызывать функции и сабы из модуля? И как правильно это все делается, коли возможно?

Если ф-ции модуля Public, то они вызываются откуда угодно.

ж. Про типы объясните, не понял я как ими пользоваться в классе. В модуле встречал такие как BITMAPINFOHEADER и ARGB и прекрасно с ними работал. Можно и свои такие же создавать. Но в классах они как то по иному работают, али нет?

Пользоваться так же, как и везде, только не получится в классе создать Public структуру, можно только Private, то есть она будет видеться только внутри этого класса.

3.
Альтернативы для решения моей задачи (создание структуры для удобства программирования процедур и функций) - есть?!

О какой структуре речь? О структуре проекта, или о структуре, которая Type?
Не понял, что ты хотел спросить по своему коду. Показать иерархию (вложенность) объектов? Да, это работает, тебе говорили, что не сделаешь вложенный класс в другой класс, а не объект в объект.

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Создание экземпляра из выбранного класса.

Сообщение Don Leno » 27.12.2018 (Чт) 16:56

Mikle и Trick
Огромная вам благодарность! Все так подробно и тщательно, что теперь пока разбираюсь с этим. Отпишусь позже, как возможность будет, так что поглядывайте сюда, вопросов у меня еще куча))))

Teranas
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 224
Зарегистрирован: 13.12.2008 (Сб) 4:26
Откуда: Новосибирск

Re: Создание экземпляра из выбранного класса.

Сообщение Teranas » 29.12.2018 (Сб) 4:02

Часто использую классы и пишу их, но в моём понимании, класс, это всего лишь возможность сгруппировать код и сделать его использование более удобным, что вроде кода внутри Type.
А обо всех этих замутах, описанных выше, я даже не задумывался, но почитал с интересом...
С уважением, Андрей.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Создание экземпляра из выбранного класса.

Сообщение Mikle » 29.12.2018 (Сб) 19:19

Teranas писал(а):что вроде кода внутри Type

Вот это - очень правильная ассоциация. Но основное различие то, что это ссылочный тип, в vb.net можно в структуры писать код, фактически получаются методы, можно создавать экземпляр структуры с помощью New, есть конструкторы, но классы от них всё равно отличаются тем, что они чисто ссылочные.

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Создание экземпляра из выбранного класса.

Сообщение Don Leno » 30.12.2018 (Вс) 20:15

Mikle прочитав последнее твое сообщение, как то проще было понять. Я с типами работал теперь понятнее стало что такое класс.
но зачем нужна сущность Engine? Чтобы лишний раз греть себе душу, что ты пишешь движок?

Еще раз повторюсь пишется мною такая структура чтобы мне было проще в коде разбираться, так сказать по полочкам в голове разложить и знать где что лежит. То есть "сущность Engine" используется только для себя, да я понимаю, что это не правильно добавлять излишества в коде. Если в большом количестве кода приходится искать название одной функции, которую не помнишь как назвал, чтобы вписать где-то в другом месте своего проекта, то как быть - для меня будет проще написать
Код: Выделить всё
Engine.Sound.

И в выпадающем списке отыскать функцию или сабу необходимую мне! Тем более все равно эту структуру кода никто кроме меня не увидит!))
Да и мало ли кому понадобиться реализовать подобную фичу у себя в проекте. Если мой исходник можно исправить и написать более "красиво", с точки зрения программирования, милости прошу покажите мне такую реализацию))

The trick и Mikle
Мне очень понравилась идея создания интерфейса, описаная The trick (про CSecondClass и CSomeClass). Попробую создать исходник, если что выложу сюда, для проверки вам. А так вопросов по интерфейсам, их реализациям и классам пока нет, вы так все подробно расписали, что данная страница у меня что-то вроде хелп справки, которую можно прочитать в любой момент, если вдруг подзабуду что да как)))

Итак, вот исходник проба по реализации интерфейсов:
Вложения
Interface.rar
(2.36 Кб) Скачиваний: 169

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Создание экземпляра из выбранного класса.

Сообщение Хакер » 31.12.2018 (Пн) 4:57

Don Leno писал(а):Еще раз повторюсь пишется мною такая структура чтобы мне было проще в коде разбираться, так сказать по полочкам в голове разложить и знать где что лежит.

Ну и зачем при этом иметь контейнер Engine, если кроме как движка в твоём проекте ничего нет? Это как идея сделать папку «ВСЁ» и в неё поместить все остальные папки и файлы на диске? Какой смысл в папке «ВСЁ», если её содержимое может просто лежать в корне диска?

Потом второй момент. Если ты хочешь большой объём функций (хотя даю голову на отсечение, что он у тебя не большой) как-то логически разбить, чтобы они смешивались, почему бы не воспользоваться идеей давать именам функций префиксы? Ядро Windows практически полностью написано на Си, в языке Си вообще нет классов, тем не менее, разработчики ядра Windows не запутались в своих функциях, хотя их у них было в тысячи раз больше, чем у тебя.

В ядре все функции имеют префиксы: Ob — функции для работы с подсистемой объектов, Io — ввод/вывод, Ldr — загрузка исполняемых файлов, Ki — (kernel internals) внутренние функции ядра, Mm — (memory management) управление памятью, Mi — (memory internals) внутренние функции управления памятью, Ex — (executive) исполнительная подсистема, Ps — работа с процессами, Po — управление питанием, и так далее.
ntos_prefixes.PNG
ntos_prefixes.PNG (55.69 Кб) Просмотров: 5322


Префиксы не обязательно должны быть 2—3 буквенными, они могут быть длинными, или однобуквенными, начинаться с большой или маленькой буквы, отделяться от основной части символом подчёркивания. Система префиксов может быть или не быть иерархической.

Если цель исключительно в категоризации имён, зачем писать Engine.Sound.Xxxx, если можно Engine_Sound_Xxxx или snd_Xxxxx. Это вопрос вкуса, стиля.

Хотя, возвращаясь к началу поста: я не вижу вообще смысла делать класс или префикс «Engine» — какой в этом смысл, если абсолютно всё будет начинаться с префикса Engine, ибо ничего другого в проекте нет?
Отдельный вопрос: что такое Engine.Sound? Это то, что в действительности должно называться Engine.SoundSubsystem? Или это именно нечто, олицетворяющее один отдельный самостоятельный проигрывающийся звук? То есть движок, предполагается, будет иметь такую архитектуру, что звучит в любой момент времени лишь 1 звук?
Аналогичный вопрос к спрайтам — почему я вижу тут Engine.Sprite, а не Engine.AllSprites(...)? Движок планируется быть настолько убогим и примитивным, что поддерживается работа только с одним спрайт-объектом?

Don Leno писал(а):Итак, вот исходник проба по реализации интерфейсов:

Всё мимо кассы. Всё не так. Помимо всеобщей кривости кода, интерфейсы здесь вообще никаким образом не используются. И лучшее доказательство этого — я удаляю строчку Implements clsShip и проект как работал, так и работает дальше.

Это как известное фейковое видео «сварщик из Индонезии собрал себе бионическую руку». На поверку оказывается, что рука у него из металлолома, а на спине закреплена куча разношерстной электроники, которая висит исключительно для вида, а не для совершения каких-то реальных функций и нужд.

Во-первых, если класс используется в качестве интерфейса, то скорее всего в этом классе в методах не будет никакого кода, и в этом классе не будет объявлено никаких полей (переменных уровня класса). Это не железное правило, это не какой-то запрет, просто статистически оказывается так, что почти не бывает в реальной жизни ситуаций, когда это имело бы хоть какой-то смысл. Хотя в ряду других языков программирования, где есть интерфейсы, иметь в них объявления переменных или в методах иметь какой-то код запрещено прямо и явно. Потому что это на грани бессмыслицы. А у тебя в clsShip есть переменная spd и в методах какой-то код.

Потому что интерфейсы — это история о том, что должен уметь делать класс, при полном и целенаправленном умолчании как именно он это делает.

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

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

Кстати, я категорически против префикса «cls», особенно когда он используется в именах интерфейсов. Это глупый бессмысленный и длинный префикс. Нет, по сути, в VB ситуаций, когда имя класса может быть перепутано с именем чего-то другого. А раз такой ситуации нет, то и префиксы бессмысленны и только имена раздуваются. Для интерфейсов принято (очень сильно принято) использовать префикс «I». Для классов можно использовать более короткий префикс «C», а можно и вообще ничего не использовать. У меня во многих проектах принято такое правило: если класс — из тех, что олицетворяют служебные программистские объекты, вроде таймеров, буферов, списков, файлов, логов, ошибок, очередей, блокировок, то в именах таких классов я не использую префикс «С». Если же класс олицетворяют объекты предметной области (в игре — машина, дерево, снаряд, в логистической программе — машина, рейс, маршрут, в медифинской системе — пациент, врач, обращение, направление), то имена таких классов начинаются на «C». Эта концепция очень хорошо стыкуется с тем, что во многих языках (включая VB) часто уже есть набор классов, образующих программистский инструментарий, и в их именах никаких префиксов нет — тогда получается, что я продолжаю этот подход, и расширяю подмножество классов, образующих «инструментарий для более высокоуровневых целей», своими, а подмножество классов предметной области имеет отличительный признак.

В контексте игродельной разработки очень правдоподобным примером использования интерфейсов был бы интерфейс IDestructable с одним единственным методом TakeDamage с параметрами, определяющими количество «урона» и тип урона. Сам интерфейс содержал бы просто объявление этого метода, и не содержал бы никакого кода, так как это бессмысленно.

Этот интерфейс давал бы возможность ряду классов провозгласить, что олицетворяемые ими объекты являются уничтожимыми и могут принимать урон (от чего угодно). Не все классы бы поддерживали этот интерфейс, а только лишь те, которые могут быть уничтожены от каких-то игровых событий. Например классы CPlayer, CBird, CMonster поддерживали бы этот интерфейс, а классы CSun, CCloud (обычно в играх нельзя никаким образом уничтожить солнце или облако не небе).

Тогда в случае, если в игровом пространстве произошёл взрыв, можно было бы пройтись по массиву/коллекции всех объектов, взять из них подмножество тех, которые способны воспринимать урон, и вызвать метод TakeDamage.

Код: Выделить всё
Sub Explosion(pos, damage_radius)
    For Each obj in AllGameObjects
          If Distance(obj.Position, pos) <= damage_radius Then
               ' Этот объект в зоне поражения: проверяем, способен ли он воспринимать урон
               If TypeOf obj Is IDestructable Then DamageByExplosion obj
          End If
    Next obj
End Sub

Sub DamageByExplosion(ByVal Victim As IDestructable)
    Victim.TakeDamage 100
End Sub


Внутри процедуры DamageByExplosion переменная Victim может ссылаться на экземпляр класса CMonster, а может ссылаться и на экземпляр класса CBird. А может — на экземпляр класса CBarrel. Программист при этом абстрагирует себя и код от того, на что именно ссылается переменная. Он придумал общий механизм взаимодействия между причинителями вреда и получателями вреда. Механизм, позволяющий одной стороне ничего не знать о другой.

В программе может быть 20 разных мест, где кому-то (не важно кому) причиняется вред, и 30 типов сущностей, которым каким-то образом (не важно каким) может быть причинён вред. Вся мощь интерфейсов в том, что причинителям вреда вообще не нужно заботиться о том, кому они причиняют вред и какая специфика получения вреда именно тем типом объектов, с которым они взаимодействуют. Получателям вреда не надо заботиться о том, кто и в результате чего им наносит урон.

Вместо того, чтобы запрограммировать 20×30 = 600 случаев взаимодействия конкретного причинителя вреда с конкретным получателям вреда, ты в 20 местах делаешь вызов метода TakeDamage, вообще ни капли не задумываясь о том, какая будет реакция объекта на причинение урона. А в 30 классах делаешь Implements IDestructable и делаешь реализацию метода TakeDamage.

У каждого класса, поддерживающего IDestructable реализация TakeDamage будет своей, не похожей на другие классы. У классов, не поддерживающих этот интерфейс, этого метода вообще не будет.

У класса CBird код внутри метода TakeDamage будет, например, таким, что какой силы бы ни был урон, птичка сразу умирает и начинает падать вниз. В классе CMonster в реализации метода TakeDamage был бы совсем другой код — он бы в зависимости от степени урона воспроизводил бы соответствующий звук боли, или просто, даже вне зависимости от степени урона, воспроизводил бы каждый раз разные звуки боли, чтобы не было повторений. Кроме того, он бы переводил объём урона в количество единиц, отнимаемых у показателя «здоровье», отнимал бы показатель здоровье, сравнивал с нулём, и если показатель стал меньше 0, переводил бы статус монстра в состояние «мёртв», запускал бы звук смерти, анимацию смерти.

У класса CBarrel (взрывоопасная бочка) реализация была бы вообще другой — ни как у птички, ни как у монстра. Реализация, была бы, например такой, что начинка метода TakeDamage просто считает, сколько раз бочка испытала «урон» (попадание пули, например). Первое попадание, к примеру, игнорировалось бы, а второе попадание запускало бы таймер и анимацию и звук горения. А после срабатывания таймера бочка взрывалась бы — и сама бы причиняла урон, вызывая метод TakeDamage у рядом расположенных объектов.

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

Какие-то места кода вызывают метод TakeDamage у объектов, поддерживающих интерфейс IDestructable. А разнородные объекты, реализуя этот интерфейс, имели бы разный код внутри своего метода TakeDamage, определяющий разную реакцию каждого класса на причинение урона. Во всяком случае, взрывающаяся граната и взрывающаяся бочка вызывали бы функцию Explosion, отвечающую за вообще любые взрывы в игре. А функция Explosion просто перебирает все объекты, смотрит, поддерживают ли они интерфейс IDestructable, то есть являются ли уничтожимыми, и если да — то вызывает метод TakeDamage. И коду без разницы, что там за объект попал под горячую руку — птичка это или бочка.

И как бонус — нельзя будет вызвать метод TakeDamage у объекта, который не поддерживает получение урона. У такого объекта не будет метода TakeDamage. Ссылку на такой объект не получится присвоить переменной, объявленной как As IDestructable — будет ошибка.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Создание экземпляра из выбранного класса.

Сообщение Don Leno » 31.12.2018 (Пн) 7:17

Хакер, спс за подробные объяснения.
Я просто пытаюсь опробовать то что мне объяснили. Но твой код теперь поясняет гораздо больше, чем я понимал насчет интерфейсов. На реальных примерах конечно легче разбираться! И я даже не подозревал что можно найти применение интерфейсам таким вот тобою описанным способом.

Код: Выделить всё
             
               ' Этот объект в зоне поражения: проверяем, способен ли он воспринимать урон
               If TypeOf obj Is IDestructable Then DamageByExplosion obj


А чтобы проверять объект, я вообще подобное впервые вижу! И меня просто удивляет как можно многое упростить!

Насчет пробного исходника, я удалил строчку Implements и был немало удивлен исходник и вправду работает без этой строчки. Но целенаправленно я не собирался создавать такого "фейкового" исходника)) Суть была реализовать и испробовать то о чем писал The trick:

Т.е. для класса CSomeClass это выведет 5, а для CSecondClass это выведет 10. Тут как раз и видно всю мощь полиморфизма на основе интерфейсов


И к сожалению моя задумка оказалась не правильной.

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Создание экземпляра из выбранного класса.

Сообщение The trick » 31.12.2018 (Пн) 10:21

Суть была реализовать и испробовать то о чем писал The trick:

Я писал о другом:
The trick писал(а):Теперь мы можем написать Dim c As CSomeClass, а дальше уже писать как Set c = New CSomeClass (в этом случае CSomeClass указывает на класс) так иSet c = New CSecondClass, т.к. у нас оба класса реализуют интерфейс CSomeClass.

У тебя же объявлено 2 ссылки на разные интерфейсы, к тому же объявленные как As New. В чем смысл?
Чтобы увидеть смысл интерфейсов следовало объявить их как минимум так:
Код: Выделить всё
Dim ship As clsShip
Dim pirate As clsShip

. . .

Set ship = New clsShip
Set pirate = New clsPirate

. . .

ship.MoveX (...)
pirate.MoveX(...)


. . .

А по-нормальному создать отдельный интерфейс и имплементировать его обеими классами.
UA6527P

Teranas
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 224
Зарегистрирован: 13.12.2008 (Сб) 4:26
Откуда: Новосибирск

Re: Создание экземпляра из выбранного класса.

Сообщение Teranas » 31.12.2018 (Пн) 12:03

По поводу нижней статьи Хакера

Почти со всем согласен.
Понимаю, что Хакер пытался объяснить работу интерфейсов.
Но кину одну маленькую ложку перца.

Если объектов 600, то да, этот подход применим, но если объектов гораздо больше, подобная проверка всех объектов, да ещё в цикле с другими расчётами приведёт к катастрофической потере FPS.
Задача конечно решаемая, но об этом стоит помнить.
С уважением, Андрей.

Don Leno
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 421
Зарегистрирован: 13.10.2013 (Вс) 14:05

Re: Создание экземпляра из выбранного класса.

Сообщение Don Leno » 31.12.2018 (Пн) 12:38

The trick я вообще не понял разве так возможно:

Код: Выделить всё
Dim ship As clsShip
Dim pirate As clsShip

. . .

Set ship = New clsShip
Set pirate = New clsPirate


Я выложу подправленный пример. Проверите?! Исходник Interface_mod.rar

создать отдельный интерфейс и имплементировать его обеими классами.

Исходник Interface_mod2.rar. Правильно ли я сделал?

To Teranas
Хакер попросту описал пример использования, а кол-во в данном случае не важно. Но спс за участие!

To Хакер Вот теперь осталось реализовать работу с интерфейсами, как в твоем примере с "бочками и птичками")) Исходник Damage.rar. В нем создается 10 бочек по случайным позициям и прочностью. Также случайно выбирается - бочка может получить урон или она неуничтожима. Бочки рендерятся в виде квадратиков (примера ради)

Всех с наступающим новым годом!
Вложения
Interface_mod.rar
(2.42 Кб) Скачиваний: 181
Interface_mod2.rar
(2.8 Кб) Скачиваний: 148
Damage.rar
(3.14 Кб) Скачиваний: 174

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Создание экземпляра из выбранного класса.

Сообщение The trick » 31.12.2018 (Пн) 18:13

Don Leno писал(а):Я выложу подправленный пример. Проверите?! Исходник Interface_mod.rar

Вот так правильнее.
С Наступающим!
UA6527P

След.

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex-бот и гости: 53

    TopList