Професионална програма
Loading...
+ Нов въпрос
ambiorix avatar ambiorix 640 Точки

Използване на overriden property за модифицане на друго property от същия клас наследник

Здравейте.

В предна инстанция на курса чух, че е по-правилно ако искаме да променим някое свойство на клас наследник (например да го увеличим с 50%) то е по-добре да се направи въпросното свойство виртуално в бащиния клас и да се презапише в наследника. Нямах проблем с това когато се налага да се направи с константа, но как е правилно да се направи ако текущото свойство зависи от друго свойство на същия клас?

 

Ето тук например(от последния изпит) ми трябва EnergyRequirement да го разделя на SonicFactor като и двете са свойства на клас SonicHarvester който наследява Harvester: https://github.com/gaydov/Softuni-OOP-Basics/blob/master/Exams/Exam-16th-July-2017/HarvestersModels/SonicHarvester.cs

 

Не успях да го направя, защото SonicFactor все още няма стойност и винаги деля на 0.

 

Ето имплементацията когато просто се ползва константа: https://github.com/gaydov/Softuni-OOP-Basics/blob/master/Exams/Exam-16th-July-2017/HarvestersModels/HammerHarvester.cs

 

Та как е най-правилно да се направи това и изобщо възможно ли е да е по-добрия начин с презаписване на EnergyRequirement по някакъв начин?

0
C# OOP Basics 19/07/2017 22:02:43
Martin.T avatar Martin.T 35 Точки
Best Answer

Колега тъй като и аз питах същото като теб няколко пъти най-накрая на изпита направих това 

public override double EnergyRequirement
    {
        get { return base.EnergyRequirement / this.sonicFactor; }
        
    }

 

Дали е правилно ? Ами незнам :D работи търсих инфо в stackoverflow там пиши, че като override-ваш property логиката ти отива в сетъра аз пробрах и получавах безкраен цикъл....

 

2
Pilgrimage avatar Pilgrimage 515 Точки

Няма да се получи зацикляне в сетъра, ако се разграничат базовото пропърти от овъррайда. Т.е. със синтаксиса :

this.EnergyRequirement = base.EnergyRequirement / this.SonicFactor;

Бях експериментирал подобни конструкции в една задача. В овъррайднатият метод можеш с base. да викаш едноименният предшественик и няма проблем - работи си.

0
20/07/2017 08:39:22
ambiorix avatar ambiorix 640 Точки

Martin.T това е ново двайсе :)  Изглежда добре обаче. И аз не знам доколко е валидно.

Pilgrimage, получава си се зацикляне, защото реално ползваш едно и също нещо. Може и да не го структурирам като хората все пак.

0
20/07/2017 08:15:58
Pilgrimage avatar Pilgrimage 515 Точки

И аз като теб имах същите съмнения. Но го проверих (не сега, преди седмица). И се оказа, че тази конструкция работи.
Защото когато имаш override, вече не е едно и също. :-)
Всъщност експеримента ми беше свързан с това да имам private поле, на което да override-вам пропъртито в наследника.

0
20/07/2017 08:38:54
Pilgrimage avatar Pilgrimage 515 Точки

В конструктора трябва да бъде :

this.EnergyRequirement = base.EnergyRequirement / this.SonicFactor;

и работи като слънце. :-)

0
19/07/2017 22:12:16
ambiorix avatar ambiorix 640 Точки

Това в сетъра ли имаш предвид? Защото там предизвиква StackOverflow.

0
Pilgrimage avatar Pilgrimage 515 Точки

Извинявай, допълних си отговора.
Имам предвид в конструктора.

0
Pilgrimage avatar Pilgrimage 515 Точки

StackOverflow се получава, когато пропъртито извиква самото себе си.... и става безкраен цикъл, който препълва стека.

0
ambiorix avatar ambiorix 640 Точки

В конструктора е ясно, аз вече съм го направил така. Въпросът е как да стане в тялото на свойството(ако изобщо може):

public override double EnergyRequirement
{
}

 

Търсих в интернет многократно, но не откривам засега нищо ясно(не съм сигурен с каква терминология да търся).

0
19/07/2017 22:18:11
Pilgrimage avatar Pilgrimage 515 Точки

Може, но не го намирам за добра идея!

Защото трябва да подадеш на пропъртито една стойност, а в полето да се запише друга!
По-читаво е да се изчисли в конструктора необходимата стойност (т.е. да се умножи base.EnergyRequirement по нужното) и да се подаде за запис на this.EnergyRequirement

 

 

0
ambiorix avatar ambiorix 640 Точки

И според мен това е по-нормално в конкретния случай. Но пак казвам, че в предна инстанция на курса споменават, че такива сметки не се правят в тялото или в сигнатурата на конструктора(това пък е най-зле). Дори се отнемали точки за това при ръчното оценяване. Затова идеята ми е дали има правилен начин това да се прави в тялото на свойството или този случай е изключение и е приемливо да е в тялото на конструктора.

0
Pilgrimage avatar Pilgrimage 515 Точки

Това и аз го гледах, но с оглед на задачата не го намирам за универсално вярно.
Имаше въпрос във фейсбук групата, където водещи потвърдиха, че е по-добре да е в конструктора.
Още повече, че ако впоследствие ти се наложи да запишеш друга стойност в полето/пропъртито - няма да можеш, защото подадената стойност ще бъде модифицирана.
Визирам задачата NFS.

0
19/07/2017 22:40:34
Tangrila avatar Tangrila 21 Точки

В условието пише при ИНИЦИАЛИЗАЦИЯ т.е. само първия път като му слагаш стойност. т.е. в КОНСТРУКТУРА.

0
Martin.T avatar Martin.T 35 Точки

Правилно бе колега питаме кое е равилно то ясно, че ще го намуаш в конструктора питаме как се прави кой са добрите практики etc .....

0
ambiorix avatar ambiorix 640 Точки

Абстрахирай се от условието. Задачата е дадена само за пример. Идеята е как генерално трябва да се прави.

0
Tangrila avatar Tangrila 21 Точки

:D Не си направих труда особено. Можеш да си маркираш на Мартин отговора за верен. Така се прави.

0