Делаю инвентарь. Есть основной скрипт Item, где указаны основные общие параметры предметов. От него наследуется скрипт Equipment, в котором указаны параметры, присущие только отдельным предметам (чтобы удобнее было создавать различные типы) и реализуется он через ScriptableObject. После создания предмета я пытаюсь обратиться к параметру (который есть только в скрипте Equipment) через Item - но мне пишет, что в Item нет таких переменных! Т.е. получить я могу только те переменные, которые хранятся именно в Item, а все, что в Equipment я не вижу, хотя он наследуется от Item. Как же мне тогда получить нужные мне переменные?
Asked
Active
Viewed 147 times
0
-
Намёк: лучше один раз показать, чем 10 раз рассказать. – Алексей Шиманский Jan 10 '23 at 11:20
-
По коду: наследовать equipment от item - немного не правильно. item - штука, equipment - совокупность штук. Это как отнаследовать автомобиль от колеса)) – Алексей Шиманский Jan 10 '23 at 11:21
-
@АлексейШиманский да я это и сам понимаю, просто получается что я обращаясь к машине хочу получить данные колеса, а оно не дает. Вот и спрашиваю - как это сделать тогда правильно? – skroliks Jan 10 '23 at 11:24
-
Нет, вы ничего не поняли. ............ а как сделать: читайте намёк – Алексей Шиманский Jan 10 '23 at 11:25
-
@АлексейШиманский так что именно я неправильно сделал то? Item - это базовый класс с основными параметрами, а Equipment - имеет все то же, что и Item + свои отдельные параметры, поэтому и наследуется от него - по-моему все логично? – skroliks Jan 10 '23 at 11:31
3 Answers
2
Item foo = new Equipment(); // условно
foo.slot // "Item" не содержит определения "slot"
Equipment наследуется от Item, но не на оборот, поэтому с чево бы Item знать не то что о полях Equipment, а вообще о существовании этого класс.
if (foo is Equipment efoo)
rightSlot = efoo.slot == targetSlot;
Yaroslav
- 7,040
-
Да я это и сам понимаю. Надо найти просто как сделать обратный ход и получить все таки данные нужные. Ваш вариант либо не работает, либо я что-то не правильно понял.. – skroliks Jan 11 '23 at 06:01
0
Это называется инкапсуляция, при апкасте к родительскому классу, все состояния и поведение дочерного скрывается. Насчёт решения, можешь пробывать даункастить объект обратно к Equipment. Допустим так:
if (object1 is Equipment equipment)
equipment.нужные_поля
-
-
2
-
1Это называется инкапсуляция - нет, вы инкапсуляцию с наследованием перепутали. Не надо так. Это разные, никак не связанные друг с другом термины ООП. – aepot Jan 11 '23 at 21:10
-
1Это называется даункастинг - нашел уже и ниже напишу как я сделал, хотя Ваш вариант тоже работает, спасибо! :) – skroliks Jan 12 '23 at 06:28
-
@aepot почему же это не инкапсуляция, в данном случае она выражена сокрытием поведений и состояний класса от которого мы приводимся к базовому. Кажется это называется сокрытие реалезации – Gilly Jan 12 '23 at 10:33
-
@aepot и я не перепутал инкапсуляцию с наследованием в том числе из за контекста, где автор вопроса говорил об "исчезновение" полей производного класса – Gilly Jan 12 '23 at 10:38
-
-
@Gilly инкапсуляция к наследованию не имеет никакого отношения. Вы никак не сможете модификаторами доступа оставить член класса доступным после апкаста если его нет у родителя. 2 большие разницы. Инкапсуляция делается не апкастом, она вообще про другое. А связаны термины ООП именно самим ООП. То что член класса становится недоступным при апкасте, это особенность наследования, а не инкапсуляции. Эта особенность говорит о том, что его именно нет у родителя, а не то что он скрыт. Утверждение что "инкапсуляция - это сокрытие" ошибочно, у меня один кандидат, сказавший это, собеседование не прошел. – aepot Jan 12 '23 at 10:46
-
@aepot ну я к вам собеседоваться и не собираюсь, я с вами не согласен, но последующие аргументы врятли вас переубедят и будят повторяться. Так что удачи – Gilly Jan 12 '23 at 11:12
-
@Gilly конечно не переубедят, ведь у вас их нет. Не надо со мной соглашаться или не соглашаться, надо найти умную книжку по основам ООП, а лучше 2 от разных авторов, чтоб наверняка, и вдумчиво почитать. – aepot Jan 12 '23 at 11:25
-
-
-
@Gilly вам кажется, мне просто лень в сообщения смайлики втыкать. :) https://ru.stackoverflow.com/q/416584/373567 – aepot Jan 12 '23 at 14:07
0
Вариант выше оказался правильным, только я сделал немного по другому и это называется даункастинг (Downcasting):
// item это производная от Item
Equipment equipment = (Equipment)item; //Downcasting
int needstat = equipment.damagePoints; //damagePoints - это один из параметров у Equipment
Всем остальным тоже спасибо за ответы!
-
Стоит иметь в виду, что если в Item будет лежать не Equipment, а другой тип наследника, в данной реализации вы получите исключение
InvalidCastException. – aepot Jan 12 '23 at 10:48