[Homework] Advanced JS - Prototype Chain and Inheritance
Имам проблем с 2-ра задача.
Проблема ми е във функцията за създаване на сегмент (редове 95-104).
Тъй като линията и сегмента имат еднакви пропъртита (A[x,y], B[x,y], color) - искам сегмента просто да наследи линията.
Като го мина през дебъгера, излиза че проблема е когато тръгна да създавам init на segment (97 ред), програмата отива в конструктора на line (базовия клас за segment, ред 80) и там зацикля с
"too much recursion" в браузъра и
"RangeError: Maximum call stack size exceeded" в nodejs
струва ми се, че проблема е някъде в this-овете, но не съм сигурен...
Някакви идеи? :)
Аз го направих с точка и двете. Така ми се стори по-логично. И аз реших че е по-добре триъгълника да наследи правата. Shape има point и color, защото това е общото между всички обекти. Така има градация: точка -> отсечка->затворен полигон. Ето ги двете задачи:
1. Geometry-PseudoClassical-Inheritance
2. Geometry-Prototype-Inheritance
С гетъри, сетъри и валидации стават 200 реда код. Освен това изглежда грозно, а логиката - трудна за проследяване. Но какво да се прави...
Това, че всички фигури имат поне по една точка - така е, но излиза, че едната точка от триъгълника се счита за базова, а другите - някакви допълнителни, което не е много ясно като логика. По принцип с геометричните фигури са доста объркани нещата на моменти и трябва много да се внимава с наследяването.
Триъгълника да наследява правата не мисля, че е правилно, триъгълника не е вид права.
Иначе че излиза дълго - еми като сме свикнали да валидираме няма начин...
Според мен пък е доста логично. Фигурата с N точки наследява фигурата с N-1 точки, както отсечката наследява точката. Така новия конструктор има да добави само една точка. Триъгълника не е вид права но и правата не е вид точка. Или е - все е тая. Тези абстракции си ги правим да си услесним писането и има много модели - някои са по-интуитивни, а други не.
Наследяването е връзка "is a", така че триъгълникът няма как да наследява правата или правата точката, просто не е коректно ООП.
Наследяването е моделиране на реалния свят и не е редно да се прави само за удобство и да се спести малко код; излиза, че може да дефинираме триъгълник, след това четириъгълник, който го наследява, понеже добавя само още една точка, след това петоъгълник, който добавя още една и т.н. Може да е удобно, но не е правилно.
Т.е. не мога да се съглася с твърдението ти, че "Тези абстракции си ги правим да си услесним писането". Това, че си улесняваме писането е страничен ефект на пренасянето на взаимовръзки от реалния свят в света на програмирането чрез принципите на ООП, което ни позволява да не повтаряме общите характеристики на свързани обекти.
Според мен е много удобно от ООП гледна точка и освен това е математически коректно. Пестенето на писане в случая е страничен ефект(както каза). Нали точно това е абстракция. Ако фигурите на този свят бяха само 4-5 -разбирам. В крайна сметка геометрията тук е на ниво 3-ти клас. А как се конструира полигосн с 257 ъгли? Правим си клас със 257 properties? Странно е. За какво ни е тогава наследяването.
ПП: Реалния свят не е в крайна сметка само това което виждаме. Ако програмирането трябва да описва просто някакви неща би било много жалко. Геометрията от гледна точка на Теория на групите например е нещо съвсем различно от това което си представят повечето хора. Но това си е мое мение. Няма повече да задълбочавам.
Правилният начин е да имаме абстрактна фигура (полигон), която има списък с точки. Всяка конкретна фигура си знае колко точки ще има в този списък и какво друго да добави.
Пак казвам, наследяването при геометрията е трудно да се измисли - дали отсечката е вид права, дали елипсата е вид окръжност или окръжността вид елипса и т.н. Има варианти. Но не е правилно нито от ООП гледна точка, нито от математическа триъгълника да наследява правата или петоъгълника да наследява четириъгълника. Не вярвам който и да е от по-опитните колеги да не се съгласи в това отношение.
Здравей! Смятам, че твоя код е най-правилен и абстрактен, най-много се доближава до кода от последния изпит - валидации, сетъри, гетъри. Вместо да пишеш имената на фигурите в метода toString можеш да ползваш this.constructor.name - това ще ти изведе името на фигурата: