Въпрос само за машини - ООП


0
Как мога ако имам някаква абстрактна колекция и не знам вътре кой конкретен клас ще сложа в тази колекция , да го достъпя...Мисля че това е най-основния проблем в абстракцията.Дори ми е трудно да задам въпроса като хората.

в C# OOP от IliyaST (251 точки)


Отговори



0
Често се случва спокойно. 
За да разбереш как да постъпиш е важно да знаеш какво искаш да правиш с колекцията. 
Примерно: Искаш колекцията да се обхожда и на всеки член да се вика DoSomething() метода. Правиш интерфейс, в който има само този метод и правиш IList<IDoSomthing> и буташ вътре. Ти не знаеш какъв клас ще сложиш, но в крайна сметка трябва да знаеш какво искаш да се случва с колекцията - просто подай правилния интерфейс (или правилния абстактен или НЕ абстрактен базов клас). 
Опитах се да отговоря възможно най-абстрактно. Ако дадеш повече информация вероятно мога да помогна повече. 

от StoikoNeykov (2621 точки)


1

Това е типичен проблем на начинаещия ... :)

Идеята е да не правиш просто "колекция от неща". Колекцията трябва да е от неща, които да могат да се ползват едно вместо друго. Абстрактността трябва все пак да е до някаква граница - такава, каквато да ограничи елементите в колекцията до такава степен, че те да са взаимозаменяеми във функциите, за които ще бъдат ползвани.

Пример: имаш колекция от геометрични елементи. Правилния начин е там да слагаш само правоъгълници, триъгълници, окръжности и т.н. Тогава ще може да викаш методи с които да получаваш техния периметър или площ без да се интересуваш как точно се изчисляват за конкретната фигура. Но примерно поставянето на котки или зайци в нея... никак не е добра идея. Да, ако си извратен тип можеш да утепеш заека, да го одереш и да измериш площта на кожата му, само и само за да имплементираш метод за площ на заек... :)


от JulianG (5316 точки)


0

Случая имам ICollection<IPlayer> players, като имам abstract class Player > Human, Ork, Undead и всеки от тях наследява сътветно следния клас Human > Mage , Ork > Warrior и Undead > rogue....И ситуацията че в списъка създавам Warrior,Mage или Rogue и съответно когато от engina се извика Gosho(name of player) Cast FireBolt(). 

case "Cast":
                        if (currentCommandLine[2] == "Firebolt")
                        {
                            this.players.Where(p => p.Name == nameOfPlayer).Select(p => p.FireBolt());                           
                        }

обаче проблема е че p ми е от IPlayer.....И то не знае още че там има mage, та ми подсказаха с проверка някаква да стане дали има такъв клас. Но как точно да стане каста ?


от IliyaST (251 точки)

1
Зависи по колко действия (магии) има всеки тип Player. 
Ако всеки има по 1 специфично действие може самия клас Player да има метод:
public abstract void (предполагам е стринг - т.е. връща текст че го е направил) DoMagic(...); 
и съответно във всеки от наследниците да го имплементираш по различен начин т.е. да се възползваш от полиморфизма както колегата по-горе е дал пример с геометрични фигури. 
Това не значи да създаваш допълнителни методи само, за да успееш да се възползваш от това. Правиш го само ако примерно имат точно по 1 магия ... или 2 магии (DoDefenceMagic(), DoAttackMagic()). Мисълта ми е наистина да намериш прилики и да ги използваш. 
! Не се изкушавай да правиш на всеки тип Player FireBolt(), това е грешна стратегия. Създаваш абстракция само, когато има нужда и може да се визползваш и по-скоро когато наистина 2 предмета имат нещо общо. 

от StoikoNeykov (2621 точки)