|
Тема |
Re: Квадратът правоъгълник ли е? [re: Питaщ] |
|
Автор |
josarjan () |
|
Публикувано | 04.10.02 17:46 |
|
|
Предполагам че, повечето отговори в този клуб (ще) са: Да, квадрата е правоъгълник.
Виж, ако питаш в клуб "Програмисти" могат и да ти дадат друг отговор, че не е.
Надолу това, което съм писал е малко Офф-Топик, щото е насочено към програмирането, а не пряко към математиката.
Значи какво имам предвид (това е подобно на класическата дилема "Окръжността елипса ли е" в обектно-ориентираното моделиране).
Идеята, е там е да се покаже как наследяването понякога уж очевидно всъщност трябва да се внимава с него. Т.е. целта е да се покаже какво точно означава връзката между два класа да е "is-a" (наследяването трябва да показва точно това). Тоест - същия въпрос, ама в друг контекст.
И така:
Имаме клас:
class Rect
{
void setWidth(int widht);
void setHeight(int height);
int getWidth();
int getHeight();
int calcArea();
// others mathematical functions
}
Въпросът е - може ли да използваме този клас за да направим квадрат, използвайки наследяване (което трябва да се използва за да покаже, че единия тип/клас *е* (is-a връзка) от другия тип/клас. Т.е. нещо от сорта на:
class Square extens Rect
{
void setWidth(int width) { setSize(width); }
void setHeight(int height) { setSize(height); }
void setSize(int size) { this.size = size; }
}
Ами оказва се, че това не е много добра идея. Защо? Ами много просто - ако имаш някакъв клиент на класа Rect, той трябва да работи (в този случай) и с класа Square. Да ама ако имаме следния код:
void f(Rect r)
{
r.setWidth(5);
r.setHeight(4);
System.out.println("calcArea() of " + r.getWidth() + "x" + r.getHeight() + "rectangle = " + r.calcArea());
}
Това нещо трябва да изкара:
calcArea() of 5x4 rectangle = 20
Да ама в случая с квадрат това няма да сработи както трябва. Защо няма да сработи - ами защото сме предположили, че за класа Rect имаме следния инвариант: ако извикаш setWidth() и после getWidth() трябва да получиш същия резултат. Същото и за getHeight(). За да може клас да наследи друг такъв, той трябва да запазва условията (инвариантите, предусловията и следусловията на методите и т.н.), валидни за базовия. В нашия случай няма такова нещо. Ето защо подобна реализация не е удачна. Разбира се, всичко това зависи от това как си си дефинирал базовия клас (най-често интерфейс) и по-точно условията на които трябва да се подчинява той (и съответно тези дето го наследяват/реализират).
Така де - идеята ми беше, че примерно в програмирането подобен модел не е много удачен - да представяш квадрата като правоъгълник. Разбира се, за да се използва функционалността на правоъгълника (тъй като същите формули за валидни и за квадрата - формули за лице, периметър и т.н.) най-правилното решение (според мене) е да се направи клас Square, който да си aggregate-не един обект Rect и да delegate-ва всички извиквания към него. Или нещо такова.
Но не е добре външните клиенти да виждат квадрата като правоъгълник.
Още веднъж - извинявайте за off-topic-а.
|
| |
|
|
|