И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 03.03.07 07:48
Оценка: +6
Все-таки математика права, квадрат это прямоугольник, и в приведенном ниже коде (на Java) нет ничего неприличного:

class Rectangle {
    int width, height;

    public Rectangle(int width, int height) {
        this.width = width;
        this.height = height;
    }
    public int Width() {
        return width;
    }
    public int Height() {
        return height;
    }
}

class Square extends Rectangle {
    public Square(int side) {
        super(side, side);
    }
}


А если захотелось добавить методы SetWidth и SetHeight, так это уже нечто за пределами математических понятий "квадрат" и "прямоугольник". В математике объекты (не в смысле ООП объекты, нет, в обычном, человеческом смысле объекты), так вот, в математике объекты как правило неизменные, то есть умножая одну матрицу на другую получаем третью, а вовсе не модифицируем первую. В программировании такие объекты тоже встречаются, например String в Java или .NET; и если Rectangle и Square определить неизменными, они вполне могут быть связаны отношением наследования.
Re: И все-таки квадрат это прямоугольник
От: FDSC Россия consp11.github.io блог
Дата: 03.03.07 09:12
Оценка:
Здравствуйте, igna, Вы писали:

I>Все-таки математика права, квадрат это прямоугольник, и в приведенном ниже коде (на Java) нет ничего неприличного:


I>А если захотелось добавить методы SetWidth и SetHeight, так это уже нечто за пределами математических понятий "квадрат" и "прямоугольник". В математике объекты (не в смысле ООП объекты, нет, в обычном, человеческом смысле объекты), так вот, в математике объекты как правило неизменные, то есть умножая одну матрицу на другую получаем третью, а вовсе не модифицируем первую. В программировании такие объекты тоже встречаются, например String в Java или .NET; и если Rectangle и Square определить неизменными, они вполне могут быть связаны отношением наследования.


И зачем такое нужно??? Это уже ближе к ФП...

Вот представь. Скажем, есть у меня задача разбить плоскость на несколько прямоугольников. Я как-нибудь итеративно это буду делать (ну, я "от балды" пример привёл), каждую итерацию изменяя размеры прямоугольника. И что, я буду ради этих мат. сущностей себе удобство программирования портить????

В этом вообще нет ничего страшного. Его можно и так наследовать, и по другому, а иногда — вообще никак. Всё зависит от конкретной задачи. Программы никогда не были идеальными с точки зрения логики... и не будут. Наследование вообще бывает чисто техническое — увидел, что кода половина копируется copy-past, сделал наследование. У меня так часто бывает, а как уж они там соотносятся в виде моделей реальной среды... кто их знает.

Потому что программный код — это модель ПРОГРАММЫ, а не реальных вещей, и там мы можем делать всё, что хотим на свой страх и риск... ну, а потом за это отвечать, может быть, придётся
Re[2]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 03.03.07 09:57
Оценка: +2
Здравствуйте, FDSC, Вы писали:

FDS>И зачем такое нужно???


Да может быть практически и не нужно, только чтоб ясность была.

Нередко попадается мнение, что то "в программировании квадрат — не прямоугольник", то вообще "прямоугольник нужно наследовать от квадрата". И хотя объяснение кажущемуся парадоксу имеется, вот оно например: http://www.objectmentor.com/resources/articles/lsp.pdf, но очень уж там много, намного больше чем нужно.

На самом деле обьяснение может быть совсем простым: квадрат это прямоугольник (как и в математике), но изменяемый квадрат не является изменяемым прямоугольником. В программировании обычно объекты изменяемые, ну мы и привыкли называть изменяемые квадрат и прямоугольник просто квадратом и просто прямоугольником, а потом вдруг вспоминаем про школьные квадрат и прямоугольник, и все, вот они три сосны и блуждающие среди них программисты.
Re: И все-таки квадрат это прямоугольник
От: VoidEx  
Дата: 03.03.07 10:33
Оценка: 1 (1) +1 -4
Здравствуйте, igna, Вы писали:

I>Все-таки математика права, квадрат это прямоугольник, и в приведенном ниже коде (на Java) нет ничего неприличного:


Все здесь неприлично. Наследование — это расширение понятия, когда все экзмепляры A являются также экзмеплярами B, но ни один экзмепляр B не является экземпляром A.
Тут же квадрат — это частный случай прямоугольника, да он им является, но из всего множества возможных прямоугольников некоторые являются квадратами.
Re: И все-таки квадрат это прямоугольник
От: jedi Мухосранск  
Дата: 03.03.07 11:06
Оценка: 1 (1) +3 -1
Здравствуйте, igna, Вы писали:

I>Все-таки математика права, квадрат это прямоугольник, и в приведенном ниже коде (на Java) нет ничего неприличного:


Мне эти разговоры о наследовании квадрата от прямоугольника (или наоборот) всегда казались глупыми. На самом деле это два разных типа, но:
1) преобразование типа КВАДРАТ->ПРЯМОУГОЛЬНИК имеет смысл всегда;
2) преобразование типа ПРЯМОУГОЛЬНИК->КВАДРАТ имеет смысл только когда ширина равна высоте.

В информатике есть куча подобных примеров. Например типы short & long. Для них также верны утверждения (1) & (2), но почему-то никому в здравом уме не приходит в голову наследовать short от long (или наоборот)
... << RSDN@Home 1.2.0 alpha rev. 0>>
Ахринеть :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.03.07 11:23
Оценка: +2 :))) :)))
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: И все-таки квадрат это прямоугольник
От: FDSC Россия consp11.github.io блог
Дата: 03.03.07 11:27
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, FDSC, Вы писали:


FDS>>И зачем такое нужно???


I>Да может быть практически и не нужно, только чтоб ясность была.


Ну вот я и говорю: такие вещи только запутывают. Ясность — она в каждом конкретном приложении своя
Впрочем, никто не мешает пообсуждать это в десятый раз...
Re: И эти люди...
От: McSeem2 США http://www.antigrain.com
Дата: 03.03.07 18:46
Оценка: 6 (3) +3
...утверждают, что парадигма наследования имеет хоть какую-то практическую пользу?! Гы-сына-лол.

Здравствуйте, igna, Вы писали:

I>Все-таки математика права, квадрат это прямоугольник


Раз уж на то пошло, отношение наследования, которое связывает квадрат и прямоугольник притянуто за уши и не имеет ни малейшего практического смысла. Правильно надо делать так: Квадрат — это Фигура, Прямоугольник — это Фигура, Треугольник — это Фигура. Ну и т.д. А то, что в геометрии квадрат является прямоугольником, то этот "гондурас" вообще не должен беспокоить, ибо этот факт является ортогональным по отношению к понятию наследования. Но для реализации такого соотношения как "Квадрат — это Фигура, Прямоугольник — это Фигура" наследование вообще не нужно. Это вообще не является наследованием. По сути это — имплементация интерфейса, или даже можно сказать, реализация контракта.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[2]: И эти люди...
От: _nn_ www.nemerleweb.com
Дата: 03.03.07 21:19
Оценка: -1
Здравствуйте, McSeem2, Вы писали:

MS>...утверждают, что парадигма наследования имеет хоть какую-то практическую пользу?! Гы-сына-лол.


MS>Здравствуйте, igna, Вы писали:


I>>Все-таки математика права, квадрат это прямоугольник


MS>Раз уж на то пошло, отношение наследования, которое связывает квадрат и прямоугольник притянуто за уши и не имеет ни малейшего практического смысла. Правильно надо делать так: Квадрат — это Фигура, Прямоугольник — это Фигура, Треугольник — это Фигура. Ну и т.д. А то, что в геометрии квадрат является прямоугольником, то этот "гондурас" вообще не должен беспокоить, ибо этот факт является ортогональным по отношению к понятию наследования. Но для реализации такого соотношения как "Квадрат — это Фигура, Прямоугольник — это Фигура" наследование вообще не нужно. Это вообще не является наследованием. По сути это — имплементация интерфейса, или даже можно сказать, реализация контракта.


+1.

Вот надумалось:

Вариант 1:
interface IFigure
{}

interface IWidth
{
 public int Width
 { get };
}

interface IHeight
{
 public int Height
 { get };
}

interface IRectangle : IWidth, IHeight
{
}

class Rectangle : IRectangle
{
 public int Width
 { get { return _width; } };
 public int Height
 { get { return _height; } };
 
 private int _width;
 private int _height;
}

interface ISide
{
 public int Side
 { get };

 public int Angle
 { get };
}

interface IRhombus : ISide
{}

class Rhombus : IRhombus
{
 public int Side
 { get { return _side; } };

 public int Angle
 { get { return _angle; } };

 int _side;
 int _angle;
}

interface ISquare : IRectangle , IRhombus

class Square : ISquare
{
 public int Width
 { get { return _width; } };
 public int Height
 { get { return _height; } };
 
 private int _width;
 private int _height;

 public int Side
 { get { return _side; } };

 public int Angle
 { get { return _angle; } };

 int _side;
 int _angle;

 // код для сохранения _width == _height == _side && _angle == 90  :maniac: 
}


Что тут получили.
Квадрат он поддерживает интерфейс прямоугольника и ромба.
Однако появляется лишний код, который не связан с квадратом.

Решение через контракт мне нравится больше:
Вариант 2:
[Contract(ISquare, Width == Height)]
interface IRectangle
{...}

class Rectangle : IRectangle
{...}

[Contract(ISquare, Angle == 90)]
interface IRhombus
{...}

class Rhombus : IRhombus
{...}


Таким образом квадрат мы получаем из прямоугольника и ромба при сопоставлении определенных условий и избавляемся от бесмысленного кода Rectangle, где есть 2 переменные на сторону. При чем также избавляемся от ненужного угла в ромбе.

С другой стороны нужно как-то красиво организовать поддержку контрактом иначе можно сходу не понять в чем проблема:
void f(ISquare) {...}

Rectangle r1 = new Rectange(1,1); // r1 : ISquare
Rectangle r2 = new Rectange(1,2); // r2 : IRectangle

f(r1); // OK
f(r2); // Ошибка ??
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: И эти люди...
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 03.03.07 21:55
Оценка: 1 (1) +2 -1
Здравствуйте, _nn_, Вы писали:

Господи, зачем так все запутывать?
interface IRectangle
{
    int Width {get;}
    int Height {get;}
}

interface ISquare : IRectangle
{
    int Size {get;}
}

class Rectangle : IRectangle
{
    int _width;
    int _height;
    ...
}

class Square : ISquare
{
    int _size;
    ...
}

Предельно простой код, никаких нарушений LSP и никаких парадоксов.
... << RSDN@Home 1.2.0 alpha rev. 675 on Windows Vista 6.0.6000.0>>
AVK Blog
Re: И все-таки квадрат это прямоугольник
От: Владек Россия Github
Дата: 03.03.07 22:01
Оценка:
Здравствуйте, igna, Вы писали:

I>А если захотелось добавить методы SetWidth и SetHeight, так это уже нечто за пределами математических понятий "квадрат" и "прямоугольник".


В математическом смысле вы правы — можно ввести такую бинарную операцию над элементами множества, что результат её выполнения не будет принадлежать исходному множеству. Это свойство имеет название, но я его забыл. Пример: операция деления натуральных чисел, результат не всегда является натуральным числом (1/2=0.5).

I>В математике объекты (не в смысле ООП объекты, нет, в обычном, человеческом смысле объекты), так вот, в математике объекты как правило неизменные, то есть умножая одну матрицу на другую получаем третью, а вовсе не модифицируем первую.


Это мысленные абстракции — очень дешёвый материал, можно транжирить.

I>В программировании такие объекты тоже встречаются, например String в Java или .NET; и если Rectangle и Square определить неизменными, они вполне могут быть связаны отношением наследования.


Это всего лишь один из способов представления отношения между абстракциями, выбор которого иногда осуществляется при помощи здравого смысла и с учётом практической необходимости.

Что нового?
Джентльмены не матерятся, они просто говорят: "Your bunny wrote!"
Re[2]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 03.03.07 23:06
Оценка: 1 (1) +1
Здравствуйте, VoidEx, Вы писали:

VE>Все здесь неприлично. Наследование — это расширение понятия, когда все экзмепляры A являются также экзмеплярами B, но ни один экзмепляр B не является экземпляром A.


Предположим, что A наследует B, а x является экземпляром A. Поскольку "все экзмепляры A являются также экзмеплярами B", x является также экземпляром B. Поскольку "ни один экзмепляр B не является экземпляром A", то x не является экземпляром A. Получили противоречие, так как x не может одновременно являться экземпляром A и не являться экземпляром A. Следовательно, из предположения, что A наследует B, следует, что не существует ни одного экземпляра A. Хм...

Вышеприведенное рассуждение верно естественно только если "наследование — это расширение понятия, когда все экзмепляры A являются также экзмеплярами B, но ни один экзмепляр B не является экземпляром A".
Re[2]: И эти люди...
От: igna Россия  
Дата: 03.03.07 23:13
Оценка:
Здравствуйте, McSeem2, Вы писали:

MS>...утверждают, что парадигма наследования имеет хоть какую-то практическую пользу?!


Ась? Какие люди "утверждают, что парадигма наследования имеет хоть какую-то практическую пользу"?
Re[3]: И эти люди...
От: igna Россия  
Дата: 03.03.07 23:30
Оценка: +1
Здравствуйте, _nn_, Вы писали:

__>interface ISquare : IRectangle , IRhombus


Вот эта возможность унаследовать ISquare от IRectangle обусловлена отсутствием в последнем методов вроде SetWidth и SetHeight.

Так что классы ли, интерфейсы ли, наследовать квадрат от прямоугольника можно только если оба неизменны (как в математике).
Re[3]: И все-таки квадрат это прямоугольник
От: VoidEx  
Дата: 04.03.07 14:01
Оценка: -4
Здравствуйте, igna, Вы писали:

I>Здравствуйте, VoidEx, Вы писали:


I>Предположим, что A наследует B, а x является экземпляром A. Поскольку "все экзмепляры A являются также экзмеплярами B", x является также экземпляром B. Поскольку "ни один экзмепляр B не является экземпляром A", то x не является экземпляром A. Получили противоречие, так как x не может одновременно являться экземпляром A и не являться экземпляром A. Следовательно, из предположения, что A наследует B, следует, что не существует ни одного экземпляра A. Хм...


Вы прекрасно поняли, о чем я говорил, придираться к формулировке можете перед зеркалом.
Re[4]: И все-таки квадрат это прямоугольник
От: FDSC Россия consp11.github.io блог
Дата: 04.03.07 14:53
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Здравствуйте, igna, Вы писали:


I>>Здравствуйте, VoidEx, Вы писали:


I>>Предположим, что A наследует B, а x является экземпляром A. Поскольку "все экзмепляры A являются также экзмеплярами B", x является также экземпляром B. Поскольку "ни один экзмепляр B не является экземпляром A", то x не является экземпляром A. Получили противоречие, так как x не может одновременно являться экземпляром A и не являться экземпляром A. Следовательно, из предположения, что A наследует B, следует, что не существует ни одного экземпляра A. Хм...


VE>Вы прекрасно поняли, о чем я говорил, придираться к формулировке можете перед зеркалом.


Вы сказали чушь откровенную. Настолько, что я так и не смог написать вам ответ с опровержением. Так что спасибо igna за то, что выразил мои мысли.
Re[2]: И все-таки квадрат это прямоугольник
От: Smal Россия  
Дата: 04.03.07 15:13
Оценка: 1 (1)
Здравствуйте, Владек, Вы писали:

В>В математическом смысле вы правы — можно ввести такую бинарную операцию над элементами множества, что результат её выполнения не будет принадлежать исходному множеству. Это свойство имеет название, но я его забыл. Пример: операция деления натуральных чисел, результат не всегда является натуральным числом (1/2=0.5).

В общем-то бинарная операция по определению замкнутая (т.е. является отображением M x M -> M). Другими словами, деление на множестве натуральных чисел не бинарная операция
С уважением, Александр
Re[2]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 04.03.07 16:49
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Все здесь неприлично. Наследование — это расширение понятия, когда все экзмепляры A являются также экзмеплярами B, но ни один экзмепляр B не является экземпляром A.

VE>Тут же квадрат — это частный случай прямоугольника, да он им является, но из всего множества возможных прямоугольников некоторые являются квадратами.

Можно ли сконструировать пример, демонстрирующий "неприличность" кода, который я привел в первом сообщении
Автор: igna
Дата: 03.03.07
этой темы?
Re[3]: И эти люди...
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 04.03.07 19:16
Оценка:
Здравствуйте, igna, Вы писали:

MS>>...утверждают, что парадигма наследования имеет хоть какую-то практическую пользу?!


I>Ась? Какие люди "утверждают, что парадигма наследования имеет хоть какую-то практическую пользу"?


Ммм, ну я, например
Re[4]: И эти люди...
От: _nn_ www.nemerleweb.com
Дата: 04.03.07 19:45
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, _nn_, Вы писали:


I>
__>>interface ISquare : IRectangle , IRhombus
I>


I>Вот эта возможность унаследовать ISquare от IRectangle обусловлена отсутствием в последнем методов вроде SetWidth и SetHeight.


I>Так что классы ли, интерфейсы ли, наследовать квадрат от прямоугольника можно только если оба неизменны (как в математике).


А чем так плохи неизменяемые объекты ?

Можно изменять введя дополнительные интерфейсы IChangeRectange, IChangeSquare
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: И эти люди...
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 04.03.07 19:51
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Можно изменять введя дополнительные интерфейсы IChangeRectange, IChangeSquare


... причем так, что IChangeSquare не является наследником IChangeRectangle, и наоборот.
Re[5]: И эти люди...
От: igna Россия  
Дата: 04.03.07 19:59
Оценка:
Здравствуйте, _nn_, Вы писали:

__>А чем так плохи неизменяемые объекты ?


Ничем не плохи. Я неизменностью прямоугольников в математике и изменяемостью их в большинстве реализаций в программировании объясняю, почему квадрат в математике является прямоугольником, а в программировании — чаще всего нет. (См. мое первое сообщение.
Автор: igna
Дата: 03.03.07
)

А ты сначала согласился с моим оппонентом
Автор: McSeem2
Дата: 03.03.07
, где было в частности "отношение наследования, которое связывает квадрат и прямоугольник притянуто за уши и не имеет ни малейшего практического смысла", а потом все же унаследовал ISquare от IRectangle. Что, замена классов на интерфейсы оттянула отношение наследования от ушей обратно?
Re[4]: И эти люди...
От: igna Россия  
Дата: 04.03.07 20:02
Оценка: :)
Здравствуйте, Alxndr, Вы писали:

A>Ммм, ну я, например


Гы-сына-лол
Автор: McSeem2
Дата: 03.03.07
тебе от McSeem2.

А я уж подумал, что он не тему.
Re[5]: И эти люди...
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 04.03.07 20:09
Оценка:
Здравствуйте, igna, Вы писали:

I>Гы-сына-лол
Автор: McSeem2
Дата: 03.03.07
тебе от McSeem2.


Ага, пасиб, прочитал еще раньше (да и вообще я мнение Максима на тему замшелой парадигмы знаю )

I>А я уж подумал, что он не тему.


А мне что-то до сих пор так кажется...
Re[2]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 04.03.07 20:15
Оценка: +1
Здравствуйте, jedi, Вы писали:

J>Мне эти разговоры о наследовании квадрата от прямоугольника (или наоборот) всегда казались глупыми.


Спасибо, сознаю.

J>На самом деле это два разных типа, но:

J>1) преобразование типа КВАДРАТ->ПРЯМОУГОЛЬНИК имеет смысл всегда;
J>2) преобразование типа ПРЯМОУГОЛЬНИК->КВАДРАТ имеет смысл только когда ширина равна высоте.

КВАДРАТ и ПРЯМОУГОЛЬНИК связаны отношением IS, а это то отношение, которое чаще всего реализуют использованием наследования. Но в случае КВАДРАТа и ПРЯМОУГОЛЬНИКа оно редко проходит, вот я и ищу ответ, почему? Пока что предполагаю, что дело в изменяемости прямоугольников в программировании в отличие от их неизменяемости в математике.
Re[6]: И эти люди...
От: _nn_ www.nemerleweb.com
Дата: 04.03.07 20:38
Оценка:
Здравствуйте, Alxndr, Вы писали:

A>Здравствуйте, _nn_, Вы писали:


__>>Можно изменять введя дополнительные интерфейсы IChangeRectange, IChangeSquare


A>... причем так, что IChangeSquare не является наследником IChangeRectangle, и наоборот.


Само собой
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[6]: И эти люди...
От: _nn_ www.nemerleweb.com
Дата: 04.03.07 20:39
Оценка: 1 (1)
Здравствуйте, igna, Вы писали:

I>Здравствуйте, _nn_, Вы писали:


__>>А чем так плохи неизменяемые объекты ?


I>Ничем не плохи. Я неизменностью прямоугольников в математике и изменяемостью их в большинстве реализаций в программировании объясняю, почему квадрат в математике является прямоугольником, а в программировании — чаще всего нет. (См. мое первое сообщение.
Автор: igna
Дата: 03.03.07
)


I>А ты сначала согласился с моим оппонентом
Автор: McSeem2
Дата: 03.03.07
, где было в частности "отношение наследования, которое связывает квадрат и прямоугольник притянуто за уши и не имеет ни малейшего практического смысла", а потом все же унаследовал ISquare от IRectangle. Что, замена классов на интерфейсы оттянула отношение наследования от ушей обратно?


Мое согласие было на предложение о контракте. Полное отрицание интерфейсов я не приводил.

Я привел пример решения через интерфейс или через контракт.

Лично мое мнение это конечно только интерфейсы без наследования реализацции. Практически это решение мне нравится.
Предложение контракта мне понравилось больше т.к. звучит более правильно теоретически. А вот как на практике это красиво сделать я не знаю.

http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: И все-таки квадрат это прямоугольник
От: MouseEntity Россия  
Дата: 04.03.07 20:52
Оценка:
Здравствуйте, igna, Вы писали:

I>Можно ли сконструировать пример, демонстрирующий "неприличность" кода, который я привел в первом сообщении
Автор: igna
Дата: 03.03.07
этой темы?


Можно:
r = Rectangle(100, 100);


С математической точки зрения r — квадрат. С точки зрения системы типов — нет.

Что касается поста VoidEx'а:
ИМХО, множество экземпляров базового класса и множество экземпляров наследника не пересекаются, однако множество ссылок/указателей на экземпляры базового класса содержит в себе множество ссылок/указателей на экземпляры производного
Re[3]: И все-таки квадрат это прямоугольник
От: jedi Мухосранск  
Дата: 04.03.07 21:34
Оценка:
Здравствуйте, igna, Вы писали:

I>КВАДРАТ и ПРЯМОУГОЛЬНИК связаны отношением IS


Любой экземпляр типа short точно также является экземпляром типа long. Те short и long связаны отношением IS

Вообще то давно признано что ПО не обязано моделировать реальность 1 : 1. Нужно просто понять. что наследование — не более чем инструмент полезный в ряде случаев, но совершенно бесполезный и даже вредный в куче других. Случай квадрата и прямоугольника — четкий пример где наследование приходится притягивать за уши.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re[4]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 04.03.07 21:47
Оценка: +1
Здравствуйте, MouseEntity, Вы писали:

ME>r = Rectangle(100, 100);


ME>С математической точки зрения r — квадрат. С точки зрения системы типов — нет.


А что, если класс Square не производить от класса Rectangle, то r сразу перестанет быть квадратом с математической точки зрения или станет им с точки зрения системы типов?
Re[4]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 04.03.07 21:49
Оценка:
Здравствуйте, jedi, Вы писали:

J>Любой экземпляр типа short точно также является экземпляром типа long. Те short и long связаны отношением IS


Это неправда. Вспомни про переполнение.
Re[5]: И все-таки квадрат это прямоугольник
От: jedi Мухосранск  
Дата: 04.03.07 22:00
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, jedi, Вы писали:


I>Это неправда. Вспомни про переполнение.


Это правда. Вспомни про операцию SetWidth (SetHeight). Если следовать твоей логике ("Вспомни про переполнение" (с)) — то квадрат не прямоугольник. А пару постов выше ты утверждал обратное. Будь последовательным
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re[6]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 04.03.07 22:17
Оценка:
Здравствуйте, jedi, Вы писали:

J>Это правда. Вспомни про операцию SetWidth (SetHeight). Если следовать твоей логике ("Вспомни про переполнение" (с)) — то квадрат не прямоугольник. А пару постов выше ты утверждал обратное. Будь последовательным


Уфф.

1) У неизменного прямоугольника SetWidth не бывает.
2) short и long изменяемы.
3) Переполнение проявляет себя по разному даже у неизменных аналогов short и long.
Re[3]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 04.03.07 22:33
Оценка:
Здравствуйте, Smal, Вы писали:

S>В общем-то бинарная операция по определению замкнутая (т.е. является отображением M x M -> M). Другими словами, деление на множестве натуральных чисел не бинарная операция


Интересно, а если результат операции в некоторых случаях не определен (как при делении на нуль), можно ли называть операцию бинарной?
Re[7]: И все-таки квадрат это прямоугольник
От: jedi Мухосранск  
Дата: 04.03.07 22:52
Оценка:
Здравствуйте, igna, Вы писали:

I>Уфф.


Аналогично)

I>1) У неизменного прямоугольника SetWidth не бывает.

I>2) short и long изменяемы.
Чем тип "прямоугольник" лучше (или хуже) типов short и long, что ему дана привилегия быть неизменяемым?

I>3) Переполнение проявляет себя по разному даже у неизменных аналогов short и long.

Что ты прицепились к переполнению? Это просто особенность реализации интегральных типов в современных процессоров. Я могу привести сотню похожих примеров без этой особенности, где наследование излишне, несмотря на точто отношение IS имеет место быть. Навскидку: окружность и эллипс, одномерный массив и массив размерности N (он является одномерным масивом элементы которого — массивы размерности N-1), файл и директория, изображение в формате BMP 8bpp и изображение в формате BMP 24bpp итд итп до бесконечности. Заметь, во всех случаях идет речь о связанных объектах, но это еще не значит что наследование уместно во вех случаях.

Я не спорю что неизменяемый квадрат является частным случаем неизменяемого прямоугольника, но наследование здесь совершенно бессмысленно.

В общем, спор этот бесполезен, ибо все эти аргументы уже миллион раз приводились. А воз все там
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re[3]: И все-таки квадрат это прямоугольник
От: VoidEx  
Дата: 04.03.07 23:41
Оценка:
Здравствуйте, igna, Вы писали:

I>Можно ли сконструировать пример, демонстрирующий "неприличность" кода, который я привел в первом сообщении
Автор: igna
Дата: 03.03.07
этой темы?


Так сам код в первом сообщении и есть этот пример. Зачем квадрату две стороны? Может, отнаследуем его еще от многоугольника?
Ответ с интерфейсами куда логичнее.
Re[5]: И все-таки квадрат это прямоугольник
От: VoidEx  
Дата: 04.03.07 23:41
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>Вы сказали чушь откровенную. Настолько, что я так и не смог написать вам ответ с опровержением. Так что спасибо igna за то, что выразил мои мысли.


Все множество прямоугольников шире, чем множество квадратов, так что квадраты — это специализация прямоугольников (когда стороны равны), а вовсе не расширение, и наследование здесь ни при чем.
Re[3]: И все-таки квадрат это прямоугольник
От: VoidEx  
Дата: 04.03.07 23:44
Оценка:
Здравствуйте, igna, Вы писали:

I>КВАДРАТ и ПРЯМОУГОЛЬНИК связаны отношением IS, а это то отношение, которое чаще всего реализуют использованием наследования. Но в случае КВАДРАТа и ПРЯМОУГОЛЬНИКа оно редко проходит, вот я и ищу ответ, почему? Пока что предполагаю, что дело в изменяемости прямоугольников в программировании в отличие от их неизменяемости в математике.


Наследованием реализуют обычно, если что-то связано _не только_ IS, но и EXTENDS. Не даром там такое слово.
Re[8]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 05.03.07 07:03
Оценка:
Здравствуйте, jedi, Вы писали:

J>Я не спорю что неизменяемый квадрат является частным случаем неизменяемого прямоугольника, но наследование здесь совершенно бессмысленно.


У такого наследования нет никаких "подводных камней" в отличие от наследования в случае, когда фигуры изменяемы.
Re[4]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 05.03.07 07:07
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Так сам код в первом сообщении и есть этот пример. Зачем квадрату две стороны?


Это может привести к неправильному поведению, или тут только избыточность?
Re[4]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 05.03.07 07:13
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Наследованием реализуют обычно, если что-то связано _не только_ IS, но и EXTENDS. Не даром там такое слово.


Где по этому поводу можно что-нибудь почитать?
Re[4]: И все-таки квадрат это прямоугольник
От: Smal Россия  
Дата: 05.03.07 09:05
Оценка: 3 (1)
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Smal, Вы писали:


S>>В общем-то бинарная операция по определению замкнутая (т.е. является отображением M x M -> M). Другими словами, деление на множестве натуральных чисел не бинарная операция


I>Интересно, а если результат операции в некоторых случаях не определен (как при делении на нуль), можно ли называть операцию бинарной?

Однозначно нет. Поэтому деление на множестве вещественных — не бинарная операция.
С уважением, Александр
Re[5]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 05.03.07 10:06
Оценка:
Здравствуйте, Smal, Вы писали:

S>Однозначно нет. Поэтому деление на множестве вещественных — не бинарная операция.


Вот как. А англоязычные в Википедии своей заблуждаются или у них множество другое? Или определение бинарной операции?

Many binary operations of interest in both algebra and formal logic are commutative or associative. Many also have identity elements and inverse elements. Typical examples of binary operations are the addition (+) and multiplication (*) of numbers and matrices as well as composition of functions on a single set.

Examples of operations that are not commutative are subtraction (-), division (/), exponentiation(^), and super-exponentiation(@).

(http://en.wikipedia.org/wiki/Binary_operation)


Или тут не о бинарной операции, а об операции вообще? Зачем тогда в статье "Binary operation"?
Re[6]: И все-таки квадрат это прямоугольник
От: Smal Россия  
Дата: 05.03.07 10:24
Оценка: +2
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Smal, Вы писали:


S>>Однозначно нет. Поэтому деление на множестве вещественных — не бинарная операция.


I>Вот как. А англоязычные в Википедии своей заблуждаются или у них множество другое? Или определение бинарной операции?


I>

I>Many binary operations of interest in both algebra and formal logic are commutative or associative. Many also have identity elements and inverse elements. Typical examples of binary operations are the addition (+) and multiplication (*) of numbers and matrices as well as composition of functions on a single set.

I>Examples of operations that are not commutative are subtraction (-), division (/), exponentiation(^), and super-exponentiation(@).

I>(http://en.wikipedia.org/wiki/Binary_operation)


I>Или тут не о бинарной операции, а об операции вообще? Зачем тогда в статье "Binary operation"?


Не ошибаются, а недоговаривают. Деления — это бинарная операция на множестве вещественных чисел без нуля (R\{0}).
С уважением, Александр
Re[6]: И все-таки квадрат это прямоугольник
От: FDSC Россия consp11.github.io блог
Дата: 05.03.07 10:53
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Здравствуйте, FDSC, Вы писали:


FDS>>Вы сказали чушь откровенную. Настолько, что я так и не смог написать вам ответ с опровержением. Так что спасибо igna за то, что выразил мои мысли.


VE>Все множество прямоугольников шире, чем множество квадратов, так что квадраты — это специализация прямоугольников (когда стороны равны), а вовсе не расширение, и наследование здесь ни при чем.



Наследование, в частности, применяется, когда нужна специализация более общего класса. Например, есть список, который сортирует с указанием функции сравнения, а мы его специализируем для более удобного и безошибочного использования в сортировщик без указания функции сравнения или со стандартным набором функций сравнения (что бы пользователь не мог ошибочно указать неправильную функцию).
При этом, в некоторых случаях объект базового класса вполне может себя вести как объект производного класса — если мы поставили туда соотв. функцию сравнения. В то же время, наследование может происходить здесь и наоборот, от списка с жёстко заданным сортировщиком, к списку с указанием функции сравнения. Всё зависит от того, для чего мы это хотим сделать и что в данной конкретной системе будет являться повышением удобства или гибкости программирования.
Re[8]: И все-таки квадрат это прямоугольник
От: FDSC Россия consp11.github.io блог
Дата: 05.03.07 10:59
Оценка:
Здравствуйте, jedi, Вы писали:

jedi>Навскидку: окружность и эллипс


Так и кто от кого тут будет наследоваться???
Re: И все-таки квадрат это прямоугольник
От: vdimas Россия  
Дата: 05.03.07 11:29
Оценка: 7 (2)
Здравствуйте, igna, Вы писали:

Реализация механизма наследования в популярных языках не всегда удачно эмулирует отношение "is a". Например, если твой экземпляр прямоугольника имеет одинаковые стороны, то он должен приводиться к классу квадратов, ромбов и т.д. В CORBA есть возможность перехватить вызов метода is_a(Type) и сделать, например, порождение экземпляра-прокси, отвечающего нужному интерфейсу.

В терминах .Net для преобразования типов твоих фигур можно ввести доп. метод:

public interface Figure {
    T IsA<T>() where T: Figure;
}

public interface Rectangle : Figure {
    int Width { get; }
    int Height { get; }
}

public interface Square : Figure {
    int Size { get; }
}

public class Figure4 : Figure {
    public T IsA<T> where T: Figure {
        if(T is Square 
             && Size0==Size1 && Size0==Size2 && Size0==Size3 
             && Angle0==90) // в градусах например
            return new SqareImpl(this.Size0);
            
        ...
        return null;
    }
}
Re[9]: И все-таки квадрат это прямоугольник
От: jedi Мухосранск  
Дата: 05.03.07 11:30
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>Здравствуйте, jedi, Вы писали:


jedi>>Навскидку: окружность и эллипс


FDS>Так и кто от кого тут будет наследоваться???


Хм, если ты не заметил, то это были как раз примеры ситуаций, где наследование не только полезно, но и вредно
Однако, если следовать логике топикстартера, то нужно наследовать окружность от эллипса, ибо окружнось IS эллипс, у которого большая и малая оси равны. Говорят этот иогурт особенно хорош, когда окружность неизменна
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re[9]: И все-таки квадрат это прямоугольник
От: jedi Мухосранск  
Дата: 05.03.07 11:30
Оценка: +1
Здравствуйте, igna, Вы писали:

I>Здравствуйте, jedi, Вы писали:


J>>Я не спорю что неизменяемый квадрат является частным случаем неизменяемого прямоугольника, но наследование здесь совершенно бессмысленно.


I>У такого наследования нет никаких "подводных камней" в отличие от наследования в случае, когда фигуры изменяемы.


У такого наследования нет нетолько "подводных камней", но и смысла
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re[7]: И все-таки квадрат это прямоугольник
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 05.03.07 11:38
Оценка:
Smal,

I>>Или тут не о бинарной операции, а об операции вообще? Зачем тогда в статье "Binary operation"?


S>Не ошибаются, а недоговаривают. Деления — это бинарная операция на множестве вещественных чисел без нуля (R\{0}).


маленькая придирка: сказанное тобой означает, что
(/) :: (R\{0}) x (R\{0}) -> (R\{0})

в то время как обычно предполагается определение
либо
(/) :: R x (R\{0}) -> R
либо
(/) :: (R_+) x (R_+) -> (R_+)
где R_+ ::= R + {Infinity, -Infinity, NaN}

причём предпочтительнее именно второй вариант — операция деления становится замкнутой.

Эта особенность отражена и в стандарте IEEE 754 — реализации "вещественных чисел" на железках.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[10]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 05.03.07 11:52
Оценка:
Здравствуйте, jedi, Вы писали:

J>Однако, если следовать логике топикстартера, то нужно наследовать окружность от эллипса, ибо окружнось IS эллипс, у которого большая и малая оси равны. Говорят этот иогурт особенно хорош, когда окружность неизменна


Не передергивай, "этот иогурт" только тогда и возможен, "когда окружность неизменна". Хорош-нехорош, а также осмыслен или нет, это другие вопросы.
Re[5]: И все-таки квадрат это прямоугольник
От: MouseEntity Россия  
Дата: 05.03.07 15:22
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, MouseEntity, Вы писали:


I>
ME>>r = Rectangle(100, 100);
I>


I>А что, если класс Square не производить от класса Rectangle, то r сразу перестанет быть квадратом с математической точки зрения или станет им с точки зрения системы типов?


Нет
Re[6]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 05.03.07 15:42
Оценка:
Здравствуйте, MouseEntity, Вы писали:

I>>А что, если класс Square не производить от класса Rectangle, то r сразу перестанет быть квадратом с математической точки зрения или станет им с точки зрения системы типов?


ME>Нет


А как же определить типы Square и Rectangle, чтобы можно было не нарушая "приличий" написать

r = new Rectangle(100, 100);

?
Re[7]: И все-таки квадрат это прямоугольник
От: MouseEntity Россия  
Дата: 05.03.07 15:55
Оценка:
Здравствуйте, igna, Вы писали:

I>А как же определить типы Square и Rectangle, чтобы можно было не нарушая "приличий" написать


I>
I>r = new Rectangle(100, 100);
I>

I>?

Можно использовать преобразования типов, придётся кидаться исключениями в случае если width != height, но похоже это неполное решение. А можно вообще отказаться от типизации или не разделять квадраты и прямоугольники на разные типы.
Re[8]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 05.03.07 16:07
Оценка:
Здравствуйте, MouseEntity, Вы писали:

ME>Можно использовать преобразования типов, придётся кидаться исключениями в случае если width != height, но похоже это неполное решение. А можно вообще отказаться от типизации или не разделять квадраты и прямоугольники на разные типы.


А если вместо квадратов и прямоугольников речь о квадратных и прямоугольных матрицах, и функция вычисления детерминанта (определителя) имеет смысл только для квадратных матриц? Определить только прямоугольную матрицу, определить функцию вычисления детерминанта для нее и "кидаться исключениями" в случае вызова этой функции для неквадратной матрицы?
Re[5]: И все-таки квадрат это прямоугольник
От: VoidEx  
Дата: 05.03.07 16:35
Оценка:
Здравствуйте, igna, Вы писали:

I>Это может привести к неправильному поведению, или тут только избыточность?

Избыточность, плюс мне лично кажется очень нелогичным такое:

void foo (Square const & sq) { ... }

void test
{
  Rectangle rect(2, 2);
  foo (rect); // Почему нет?
}

Тут объект базового класса (т.е. созданный как Rectangle) явно является и объектом Square, однако языком это никак не выражается.

I>Где по этому поводу можно что-нибудь почитать?

Конкретно не скажу, может быть, даже и нет такого. Может, это только мое мнение))
Но вот у Страуструпа точно есть про то, что окружность не надо наследовать от эллипса.
Лично мне кажется, что наследование должно именно расширять множество, т.е. например "Кнопка с текстом" наследуется от "Кнопка". Множество всех кнопок с текстом (в том числе и с пустым) будет шире, чем множество всех простых кнопок (без текста).
Ессно, что это теория, и вообще наследование надо использовать так, как оно удобно.
В случае с прямоугольником/квадратом мне неудобно именно то, что Rectangle(2,2) не эквивалентен Square(2), хотя вообще говоря, это одно и то же.
Re[7]: И все-таки квадрат это прямоугольник
От: VoidEx  
Дата: 05.03.07 16:37
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>Здравствуйте, VoidEx, Вы писали:


FDS>Всё зависит от того, для чего мы это хотим сделать и что в данной конкретной системе будет являться повышением удобства или гибкости программирования.


Само собой, гибкость, это хорошо, но я говорил с позиции.. философии что ли.
Re[6]: И все-таки квадрат это прямоугольник
От: anton_t Россия  
Дата: 05.03.07 16:45
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Конкретно не скажу, может быть, даже и нет такого. Может, это только мое мнение))

VE>Но вот у Страуструпа точно есть про то, что окружность не надо наследовать от эллипса.
VE>Лично мне кажется, что наследование должно именно расширять множество, т.е. например "Кнопка с текстом" наследуется от "Кнопка". Множество всех кнопок с текстом (в том числе и с пустым) будет шире, чем множество всех простых кнопок (без текста).
VE>Ессно, что это теория, и вообще наследование надо использовать так, как оно удобно.
VE>В случае с прямоугольником/квадратом мне неудобно именно то, что Rectangle(2,2) не эквивалентен Square(2), хотя вообще говоря, это одно и то же.

Воовбще-то множество кнопок шире, чем множество кнопок с с текстом.
Re[8]: И все-таки квадрат это прямоугольник
От: FDSC Россия consp11.github.io блог
Дата: 05.03.07 17:03
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Здравствуйте, FDSC, Вы писали:


FDS>>Здравствуйте, VoidEx, Вы писали:


FDS>>Всё зависит от того, для чего мы это хотим сделать и что в данной конкретной системе будет являться повышением удобства или гибкости программирования.


VE>Само собой, гибкость, это хорошо, но я говорил с позиции.. философии что ли.


С позиции философии наследование есть всего лишь наследование реализации и интерфейса.
Re[6]: И все-таки квадрат это прямоугольник
От: FDSC Россия consp11.github.io блог
Дата: 05.03.07 17:06
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Здравствуйте, igna, Вы писали:


I>>Это может привести к неправильному поведению, или тут только избыточность?

VE>Избыточность, плюс мне лично кажется очень нелогичным такое:

VE>
VE>void foo (Square const & sq) { ... }

VE>void test
VE>{
VE>  Rectangle rect(2, 2);
VE>  foo (rect); // Почему нет?
VE>}
VE>

VE>Тут объект базового класса (т.е. созданный как Rectangle) явно является и объектом Square, однако языком это никак не выражается.

Естественно, не выражается. Так как здесь прямоугольник СЛУЧАЙНО стал квадратом, в результате некоторых вычислений, которые вы заменили Rectangle rect(2, 2), иначе программист должен был бы просто сделать Rectangle rect = new Square(2);
Т.е. не нужно путать случайное совпадение параметров и СТАТИЧЕСКИ гарантированный тип данных.

I>>Где по этому поводу можно что-нибудь почитать?

VE>Конкретно не скажу, может быть, даже и нет такого. Может, это только мое мнение))
VE>Но вот у Страуструпа точно есть про то, что окружность не надо наследовать от эллипса.
VE>Лично мне кажется, что наследование должно именно расширять множество, т.е. например "Кнопка с текстом" наследуется от "Кнопка". Множество всех кнопок с текстом (в том числе и с пустым) будет шире, чем множество всех простых кнопок (без текста).

Т.е. вы предлагаете наследовать прямоугольник от квадрата???
Re[6]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 05.03.07 18:42
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Но вот у Страуструпа точно есть про то, что окружность не надо наследовать от эллипса.


Ага, вот оно:

... in mathematics a circle is a kind
of an ellipse, but in most programs a circle should not be derived from an ellipse or an ellipse
derived from a circle. The oftenheard
arguments ‘‘because that’s the way it is in mathematics’’
and ‘‘because the representation of a circle is a subset of that of an ellipse’’ are not conclusive and
most often wrong. This is because for most programs, the key property of a circle is that it has a
center and a fixed distance to its perimeter. All behavior of a circle (all operations) must maintain
this property (invariant; §24.3.7.1).


Ну а если наши эллипс и круг (или прямоугольник и квадрат) неизменны, проблема поддержания инвариантов неизменными решается автоматически.
Re[7]: И все-таки квадрат это прямоугольник
От: VoidEx  
Дата: 05.03.07 19:56
Оценка:
Здравствуйте, anton_t, Вы писали:

_>Воовбще-то множество кнопок шире, чем множество кнопок с с текстом.

Кнопок Button. Они не включают в себя ButtonWithText. Вы к понятию "кнопка" приписываете все кнопки, т.е. и всех ее наследников. Я имею ввиду именно сам базовый.
Button b (...); ни при каких условиях не будет ButtonWithText, так как у нее нету текста, а вот Rectangle rect(2, 2) не то, чтобы является Square(2), так еще и с избытком.
Я просто к тому, что квадрат — это частный случай прямоугольника, он ничего нового не вносит, он вносит только ограничения. А делается это наследованием видимо потому, что нормального способа это указать нет. Было бы неплохо что-то в таком виде:

Square specializes Rectangle
{
  invariant { base.a == base.b; }
  ...
}

Rectangle rect (2, 3);
Rectangle rect2 = SomeOperations (rect);
if (rect2 is Square) // проверка всего-лишь инварианта rect2.a == rect2.b
{
  ...
}

Наследование здесь неествесственно, но используется в силу того, что нормальнее ничего нет.


Здравствуйте, FDSC, Вы писали:

FDS>Т.е. вы предлагаете наследовать прямоугольник от квадрата???

Нет, тут оно вообще неуместно, ни так, ни эдак. Ибо кроме extends надо еще и is, а прямоугольник квадратом в общем случае не является.

Здравствуйте, igna, Вы писали:

I>Ну а если наши эллипс и круг (или прямоугольник и квадрат) неизменны, проблема поддержания инвариантов неизменными решается автоматически.
Re[8]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 05.03.07 20:11
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Я просто к тому, что квадрат — это частный случай прямоугольника, он ничего нового не вносит, он вносит только ограничения.


Зато квадратная матрица с одной стороны ограничивая прямоугольную равенством количества строк и столбцов, с другой стороны добавляет возможность вычисления детерминанта. Можно наследовать? То есть, что на самом деле важно, расширение или "не сужение"?
Re[8]: И все-таки квадрат это прямоугольник
От: anton_t Россия  
Дата: 06.03.07 06:03
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Здравствуйте, anton_t, Вы писали:


_>>Воовбще-то множество кнопок шире, чем множество кнопок с с текстом.

VE>Кнопок Button. Они не включают в себя ButtonWithText. Вы к понятию "кнопка" приписываете все кнопки, т.е. и всех ее наследников. Я имею ввиду именно сам базовый.
VE>Button b (...); ни при каких условиях не будет ButtonWithText, так как у нее нету текста, а вот Rectangle rect(2, 2) не то, чтобы является Square(2), так еще и с избытком.
VE>Я просто к тому, что квадрат — это частный случай прямоугольника, он ничего нового не вносит, он вносит только ограничения. А делается это наследованием видимо потому, что нормального способа это указать нет. Было бы неплохо что-то в таком виде:

VE>
VE>Square specializes Rectangle
VE>{
VE>  invariant { base.a == base.b; }
VE>  ...
VE>}

VE>Rectangle rect (2, 3);
VE>Rectangle rect2 = SomeOperations (rect);
VE>if (rect2 is Square) // проверка всего-лишь инварианта rect2.a == rect2.b
VE>{
VE>  ...
VE>}
VE>

VE>Наследование здесь неествесственно, но используется в силу того, что нормальнее ничего нет.


Легко:
Button b = new ButtonWithText("bla-bla");

А прямоугольник с квадратом лучше не смешивать — поведение разное.
Re: И все-таки квадрат это прямоугольник
От: Tilir Россия http://tilir.livejournal.com
Дата: 06.03.07 06:45
Оценка: -1
Здравствуйте, igna, Вы писали:

I>Все-таки математика права, квадрат это прямоугольник, и в приведенном ниже коде (на Java) нет ничего неприличного:


Ох уж мне эти java-developer'ы... Ясное дело, Мейерса вы не читали. А между прочим, в книге "Эффективное использование C++" есть целый раздел, посвящённый тому, почему (в рамках философии C++) квадрат нельзя наследовать от прямоугольника. Коротко говоря, для него не выполняется LSP. Очень советую ознакомится. Если лень читать всю книжку, то подскажу: см. правило №35.
Re[9]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 06.03.07 07:40
Оценка:
Здравствуйте, anton_t, Вы писали:

_>А прямоугольник с квадратом лучше не смешивать — поведение разное.


Если прямоугольник и квадрат изменяемые. Если неизменные — нет проблем, квадрат это прямоугольник.
Re[2]: И все-таки квадрат это прямоугольник
От: FDSC Россия consp11.github.io блог
Дата: 06.03.07 07:56
Оценка:
Здравствуйте, Tilir, Вы писали:

T>Здравствуйте, igna, Вы писали:


I>>Все-таки математика права, квадрат это прямоугольник, и в приведенном ниже коде (на Java) нет ничего неприличного:


T>Ох уж мне эти java-developer'ы... Ясное дело, Мейерса вы не читали. А между прочим, в книге "Эффективное использование C++" есть целый раздел, посвящённый тому, почему (в рамках философии C++) квадрат нельзя наследовать от прямоугольника. Коротко говоря, для него не выполняется LSP. Очень советую ознакомится. Если лень читать всю книжку, то подскажу: см. правило №35.


Вы бы лучше сказали, где взять книгу в электронном виде...
Re[8]: И все-таки квадрат это прямоугольник
От: FDSC Россия consp11.github.io блог
Дата: 06.03.07 08:00
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Здравствуйте, anton_t, Вы писали:


_>>Воовбще-то множество кнопок шире, чем множество кнопок с с текстом.

VE>Кнопок Button. Они не включают в себя ButtonWithText. Вы к понятию "кнопка" приписываете все кнопки, т.е. и всех ее наследников. Я имею ввиду именно сам базовый.
VE>Button b (...); ни при каких условиях не будет ButtonWithText, так как у нее нету текста, а вот Rectangle rect(2, 2) не то, чтобы является Square(2), так еще и с избытком.


FDS>>Т.е. вы предлагаете наследовать прямоугольник от квадрата???

VE>Нет, тут оно вообще неуместно, ни так, ни эдак. Ибо кроме extends надо еще и is, а прямоугольник квадратом в общем случае не является.

Следуя вашей логике, мы должны сказать, что кнопка с текстом ведь тоже не является кнопкой без текста, однако наследование у вас в данном случае возможно.
Re[2]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 06.03.07 08:01
Оценка: 4 (1) +1
Здравствуйте, Tilir, Вы писали:

T>Ох уж мне эти java-developer'ы... Ясное дело, Мейерса вы не читали. А между прочим, в книге "Эффективное использование C++" есть целый раздел, посвящённый тому, почему (в рамках философии C++) квадрат нельзя наследовать от прямоугольника. Коротко говоря, для него не выполняется LSP. Очень советую ознакомится. Если лень читать всю книжку, то подскажу: см. правило №35.


Читал, читал. Вот кое-кому неплохо бы дочитать до конца сообщение, на которое он ответил, там всего-то несколько строк текста.

Речь о том, что нехорошие вещи при наследовании квадрата от прямоугольника происходят только, если эти квадрат и прямоугольник изменяемы. Именно этот случай чаще всего встречается в практике и рассматривается у Страуструпа, Мейерса и других. Но в случае неизменности квадрата и прямоугольника можно наследовать квадрат от прямоугольника, и никаких неприятностей я (пока?) не знаю. Независимо от полезности неизменных квадрата и прямоугольника в программировании, это наблюдение может оказаться полезным для объяснения того факта, что в математике квадрат является прямоугольником, а в программировании обычно нет.

P.S. Про Java. Это наверное была первая программа на Java, которую я показал на RSDN. Я вообще-то на C++ пишу, и в последнее время немного на C#. Независимо от того, некрасиво вот так вот о всех, кто программирует на Java. Сорри за нотации.
Re[3]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 06.03.07 08:03
Оценка: 8 (1)
anatolix.naumen.ru
Re[3]: И все-таки квадрат это прямоугольник
От: AndreiF  
Дата: 06.03.07 08:26
Оценка:
Здравствуйте, igna, Вы писали:

I>Речь о том, что нехорошие вещи при наследовании квадрата от прямоугольника происходят только, если эти квадрат и прямоугольник изменяемы. Именно этот случай чаще всего встречается в практике и рассматривается у Страуструпа, Мейерса и других. Но в случае неизменности квадрата и прямоугольника можно наследовать квадрат от прямоугольника, и никаких неприятностей я (пока?) не знаю.


Насколько я понимаю, главная проблема в том, что изменение величины сторон может привести к превращению квадрата в прямоугольник и наоборот. Выхода здесь два — или запретить менять стороны, или разрешить менять тип объекта "на лету", то есть использовать динамическую классификацию объектов.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 06.03.07 08:31
Оценка:
Здравствуйте, AndreiF, Вы писали:

I>>Речь о том, что нехорошие вещи при наследовании квадрата от прямоугольника происходят только, если эти квадрат и прямоугольник изменяемы. Именно этот случай чаще всего встречается в практике и рассматривается у Страуструпа, Мейерса и других. Но в случае неизменности квадрата и прямоугольника можно наследовать квадрат от прямоугольника, и никаких неприятностей я (пока?) не знаю.


AF>Насколько я понимаю, главная проблема в том, что изменение величины сторон может привести к превращению квадрата в прямоугольник и наоборот. Выхода здесь два — или запретить менять стороны, или разрешить менять тип объекта "на лету", то есть использовать динамическую классификацию объектов.


Сравни выделенное.
Re[3]: И все-таки квадрат это прямоугольник
От: Tilir Россия http://tilir.livejournal.com
Дата: 06.03.07 08:48
Оценка: -4
Здравствуйте, igna, Вы писали:

I>Речь о том, что нехорошие вещи при наследовании квадрата от прямоугольника происходят только, если эти квадрат и прямоугольник изменяемы. Именно этот случай чаще всего встречается в практике и рассматривается у Страуструпа, Мейерса и других. Но в случае неизменности квадрата и прямоугольника можно наследовать квадрат от прямоугольника, и никаких неприятностей я (пока?) не знаю. Независимо от полезности неизменных квадрата и прямоугольника в программировании, это наблюдение может оказаться полезным для объяснения того факта, что в математике квадрат является прямоугольником, а в программировании обычно нет.


Ещё раз. Давайте сформулируем LSP:

Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.


Можем ли мы придумать для квадрата такое свойство, которого нет у прямоугольника? Да, можем — у квадрата все стороны равны. Для него это provable property Равенство сторон("Квадрат") = true. Очевидно, что существует такой прямоугольник (например со сторонами длиной 2 и 1) для которого Равенство сторон("Прямоугольник") = false => LSP не выполнен и тип "Квадрат" не является подтипом типа "Прямоугольник", что и требовалось доказать. Так называемый "здравый смысл" и "математическая интуиция" здесь ни при чём, это ООП.

I>P.S. Про Java. Это наверное была первая программа на Java, которую я показал на RSDN. Я вообще-то на C++ пишу, и в последнее время немного на C#. Независимо от того, некрасиво вот так вот о всех, кто программирует на Java. Сорри за нотации.


Формально я не сказал ничего плохого о Java-developer'ах, мы все их очень любим и уважаем. Поэтому я даже не буду извиняться перед вами, что сгоряча вас к ним причислил, хотя конечно следовало бы.
Re[5]: И все-таки квадрат это прямоугольник
От: AndreiF  
Дата: 06.03.07 08:55
Оценка:
Здравствуйте, igna, Вы писали:

I>Сравни выделенное.


и?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 06.03.07 08:57
Оценка: +1
Здравствуйте, Tilir, Вы писали:

T>Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.


T>Можем ли мы придумать для квадрата такое свойство, которого нет у прямоугольника? Да, можем — у квадрата все стороны равны. Для него это provable property Равенство сторон("Квадрат") = true. Очевидно, что существует такой прямоугольник (например со сторонами длиной 2 и 1) для которого Равенство сторон("Прямоугольник") = false => LSP не выполнен и тип "Квадрат" не является подтипом типа "Прямоугольник", что и требовалось доказать.


Если в выделенном поменять "Квадрат" и "Прямоугольник" местами, то будет верно. Я серьезно, проверь свое доказательство.

T>Так называемый "здравый смысл" и "математическая интуиция" здесь ни при чём, это ООП.


Re[6]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 06.03.07 09:01
Оценка:
Здравствуйте, AndreiF, Вы писали:

AF>и?


Чего "и"?

Я говорю о неизменных фигурах, в объектах, которые их представляют нет никаких методов для их изменения, а ты: "изменение величины сторон может привести к превращению квадрата в прямоугольник". Эта возможность отсутствует в классах, которые я определил, посмотри первое сообщение.
Re[4]: И все-таки квадрат это прямоугольник
От: FDSC Россия consp11.github.io блог
Дата: 06.03.07 09:06
Оценка: +1
Здравствуйте, Tilir, Вы писали:

T>Здравствуйте, igna, Вы писали:


I>>Речь о том, что нехорошие вещи при наследовании квадрата от прямоугольника происходят только, если эти квадрат и прямоугольник изменяемы. Именно этот случай чаще всего встречается в практике и рассматривается у Страуструпа, Мейерса и других. Но в случае неизменности квадрата и прямоугольника можно наследовать квадрат от прямоугольника, и никаких неприятностей я (пока?) не знаю. Независимо от полезности неизменных квадрата и прямоугольника в программировании, это наблюдение может оказаться полезным для объяснения того факта, что в математике квадрат является прямоугольником, а в программировании обычно нет.


T>Ещё раз. Давайте сформулируем LSP:


T>

T>Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.


А теперь то же самое на русском. По моему ты напутал с применением этого принципа в теореме

T>Формально я не сказал ничего плохого о Java-developer'ах, мы все их очень любим и уважаем. Поэтому я даже не буду извиняться перед вами, что сгоряча вас к ним причислил, хотя конечно следовало бы.


Следовало бы причислить или следовало бы извинится???
Формально, но вы же не в суде...
Re: И все-таки квадрат это прямоугольник
От: dmz Россия  
Дата: 06.03.07 09:20
Оценка:
I>Все-таки математика права, квадрат это прямоугольник, и в приведенном ниже коде (на Java)
I>нет ничего неприличного:

Объект характеризуется данными/состоянием и поведением. Причем, поведение можно поставить на первое место, так как данные по-хорошему, сокрыты. Таким образом, вопрос квадрат является прямоугольником или наоборот, зависит от контекста задачи.

В каких задачах квадраты отличаются поведением от прямоугольника? Если речь о графических или геометрических приложениям — то, вероятно, ни в каких (попробуйте привести контр-пример):

Отрисовываются они одинаково, заливаются одинаково, вращаются, масштабируются одинаково,
даже площадь вычисляется одинаково.

Скорее всего, нет никаких квадратов и прямоугольников, а есть выпуклые многоугольники, например.
Re[7]: И все-таки квадрат это прямоугольник
От: AndreiF  
Дата: 06.03.07 09:21
Оценка:
Здравствуйте, igna, Вы писали:

I>Я говорю о неизменных фигурах, в объектах, которые их представляют нет никаких методов для их изменения, а ты: "изменение величины сторон может привести к превращению квадрата в прямоугольник". Эта возможность отсутствует в классах, которые я определил, посмотри первое сообщение.


А я говорил о возможных альтернативах решению делать объекты неизменяемыми
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 06.03.07 09:31
Оценка:
Здравствуйте, AndreiF, Вы писали:

AF>А я говорил о возможных альтернативах решению делать объекты неизменяемыми


OK
Re[5]: И все-таки квадрат это прямоугольник
От: Tilir Россия http://tilir.livejournal.com
Дата: 06.03.07 09:49
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Tilir, Вы писали:


I>

T>>Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.


T>>Можем ли мы придумать для квадрата такое свойство, которого нет у прямоугольника? Да, можем — у квадрата все стороны равны. Для него это provable property Равенство сторон("Квадрат") = true. Очевидно, что существует такой прямоугольник (например со сторонами длиной 2 и 1) для которого Равенство сторон("Прямоугольник") = false => LSP не выполнен и тип "Квадрат" не является подтипом типа "Прямоугольник", что и требовалось доказать.


I>Если в выделенном поменять "Квадрат" и "Прямоугольник" местами, то будет верно. Я серьезно, проверь свое доказательство.


Прямоугольник можно наследовать от квадрата. Примерно так:

class Square{
public:
  explicit Square(int len = 1):m_Len(len){};
  virtual ~Square() {};
  virtual GetSquare() const {return m_Len*m_Len;}
  virtual GetPerimeter() const {return m_Len*4;}
protected:
  int m_Len;
}

class Rectangle: public Square{
public:
  explicit Rectangle(int len = 1, int width = 1):m_Len(len), m_Width(width){};
  virtual ~Rectangle() {};
  virtual GetSquare() const {return m_Len*m_Width;}
  virtual GetPerimeter() const {return m_Len*2 + m_Width*2;}
protected:
  int m_Width;
}


Легко проверить, что тип "Прямоугольник" является подтипом типа "Квадрат" согласно LSP, но не наоборот.
Re[6]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 06.03.07 10:49
Оценка:
Здравствуйте, Tilir, Вы писали:

T>Легко проверить, что тип "Прямоугольник" является подтипом типа "Квадрат" согласно LSP, но не наоборот.


Ну смотри, сам же писал:

Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.

Равенство сторон("Квадрат") = true
Равенство сторон("Прямоугольник") = false


Замени q на Равенство сторон, T — на "Квадрат", а S — на "Прямоугольник", и получишь противоречие:

Let Равенство сторон(x) be a property provable about objects x of type "Квадрат". Then Равенство сторон(y) should be true for objects y of type "Прямоугольник" where "Прямоугольник" is a subtype of "Квадрат".


То есть "Прямоугольник" не может быть подтипом "Квадрата".
Re[10]: И все-таки квадрат это прямоугольник
От: anton_t Россия  
Дата: 06.03.07 11:52
Оценка: +2
Здравствуйте, igna, Вы писали:

I>Здравствуйте, anton_t, Вы писали:


_>>А прямоугольник с квадратом лучше не смешивать — поведение разное.


I>Если прямоугольник и квадрат изменяемые. Если неизменные — нет проблем, квадрат это прямоугольник.


Ну, функциональное программирование, вообще, многие проблемы решает
Re[9]: И все-таки квадрат это прямоугольник
От: VoidEx  
Дата: 06.03.07 14:56
Оценка:
Здравствуйте, anton_t, Вы писали:

_>Легко:

_>
_>Button b = new ButtonWithText("bla-bla");
_>

_>А прямоугольник с квадратом лучше не смешивать — поведение разное.
Здесь ButtonWithText, а не Button. То, что вы его к указателю на базовый привели, не сделало его просто Button'ом.

Здравствуйте, FDSC, Вы писали:

FDS>Следуя вашей логике, мы должны сказать, что кнопка с текстом ведь тоже не является кнопкой без текста, однако наследование у вас в данном случае возможно.

Button — это не кнопка без текста, это просто кнопка. Я только уточнил, что у нее текста нету, чтобы не говорили о том, что множество всех кнопок шире. Но все равно сказали.
ButtonWithText может участвовать везде, где нужна просто кнопка. А Button там, где нужна ButtonWithText — нет.
Square может участвовать везде, где нужен Rectangle. Rectangle тоже может там, где нужен Square, но при определенных условиях, когда r.a == r.b.
Re[10]: И все-таки квадрат это прямоугольник
От: anton_t Россия  
Дата: 06.03.07 15:10
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Здравствуйте, anton_t, Вы писали:


_>>Легко:

_>>
_>>Button b = new ButtonWithText("bla-bla");
_>>

_>>А прямоугольник с квадратом лучше не смешивать — поведение разное.
VE>Здесь ButtonWithText, а не Button. То, что вы его к указателю на базовый привели, не сделало его просто Button'ом.

А что такое "Просто Button"?
Re[9]: И все-таки квадрат это прямоугольник
От: MouseEntity Россия  
Дата: 06.03.07 16:32
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, MouseEntity, Вы писали:


ME>>Можно использовать преобразования типов, придётся кидаться исключениями в случае если width != height, но похоже это неполное решение. А можно вообще отказаться от типизации или не разделять квадраты и прямоугольники на разные типы.


I>А если вместо квадратов и прямоугольников речь о квадратных и прямоугольных матрицах, и функция вычисления детерминанта (определителя) имеет смысл только для квадратных матриц? Определить только прямоугольную матрицу, определить функцию вычисления детерминанта для нее и "кидаться исключениями" в случае вызова этой функции для неквадратной матрицы?


Можно и исключения. Если хочется статических проверок, то лучше всего автоматическое доказательство некоторых утверждений, по сути типизация именно это и позволяет делать, только в упрощённом случае.

Если же для этого вводить отдельный тип для квадрата, то в неимперативном случае будет достаточно приведений типов — неявных от квадрата к прямоугольнику, явных или неявных от прямоугольника к квадрату (в случае явного приведения программист берёт как бы на себя доказательство утверждения). Хотя это, конечно, имитация теоретико-множественного включение: чтобы всё было математически красиво, надо использовать систему типов, в которой можно использовать типы-подмножества других типов — однако без автоматических доказательств ничего нового они имхо не дадут.
Re[11]: И все-таки квадрат это прямоугольник
От: VoidEx  
Дата: 06.03.07 18:28
Оценка:
Здравствуйте, anton_t, Вы писали:

_>А что такое "Просто Button"?

Мне что, надо приводить четкие формулировки?
Вот по Стандарту Си++, надеюсь, будет понятно, о чем я.
1.3.3 dynamic type [defns.dynamic.type]
the type of the most derived object (1.8) to which the lvalue denoted by an lvalue expression refers. [Example:
if a pointer (8.3.1) p whose static type is “pointer to class B” is pointing to an object of class D, derived
from B (clause 10), the dynamic type of the expression *p is “D.” References (8.3.2) are treated similarly. ]
The dynamic type of an rvalue expression is its static type.

Просто Button, когда dynamic type == Button.
Re: И все-таки квадрат это прямоугольник
От: Big_Urri Казахстан  
Дата: 07.03.07 03:16
Оценка:
Здравствуйте, igna, Вы писали:

I>А если захотелось добавить методы SetWidth и SetHeight, так это уже нечто за пределами математических понятий "квадрат" и "прямоугольник". В математике объекты (не в смысле ООП объекты, нет, в обычном, человеческом смысле объекты), так вот, в математике объекты как правило неизменные, то есть умножая одну матрицу на другую получаем третью, а вовсе не модифицируем первую. В программировании такие объекты тоже встречаются, например String в Java или .NET; и если Rectangle и Square определить неизменными, они вполне могут быть связаны отношением наследования.


А еще, как квадрат, так и прямоугольник можно задавать длиной диагонали и углом между ними. В этом случае проблем с наследованием и изменяемостью не возникает, поведение фигур полностью идентично. Height и Width будут вычисляемые. Но есть еще ромб.
Re[2]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 07.03.07 04:10
Оценка: +1
Здравствуйте, Big_Urri, Вы писали:

B_U>А еще, как квадрат, так и прямоугольник можно задавать длиной диагонали и углом между ними. В этом случае проблем с наследованием и изменяемостью не возникает, поведение фигур полностью идентично. Height и Width будут вычисляемые. Но есть еще ромб.


Хм. Угол между диагоналями квадрата всегда 90°, чего в общем случае не скажешь об угле между диагоналями прямоугольника.
Re[3]: И все-таки квадрат это прямоугольник
От: Big_Urri Казахстан  
Дата: 07.03.07 04:17
Оценка:
Здравствуйте, igna, Вы писали:

I>Хм. Угол между диагоналями квадрата всегда 90°, чего в общем случае не скажешь об угле между диагоналями прямоугольника.


Несомненно.
Но в случае, если хранить "внутре" длину диагонали и угол — для этих внутренних полей как базового класса (прямоугольник), так и для потомка (квадрат) исключено противоречивое состояние, как в случае, если хранить длину и ширину (Height<>Width для квадрата). А извне можно манипулировать длиной и шириной (как задавать, так и получать).
А основа признака квадрата — значение угла 90, но не равенство длины и ширины (это следствие прямого угла между диагоналями).
Re[4]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 07.03.07 04:30
Оценка:
Здравствуйте, Big_Urri, Вы писали:

B_U>Но в случае, если хранить "внутре" длину диагонали и угол — для этих внутренних полей как базового класса (прямоугольник), так и для потомка (квадрат) исключено противоречивое состояние, как в случае, если хранить длину и ширину (Height<>Width для квадрата). А извне можно манипулировать длиной и шириной (как задавать, так и получать).


Объект потомка (квадрат) в программе может рассматриваться как объект базового класса (прямоугольник), то есть программа может попытаться к примеру удвоить его ширину оставив высоту неизменной. Ну это в общем тот же аргумент, что и приводят обычно обосновывая некорректность наследования изменяемого квадрата от изменяемого прямоугольника.
Re[10]: И все-таки квадрат это прямоугольник
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.03.07 05:19
Оценка:
Здравствуйте, MouseEntity, Вы писали:
ME>Если же для этого вводить отдельный тип для квадрата, то в неимперативном случае будет достаточно приведений типов — неявных от квадрата к прямоугольнику, явных или неявных от прямоугольника к квадрату (в случае явного приведения программист берёт как бы на себя доказательство утверждения). Хотя это, конечно, имитация теоретико-множественного включение: чтобы всё было математически красиво, надо использовать систему типов, в которой можно использовать типы-подмножества других типов — однако без автоматических доказательств ничего нового они имхо не дадут.
Что-то мне подсказывает, что ситуация с квадратами/прямоугольниками банально слабо описывается тем полиморфизмом, который принят в ООП.
С точки зрения ADT, тип — это как множество значений, так и набор операций над ними. Квадратная матрица является частным случаем прямоугольной. Операция "вычисление детерминанта" применима только к ним. Выразить это традиционным способом явной типизации затруднительно. В С++ это в принципе возможно, но не благодаря ООП.
Две идеи:
1. Отнаследовать класс SquareMatrix<int N> от Matrix<N, N> и добавить в него метод Determinant(), а также оператор (неявного) преобразования из Matrix<N,N>.
Тогда можно будет писать примерно так:
Matrix<4, 3> m1;
Matrix<3, 4> m2;
double D = ((SquareMatrix<4>)(m1 * m2)).Determinant();

2. Сделать Determinant() внешней функцией, определенной только на Matrix<N, N> и писать:
Matrix<4, 3> m1;
Matrix<3, 4> m2;
double D = Determinant(m1 * m2);
1.2.0 alpha rev. 655
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: И все-таки квадрат это прямоугольник
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.03.07 05:20
Оценка: +1
Здравствуйте, igna, Вы писали:

I>Зато квадратная матрица с одной стороны ограничивая прямоугольную равенством количества строк и столбцов, с другой стороны добавляет возможность вычисления детерминанта. Можно наследовать? То есть, что на самом деле важно, расширение или "не сужение"?


Наследовать нельзя. Потому, что собственно прямоугольная матрица с равным количеством строк и столбцов уже должна позволять вычислять детерминант. Нет никакой гарантии что мы сразу создадим объект как именно квадратную матрицу. Результат умножения двух прямоугольных матриц — в общем случае, прямоугольная матрица. И только иногда она может оказаться квадратной, и сразу научиться вычислению детерминанта. Классическое ООП в этом случае считает, что размерность матрицы является частью ее состояния, и результат операции "вычисление детерминанта" существенным образом от этого состояния зависит. В том числе этот результат может быть и выбросом исключения. В классическом ООП нет никакого способа выразить отношения типов, нужные для статического моделирования матриц с разными размерностями.
1.2.0 alpha rev. 655
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: И все-таки квадрат это прямоугольник
От: Big_Urri Казахстан  
Дата: 07.03.07 06:01
Оценка:
Здравствуйте, igna, Вы писали:

I>Объект потомка (квадрат) в программе может рассматриваться как объект базового класса (прямоугольник), то есть программа может попытаться к примеру удвоить его ширину оставив высоту неизменной. Ну это в общем тот же аргумент, что и приводят обычно обосновывая некорректность наследования изменяемого квадрата от изменяемого прямоугольника.


А, ну да. Значит таки позволять задавать только угол и диагональ. Тогда длину и ширину напрямую базовый класс задавать не будет, они будут вычисляемыми. Противоречивость устраняется, но понятно, что на практике манипулировать углом и диагональю для задания прямоугольника скучно.
Re[6]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 07.03.07 06:08
Оценка:
Здравствуйте, Big_Urri, Вы писали:

B_U>А, ну да. Значит таки позволять задавать только угол и диагональ. Тогда длину и ширину напрямую базовый класс задавать не будет, они будут вычисляемыми. Противоречивость устраняется, но понятно, что на практике манипулировать углом и диагональю для задания прямоугольника скучно.


Думаешь так? Тогда смотри:

Объект потомка (квадрат) в программе может рассматриваться как объект базового класса (прямоугольник), то есть программа может попытаться к примеру поманипулировать углом установив его не равным 90°.
Re[7]: И все-таки квадрат это прямоугольник
От: Big_Urri Казахстан  
Дата: 07.03.07 06:25
Оценка:
Здравствуйте, igna, Вы писали:

I>Объект потомка (квадрат) в программе может рассматриваться как объект базового класса (прямоугольник), то есть программа может попытаться к примеру поманипулировать углом установив его не равным 90°.


Согласный
То же самое, но только в профиль
Re[7]: И все-таки квадрат это прямоугольник
От: Tilir Россия http://tilir.livejournal.com
Дата: 07.03.07 06:37
Оценка: 2 (2)
Здравствуйте, igna, Вы писали:

I>То есть "Прямоугольник" не может быть подтипом "Квадрата".


Немножко подумав, вынужден признать, что вы правы. Тем не менее, ЛСП наоборот также не выполняется, если мы предположим стороны изменяемыми раздельно. Для того, чтобы в вашем исходном коде не было ничего криминального, я бы переписал его вот так (не знаю, как это будет на Java). В таком случае квадрат будет поддерживать инвариант одним фактом его создания. Вводить новые поля в квадрате не нужно. В этом случае я согласен и с исходной мыслью — такой квадрат действительно является таким прямоугольником. Но модификатор const на protected членах всё-таки критичен. Это реализует вашу идею, что изменённый прямоугольник — уже другой прямоугольник. Но и в этом случае остаются проблемы (см. комментарии).

class Rectangle{
public:
  explicit Rectangle(double x, double y):m_x(x), m_y(y){};
  virtual double GetSquare() const{ return m_x*m_y;}; // Пока всё хорошо
  virtual double GetPerimeter() const{ return 2.0*(m_x+m_y);}; // Тоже ok.
  // Получаем копию масштабированную в n раз только по x
  virtual const Rectangle GetCopyX(double n){
    return Rectangle(m_x*n, m_y);
  } // Ага! доигрались.
protected:
  // Раздельная модификация (и вообще модификация) сторон невозможна.
  const double m_x;
  const double m_y;
};

// Теперь квадрат. У него переопределяется только конструктор
class Square: public Rectangle{
public:
  explicit Square(double x): ::Rectangle(x, x){};
  // Здесь придётся идти на кривые уловки, например делать
  // private: const Rectangle GetCopyX(double n){}; // чтобы её не дай Б-же не вызвали
};
Re[8]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 07.03.07 07:34
Оценка:
Здравствуйте, Tilir, Вы писали:

T>... Но модификатор const на protected членах всё-таки критичен.


+1

Да, это я упустил. "Критичен" это может быть сказано слишком сильно, пользователь класса все равно ширины и высоты не изменит, но разработчику класса контроль компилятора пойдет на пользу. И наверное еще больше модификатор пойдет на пользу тому, кто читает определение класса.

На Java это модификатор final:

    . . .
    final int width, height;
    . . .
Re[2]: И все-таки квадрат это прямоугольник
От: Pavel Dvorkin Россия  
Дата: 07.03.07 07:47
Оценка: +1 :))) :))
Здравствуйте, Big_Urri, Вы писали:

B_U>А еще, как квадрат, так и прямоугольник можно задавать длиной диагонали и углом между ними. В этом случае проблем с наследованием и изменяемостью не возникает, поведение фигур полностью идентично. Height и Width будут вычисляемые. Но есть еще ромб.


Только не ромб! Не надо ромбов! Никаких ромбов не надо! Дискуссию с участием еще и ромба сервер не выдержит!

P.S. Как много у программистов свободного времени
With best regards
Pavel Dvorkin
Re[3]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 07.03.07 08:22
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Только не ромб! Не надо ромбов! Никаких ромбов не надо! Дискуссию с участием еще и ромба сервер не выдержит!


Здесь похоже можно и ромб от квадрата произвести. А потом и четырехугольник от него.

PD> P.S. Как много у программистов свободного времени


У меня оно кончается сегодня, завтра будет так:
Re: И все-таки квадрат это прямоугольник
От: last_hardcoder  
Дата: 07.03.07 08:49
Оценка:
Здравствуйте, igna, Вы писали:

I>
I>class Rectangle {
I>    int width, height;

I>    public Rectangle(int width, int height) {
I>        this.width = width;
I>        this.height = height;
I>    }
I>    public int Width() {
I>        return width;
I>    }
I>    public int Height() {
I>        return height;
I>    }
I>}

I>class Square extends Rectangle {
I>    public Square(int side) {
I>        super(side, side);
I>    }
I>}
I>


Это решение соответствует минимуму кода и максимуму памяти, занимаемой объектом. Оно не является идеальным для 100% случаев применения.
Re[2]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 07.03.07 08:57
Оценка:
Здравствуйте, last_hardcoder, Вы писали:

_>Это решение соответствует минимуму кода и максимуму памяти, занимаемой объектом. Оно не является идеальным для 100% случаев применения.


Конечно нет, но оно возможно и корректно. Вопреки распространенному мнению, что квадрат якобы вообще никогда нельзя производить от прямоугольника.
Re: И все-таки квадрат это прямоугольник
От: elmal  
Дата: 07.03.07 09:23
Оценка:
Здравствуйте, igna, Вы писали:

А почему рассматриваете только простейшие случаи наследования? Если мне не изменяет память (из школьного курса математики), то квадрат это правильный многогранник (терминологию могу забыть уже), у которого число граней равно 4. А прямоугольник это более общий случай многогранника. И иерархия наследования для квадрата будет "Фигура <- Многогранник <- правильный многогранник <- квадрат (хотя его можно не выделять)". Плюс кваррат является четырехугольником (то есть множественное наследование). А для прямоугольника — "Фигура <- Многогранник <- четырехугольник <- прямоугольник".

Это естественно только одна из возможных иерархий наследования. Можно сделать посложнее, можно попроще. А степень сложности будет определяться требованиями к поддержке фигур, в случае, если изначально нужно поддерживать только прямоугольники и квадраты, то наследовать квадрат от прямоугольника допустимо. Также степень сложности будет определяться методами классов, в случае, если от этих фигур требуется только рисоваться, то лучше вообще определить, что и то, и другое является фигурами (абстрактный класс) и не мучиться с наследованием. А если потребуется там площади, периметры, диагонали считать — то иерархию придется пересмотреть. Главное в иерархиях наследования, чтобы они упрощали все, а не усложняли плюс убирали дублирующийся код. XP рулит, заранее все усложнять не очень хорошо . Все равно заранее всего не предусмотреть.
Re[3]: И все-таки квадрат это прямоугольник
От: last_hardcoder  
Дата: 07.03.07 09:43
Оценка:
Здравствуйте, igna, Вы писали:

I>Конечно нет, но оно возможно и корректно. Вопреки распространенному мнению, что квадрат якобы вообще никогда нельзя производить от прямоугольника.


Если отвлечся от конкретики фигур, то получается, что частные случаи нельзя выражать через общие? Ну это бред какой-то. И частные через общие можно выражать, и развивать частные до общих, и независимо реализовывать и то и другое. Вопрос лишь в ресурсах, которые тратятся в каждом случае.
Re[2]: И все-таки квадрат это прямоугольник
От: last_hardcoder  
Дата: 07.03.07 10:48
Оценка:
Здравствуйте, Tilir, Вы писали:

T>Ох уж мне эти java-developer'ы... Ясное дело, Мейерса вы не читали. А между прочим, в книге "Эффективное использование C++" есть целый раздел, посвящённый тому, почему (в рамках философии C++) квадрат нельзя наследовать от прямоугольника. Коротко говоря, для него не выполняется LSP. Очень советую ознакомится. Если лень читать всю книжку, то подскажу: см. правило №35.


Там сказано, что нельзя публично наследовать. А приватно то что мешает?
Re[3]: И все-таки квадрат это прямоугольник
От: FDSC Россия consp11.github.io блог
Дата: 07.03.07 11:11
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, Big_Urri, Вы писали:


B_U>>А еще, как квадрат, так и прямоугольник можно задавать длиной диагонали и углом между ними. В этом случае проблем с наследованием и изменяемостью не возникает, поведение фигур полностью идентично. Height и Width будут вычисляемые. Но есть еще ромб.


PD>Только не ромб! Не надо ромбов! Никаких ромбов не надо! Дискуссию с участием еще и ромба сервер не выдержит!


Предлагаю наследовать вместо ромба токосъёмник от электропоездов

PD>P.S. Как много у программистов свободного времени


Мда... только вот потом все почему-то жалуются на то, что заставляют работать сверхурочно
Re[8]: И все-таки квадрат это прямоугольник
От: . Великобритания  
Дата: 07.03.07 11:35
Оценка:
Tilir wrote:

> // private: const Rectangle GetCopyX(double n){}; // чтобы её не дай Б-же не вызвали

Ну вот и меня соблазнили в флейм ввязаться!
Почему не бы вызвать? Пусть вызывают, вернётся нормальный прямоугольник, полученный растягиванием стороны квадрата.

По моему главное при наследовании down-casting. Т.е. если мы имеем
class Rectangle;
class Square : Rectange;

то всё ок.
Square *sq = new Square(5);
assert(sq.GetWidth()*4 == sq.GetPerimeter());
Rectange *rect = sq;
assert((rect.GetWidth()+rect.GetHeight())*2 == rect.GetPerimeter());

Если же наследоваться наоборот
class Square;
class Rectangle : Square;

, то получаются квадраты со сторонами 3*4 — гадость!
Rectangle *rect = new Rectangle(3,4);
Square *sq = rect;
assert(sq.GetWidth()*4 == sq.GetPerimeter());//Бабах!

Т.е. идея такова, что экземлпяры наследника должны вести себя точно также, как экземпляры базы.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[4]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 07.03.07 11:50
Оценка:
Здравствуйте, last_hardcoder, Вы писали:

_>Если отвлечся от конкретики фигур, то получается, что частные случаи нельзя выражать через общие? Ну это бред какой-то. И частные через общие можно выражать, и развивать частные до общих, и независимо реализовывать и то и другое. Вопрос лишь в ресурсах, которые тратятся в каждом случае.


Ну открой тему с названием вроде "Можно без неприятностей открыто наследовать прямоугольник от квадрата" и одевай каску.
Re[3]: И все-таки квадрат это прямоугольник
От: igna Россия  
Дата: 07.03.07 11:56
Оценка:
Здравствуйте, last_hardcoder, Вы писали:

_>Там сказано, что нельзя публично наследовать. А приватно то что мешает?


Но ведь это форум "Философия программирования", а не "C/C++". Я думаю, в этом форуме "наследование" означает "открытое наследование".
Re[4]: И все-таки квадрат это прямоугольник
От: last_hardcoder  
Дата: 07.03.07 13:58
Оценка:
Здравствуйте, igna, Вы писали:

I>Но ведь это форум "Философия программирования", а не "C/C++". Я думаю, в этом форуме "наследование" означает "открытое наследование".


Бедные не "C/C++" программисты :'( Ну тогда всё правильно, Либо SetWidth должен отсутствовать (что существенно сужает область применения и крайне нежелательно, т.к может стать препядствием расширения системы в будущем, даже если на текущем этапе это не нужно). Либо наследовать нельзя и нужно создавать обёртку, прячущую SetWidth, отличным от наследования способом.
Re[9]: И все-таки квадрат это прямоугольник
От: Tilir Россия http://tilir.livejournal.com
Дата: 07.03.07 14:15
Оценка:
Здравствуйте, ., Вы писали:

.>, то получаются квадраты со сторонами 3*4 — гадость!

Rectangle *rect = new Rectangle(3,4);
Square *sq = rect;
assert(sq.GetWidth()*4 == sq.GetPerimeter());//Бабах!

.>Т.е. идея такова, что экземлпяры наследника должны вести себя точно также, как экземпляры базы.

Вот здесь есть моя реализация:
http://www.rsdn.ru/Forum/Message.aspx?mid=2395831&amp;only=1
Автор: Tilir
Дата: 06.03.07


Она в данном случае не даст бабаха, поскольку виртуальная GetWidth (её там напрямую нет, но легко доопределить) для прямоугольника будет возвращать m_Width, а для квадрата m_Len.

Вообще по здравому размышлению, мне до сих пор очень нравится этот код — я так и не смог придумать ситуации, когда бы он привёл к откровенно плохим результатам. Не нужны даже const-модификаторы, а LSP выполняется, поскольку "Все стороны равны" у моего квадрата вырождается в "m_Len==m_Len", что выполняется и для прямоугольника. И побочных эффектов http://www.rsdn.ru/Forum/Message.aspx?mid=2396945&amp;only=1
Автор: Tilir
Дата: 07.03.07
он не вызывает. И по памяти оптимален — зачем квадрату два закрытых члена для длины и ширины? Ему и одного хватит.
А что? Прямоугольник — это на самом деле квадрат, только у него стороны разные.
Re[10]: И все-таки квадрат это прямоугольник
От: . Великобритания  
Дата: 07.03.07 14:41
Оценка:
Tilir wrote:

> А что? Прямоугольник — это на самом деле квадрат, только у него стороны

> разные.
Нет, представь себе, что у тебя есть функция, на вход берущая квадраты.
Она вполне имеет право ожидать, что квадраты квадратные и ничего не знать о существовании прямоугольников.
Так как у тебя от квадрата наследуется прямоугольник, ты можешь получить косвенно вызов "functionForSquaresOnly(new
Rectangle(3,4))"
И функция будет удивлена, обнаружив очень странные свойства у переданного ей квадарата, как то что вдруг периметр стал
каким-то неправильным, например не выполняется "square.getWidth()*4==square.getPerimeter()" и т.п.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[10]: И все-таки квадрат это прямоугольник
От: deniok Россия  
Дата: 07.03.07 14:42
Оценка: +1 :))) :)
Здравствуйте, Tilir, Вы писали:

T>А что? Прямоугольник — это на самом деле квадрат, только у него стороны разные.


Эллипс — это круг, вписанный в квадрат размером три на два.
Re: Квадрат И ЕСТЬ прямоугольник
От: Poudy Россия  
Дата: 08.03.07 17:28
Оценка: 13 (1) -1
Кажется, пример про квадрат и прямоугольник совершенно идиотский, однако это не так.
В том или ином виде эта задача регулярно всплывает.
Например:
"файл" — "бинарный файл" — "текстовый файл",
"файл" — "файл только для чтения"
"контрол" — "контрол-контейнер" — "табконтрол"
"коллекция" — "список" — "типизированный список"
"маршалер" — "конкретный маршалер"

и уже упоминаемые здесь "матрица" — "квадратная матрица".


Мое решение такое:

    class Rectangle
    {
        public Rectangle(int width, int height)
        {
            this.width = width;
            this.height = height;
        }
        public Rectangle(int squareSide)
            : this(squareSide, squareSide)
        {
        }

        public bool IsSquare
        {
            get { return this.width == this.height; }
        }

        private int width;
        public int Width
        {
            get { return this.width; }
            set { this.width = value; }
        }

        private int height;
        public int Height
        {
            get { return this.height; }
            set { this.height = value; }
        }
    }


Оно нехорошо только тем, что нельзя задать определение функции, которая принимает квадрат.
Вообще это тоже серьезный недочет, однако мы как-то живем с функциями, которые принимают int, но он должен быть > 0, и с функциями, которые принимают файл, который должен быть доступен на запись. И понятно почему!

Открытое наследование, как наследование и интерфейса, и реализации, практически всегда используется на практике как средство уточнения типа. конкретизации. А реализация интерфейса — как обобщение. Щас я имею в виду C#. Т.е. если я вижу, что человек отнаследовался от Control, я понимаю — он хочет конкретизировать Control, заюзать функциональность базового класса. И я не должен ждать от него соблюдения LSP. Если же я вижу реализацию интерфейса IComponent, я понимаю — человек хочет встроить свой класс в инфраструктуру компонентов и жду от него соблюдения LSP. Потому как если он не соблюдет, уже готовый код инфраструктуры завалится с исключением и класс этот никуда не встроится. Вот почему на практике программист обычно понимает что к чему.

IMHO, объектные системы должны быть написаны именно так. Т.е. чтобы а) не плодить интерфейсы ISquare, которые все равно бесполезны при изменяемых объектах, б) не плодить ISquare, когда вариантов "фигур" очень много (например, они задаются пересечением 3х енумов по 10 записей в каждом) и в) позволять как-то узнать о том, можно ли вызывать ThisFunction(Rectangle), не обрамляя это в try/catch, нужны свойства по типу IsRectangle. Когда-то давно в таком же обсуждении я заморочился и написал большой пример
Автор: Poudy
Дата: 17.01.05
.
Re[2]: Квадрат И ЕСТЬ прямоугольник
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 09.03.07 08:23
Оценка:
Poudy,

P>IMHO, объектные системы должны быть написаны именно так. Т.е. чтобы а) не плодить интерфейсы ISquare, которые все равно бесполезны при изменяемых объектах, б) не плодить ISquare, когда вариантов "фигур" очень много (например, они задаются пересечением 3х енумов по 10 записей в каждом) и в) позволять как-то узнать о том, можно ли вызывать ThisFunction(Rectangle), не обрамляя это в try/catch, нужны свойства по типу IsRectangle. Когда-то давно в таком же обсуждении я заморочился и написал большой пример
Автор: Poudy
Дата: 17.01.05
.


Хм, за 2 года твои взгляды однако сильно не изменились
Автор: Poudy
Дата: 16.01.05
.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[2]: Бинарный файл -> текстовый файл
От: FDSC Россия consp11.github.io блог
Дата: 09.03.07 10:05
Оценка:
Здравствуйте, Poudy, Вы писали:

P>Кажется, пример про квадрат и прямоугольник совершенно идиотский, однако это не так.

P>В том или ином виде эта задача регулярно всплывает.
P>Например:
P> "файл" — "бинарный файл" — "текстовый файл",

Тут мне кажется, всё нормально. Где закавыка?

P> "файл" — "файл только для чтения"


Ну, это хороший пример
Re[3]: Квадрат И ЕСТЬ прямоугольник
От: Poudy Россия  
Дата: 10.03.07 07:26
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Poudy,


P>>IMHO, объектные системы должны быть написаны именно так. Т.е. чтобы а) не плодить интерфейсы ISquare, которые все равно бесполезны при изменяемых объектах, б) не плодить ISquare, когда вариантов "фигур" очень много (например, они задаются пересечением 3х енумов по 10 записей в каждом) и в) позволять как-то узнать о том, можно ли вызывать ThisFunction(Rectangle), не обрамляя это в try/catch, нужны свойства по типу IsRectangle. Когда-то давно в таком же обсуждении я заморочился и написал большой пример
Автор: Poudy
Дата: 17.01.05
.


LCR>Хм, за 2 года твои взгляды однако сильно не изменились
Автор: Poudy
Дата: 16.01.05
.


Ну я этот же пост и привел. Собственно, взглядам совсем не обязательно меняться за два года.
Кстати, если уж о взглядах ... за 2 года вот что поменялось:
1. LazyLoading — теперь сичтаю, что это вредная идея вообще;
2. Сущности — раньше думал, что должны быть "бесшовными" в плане общения с сервером, чтобы все было автоматом и незаметно. Сейчас думаю, что сервер и клиент должны всегда рассматриваться как совершенно разные приложения (ну примерно как сервер — ERP, а клиент — софт на КПК) и, соответственно, у сервера и клиента должны быть свои уникальные версии модели.
3. Про средства разработки в ERP — теперь считаю, все должно работать в VisualStudio.
Re[3]: Бинарный файл -> текстовый файл
От: Poudy Россия  
Дата: 10.03.07 07:32
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>Здравствуйте, Poudy, Вы писали:


P>>Кажется, пример про квадрат и прямоугольник совершенно идиотский, однако это не так.

P>>В том или ином виде эта задача регулярно всплывает.
P>>Например:
P>> "файл" — "бинарный файл" — "текстовый файл",

FDS>Тут мне кажется, всё нормально. Где закавыка?

Закавыка в дереве наследования. Как наследовать?
Вообще говоря, текстовый поток UTF-8 или UTF-16 "испортится", если из него взять и прочитать байт как из бинарного. По-другому должны работать откат на одну позицию и вообще seek. Какой-нибудь светлой голове может прийти в голову наследовать текстовый от бинарного (или наоборот . Я думаю в данном примере текстовый файл — это ваще отдельно. Т.е. не должно быть понятия "текстовый файл". Должно быть так: "бинарный файл" — "текстовый ридер".
Re[4]: И!
От: Poudy Россия  
Дата: 10.03.07 10:07
Оценка:
Здравствуйте, Poudy, Вы писали:

P>>>Должно быть так: "бинарный файл" — "текстовый ридер".


Непонятно написал. Забыл ометить, что "текстовый ридер" не наследуется от "бинарного файла", а агрегирует его.
Re: Топологически прямоугольникт- это изменённый квадрат
От: Michael7 Россия  
Дата: 25.04.07 06:32
Оценка: :)
Здравствуйте, igna, Вы писали:

I>Все-таки математика права, квадрат это прямоугольник,


Кстати, насчёт математики тоже не всё так просто, есть два подхода.
В обычной, хорошо нам знакомой, статической геометрии можно считать, что квадрат — это прямоугольник с равными сторонами.

Но есть ещё такой раздел математики как топология. Так вот с точки зрения топологии, наоборот, прямоугольник — это растянутый(или сжатый) квадрат. То есть, первичен именно квадрат.
Re[2]: Топологически прямоугольник- это изменённый квадрат
От: Michael7 Россия  
Дата: 25.04.07 06:36
Оценка:
Хотел исправить заголовок, удалив предыдущее сообщение — не вышло, если появилась "бомбочка", то я вовсе не отказываюсь от своего сообщения, а только хотел поправить заголовок.
Re: И все-таки квадрат это прямоугольник
От: no4  
Дата: 25.04.07 10:44
Оценка:
Здравствуйте, igna, Вы писали:

Есть язык в котором прямоугольник может стать квадратом — то есть классификация динамическая на основе свойств
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: И все-таки квадрат это прямоугольник
От: vdimas Россия  
Дата: 25.04.07 13:05
Оценка:
Здравствуйте, no4, Вы писали:


no4>Есть язык в котором прямоугольник может стать квадратом — то есть классификация динамическая на основе свойств


Что за язык?
Re[2]: Топологически прямоугольникт- это изменённый квадра
От: Sergey Россия  
Дата: 25.04.07 13:05
Оценка: +2
Здравствуйте, Michael7, Вы писали:

I>>Все-таки математика права, квадрат это прямоугольник,


M>Кстати, насчёт математики тоже не всё так просто, есть два подхода.

M>В обычной, хорошо нам знакомой, статической геометрии можно считать, что квадрат — это прямоугольник с равными сторонами.

M>Но есть ещё такой раздел математики как топология. Так вот с точки зрения топологии, наоборот, прямоугольник — это растянутый(или сжатый) квадрат. То есть, первичен именно квадрат.


Насколько я помню, с точки зрения топологии квадрат и прямоугольник вообще неотличимы.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[3]: И все-таки квадрат это прямоугольник
От: no4  
Дата: 26.04.07 05:57
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, no4, Вы писали:



no4>>Есть язык в котором прямоугольник может стать квадратом — то есть классификация динамическая на основе свойств


V>Что за язык?


Я уже не помню, было что-то, где можно было сказать что-то типа

class Suqare extends Rectangle where (width == height)
{
...
}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: И все-таки квадрат это прямоугольник
От: no4  
Дата: 26.04.07 05:57
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, no4, Вы писали:



no4>>Есть язык в котором прямоугольник может стать квадратом — то есть классификация динамическая на основе свойств


V>Что за язык?



А может и наврал....
http://www.cs.washington.edu/research/projects/cecil/www/cecil.html#resources

Cecil has predicate objects, which allow virtual "subclasses" to be defined carrying specialized methods that override their parent's methods whenever some boolean predicate over the object is true. In this way, inheritance can be used to model time-varying and/or state-dependent properties of objects just like permanent properties of objects.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.