2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3, 4, 5, 6  След.
 
 
Сообщение21.03.2006, 19:21 
Заслуженный участник
Аватара пользователя


16/03/06
406
Moscow
незванный гость писал(а):
Если же Вы считаете, что все было так хорошо, попытайтесь ответить на вопрос -- зачем же в Java были введены (поздно, далеко не в первой версии) generics?

Не знаю, к сожалению, что это такое.

Думаю, что метод решения при помощи базового класса плох тем, что он ослабляет проверку типов. Это может вызвать желание создать какой-нибудь workaround. Но шаблоны тоже обладают этим недостатком, но иного рода. Допустим, вы пишите шаблон, который предполагает, что в классе-параметре есть член с определённым именем или метод. Компилятор этого не проверит. А метод с базовыми классами проверит: вы можете потребовать, чтобы класс обладал определённым интерфейсом.

незванный гость писал(а):
И что, можно break функцию? Или класс?!?

Функцию можно. Только вместо break надо писать return. Класс тоже можно, если возникнет исключение.

Цитата:
break -- это не просто return. Заметьте, Вы не можете написать его вне цикла -- там он не нужен, есть и другие операторы.

С чего Вы взяли? Вот, читаю мануал -- там написано, что можно.

 Профиль  
                  
 
 
Сообщение21.03.2006, 21:18 


29/05/05
143
Dims писал(а):
В Си++ структура ничем не отличается от класса кроме [...]


Первые два пункта в моём списке - это одни из мелочей. Я могу привести их... ну, не 100, но достаточное количество. Какой смысл в наборе этого длинного списка, если Вы всё равно ответите: "Удобства-вольности-сокращения один тире сто - это не нужно, это недостаток, это нарушает чистоту и красоту ОО концепции"?

Dims писал(а):
Ничего не мешает отпределить класс с одной статической функцией. Но это желание обычно говорит о неполноте объектного подхода.


Ни о какой неполноте это не говорит. Если бы Страуструп хотел, то сделал бы так, чтобы все функции-нечлены были по умолчанию членами root-сласса (дабы сохранить "чистоту" ОО концепции), впрочем, Вы можете считать, что это так, если будет легче:). Только зачем? То, что существует в C++ удобно, не ухудшает читабельность кода, не пораждает принципиальных ошибок, и не приносит элегантность в жертву "чистоте".

Dims писал(а):
Не не поддерживается, а намеренно запрещено. В Си++ это приводило к идеологическим глюкам. Например, если два класса являются наследниками одного, а потом оба порождают третий, то должен ли самый базовый класс входит в него дважды?


О каких глюках Вы говорите? В C++ можно использовать любой из двух описанных вами способов (и дважды, и не дважды) по желанию.

Dims писал(а):
Если нужно много базовых классов, логично их все сделать просто членами.


А вот и нет: это просто ещё один вариант (наследование vs композиция), который имеет как свои недостатки, так и преимущества.
Кстати, почему в интерфейсах "логика" нарушается?:)

Dims писал(а):
dikun писал(а):
нет шаблонов (templates).

Тоже правильно. Вы должны написать функции или класс, определённые для надкласса. А потом передавать ему экземпляры подкласса. Это будет то же самое, что и шаблоны.


Заблуждение.
\text{ со всеми вытекающими.
Кстати, я, глянув на спецификацию по предоставленной Sanyok ссылке, увидел до боли знакомые вещи:
Код:
class Outer<T>{
        T t;
        class Inner {
                T setOuterT(T t1) {t = t1;return t;}
        }
}

Это называется Parameterized Types :)

 Профиль  
                  
 
 
Сообщение21.03.2006, 21:44 


29/05/05
143
MrD писал(а):
4. Не понимаю о чем речь...


Я хочу реализовать интерфейс WindowListener. От меня требуют, чтобы реализованы были все методы этого слушателя (весьма распространённая практика в мире Java - использовать интерфейсы:)). Но зачем мне все? Мне, например, нужен только один. Тогда я пишу примерно следующее
Код:
class MyWindowListener extends WindowAdapter {
  public void windowClosing(WindowEvent e) {
    System.exit(0);
  }
}

Хе-хе. Мне повезло-о-о... Нужного адаптера могло и не оказаться (самому ваять?) - привет интерфейсам!
Думаете, это единственная ситуация, где программиста принуждают юзать паттерн из GoF? Сами придумали проблему. Сами её и решили:).

 Профиль  
                  
 
 
Сообщение21.03.2006, 21:49 
Заслуженный участник
Аватара пользователя


17/10/05
3709
:evil:
Dims писал(а):
Не знаю, к сожалению, что это такое.

Все тот же мануал, на который Вы позже ссылаетесь.

Dims писал(а):
незванный гость писал(а):
И что, можно break функцию? Или класс?!?

Функцию можно. Только вместо break надо писать return. Класс тоже можно, если возникнет исключение.

Заметьте, я не писал прервать. Я писал break (а имел в виду break и continue). Есть все-таки разница между возвратом управления из метода (потенциально, с возвратом значения) и прерыванием исполнения цикла. Сходство -- на уровне ассемблера, да и то не полное. Класс же вовсе нельзя прервать, это Вас кто-то обманул. Класс не имеет потока управления, класс -- это статическая структура (включающая данные и методы).

Dims писал(а):
Цитата:
break -- это не просто return. Заметьте, Вы не можете написать его вне цикла -- там он не нужен, есть и другие операторы.

С чего Вы взяли? Вот, читаю мануал -- там написано, что можно.

Виноват, с break label погорячился. А вот с continue -- нет.

Интересно, что в контексте этого определения break и вовсе становиться структурным переходом. Чем он лучше goto? Именем? В чем состоит структурное программирование с таким break'ом? """Не так ли поступают и язычники?"""

 Профиль  
                  
 
 
Сообщение21.03.2006, 22:14 
Заслуженный участник
Аватара пользователя


17/10/05
3709
:evil:
2 Dikun:
Я, в основном, согласен с Вашим ответом Dims и очень Вам благодарен за него.

dikun писал(а):
Dims писал(а):
Не не поддерживается, а намеренно запрещено. В Си++ это приводило к идеологическим глюкам. Например, если два класса являются наследниками одного, а потом оба порождают третий, то должен ли самый базовый класс входит в него дважды?


О каких глюках Вы говорите? В C++ можно использовать любой из двух описанных вами способов (и дважды, и не дважды) по желанию.


Есть тут действительно глюки. Я буду писать пример сокращенно, но, надеюсь, понятно.
Код:
class O {
public:
  virtual int f();
};

class X: virtual public O {
public:
  virtual int f();
};

class Y: virtual public O {
public:
  virtual int f();
};

class A
  : virtual public X
  : virtual public Y
{
};

class B
  : virtual public Y
  : virtual public X
{
};

class T
  : virtual public A
  : virtual public B
{
};

void g{
  T t;

  t.f();
}

Сможете ли Вы без внимательного анализа сказать, который f() вызовется в g()? Я не смогу. Я предполагаю, что С++ либо запрещает такую конструкцию, либо задает порядок разрешения. Но читаемость это не повышает, чего уж там.

Здесь дело не столько в отсутствие четких правил, сколько в проблемах с ожидаемым результатом, который весьма трудно угадать. Если убрать виртуальное наследование, появляется еще один слой интересных вопросов -- в этой структуре стоит хоть раз покопаться, чтобы усвоить механизмы наследования в С++.

 Профиль  
                  
 
 
Сообщение21.03.2006, 22:19 
Заслуженный участник
Аватара пользователя


17/10/05
3709
:evil:
dikun писал(а):
Хе-хе. Мне повезло-о-о... Нужного адаптера могло и не оказаться (самому ваять?) - привет интерфейсам!

Лично я склонен считать, что класс (модуль, компонента, библиотека), экпортирующий listener обязан экспортировать и базовый адаптер -- как правило хорошего тона. Аки мытье рук перед едой. Тогда его и искать особливо не надо.

 Профиль  
                  
 
 
Сообщение22.03.2006, 23:51 
Заслуженный участник
Аватара пользователя


16/03/06
406
Moscow
dikun писал(а):
Первые два пункта в моём списке - это одни из мелочей. Я могу привести их... ну, не 100, но достаточное количество. Какой смысл в наборе этого длинного списка, если Вы всё равно ответите: "Удобства-вольности-сокращения один тире сто - это не нужно, это недостаток, это нарушает чистоту и красоту ОО концепции"?

Ну так что ж. Вы просто привыкли писать на Си++. И поэтому в похожем языке -- Джаве -- Вам кажутся писутствующими множество мелких недостатков. А на самом деле, это просто эффект привычки.

Цитата:
Dims писал(а):
Ничего не мешает отпределить класс с одной статической функцией. Но это желание обычно говорит о неполноте объектного подхода.

Ни о какой неполноте это не говорит. Если бы Страуструп хотел, то сделал бы так, чтобы все функции-нечлены были по умолчанию членами root-сласса (дабы сохранить "чистоту" ОО концепции),

Не знаю, хотел ли он. Но он не мог: он был связан синтаксисом простого Си.

Цитата:
Только зачем? То, что существует в C++ удобно, не ухудшает читабельность кода, не пораждает принципиальных ошибок, и не приносит элегантность в жертву "чистоте".

Я уже говорил, зачем, по моему мнению нужна чистота. Это не эстетство. Это способ избегать ошибок.

Цитата:
Dims писал(а):
Не не поддерживается, а намеренно запрещено. В Си++ это приводило к идеологическим глюкам. Например, если два класса являются наследниками одного, а потом оба порождают третий, то должен ли самый базовый класс входит в него дважды?

О каких глюках Вы говорите? В C++ можно использовать любой из двух описанных вами способов (и дважды, и не дважды) по желанию.

Как?

Цитата:
Dims писал(а):
Если нужно много базовых классов, логично их все сделать просто членами.

А вот и нет: это просто ещё один вариант (наследование vs композиция), который имеет как свои недостатки, так и преимущества.

Не понял. Базовый класс -- это, по сути, просто "самый родной" член. Если у вас слишком много родных, то вам, вероятно, уже нелогично считать их всех "самыми".

Цитата:
Кстати, почему в интерфейсах "логика" нарушается?:)

Потому что интерфейсы нужны для другого.


Цитата:
Dims писал(а):
dikun писал(а):
нет шаблонов (templates).

Тоже правильно. Вы должны написать функции или класс, определённые для надкласса. А потом передавать ему экземпляры подкласса. Это будет то же самое, что и шаблоны.


Заблуждение.
\text{ со всеми вытекающими.

Ничё не понял.

 Профиль  
                  
 
 
Сообщение23.03.2006, 00:01 
Заслуженный участник
Аватара пользователя


16/03/06
406
Moscow
незванный гость писал(а):
:evil:
Dims писал(а):
Не знаю, к сожалению, что это такое.

Все тот же мануал, на который Вы позже ссылаетесь.

А, ну да. Не знал такого. Естестественно, это шаблоны. Значит, происходит "эрозия", вероятно, под влиянием маркетинговых требований. Я лично очень долго приучал себя отказаться от шаблонов.

 Профиль  
                  
 
 
Сообщение23.03.2006, 01:05 
Заслуженный участник
Аватара пользователя


17/10/05
3709
:evil:

1) В С++ возможно "виртуальное" наследование:
Код:
class A
  : public BB
  : virtual public CC
{    } ;

В случае BB предки будут размножаться. В случае CC -- не будут.

2) Вы большой сторонник чистоты языка. Это тоже не ново: в 1976 году вышло "Пересмотренное сообщение об Алголе-68". Там многие неэлегантности и избыточные черты были убиты на корню. А люди предпочли не стройность, а практичность. Может быть потому, что программы пишут, а не поэмы. Этим-то и жив и процветает мной нелюбимый Perl -- в нем каждый находит свой любимый стиль. А из Java можно было бы выкинуть треть, следуя принципу неизбыточности. И читаемость бы не ухудшилась.

Со временем пропадает желание поучать, как следует программировать. Сменяются языки, и то, что когда-то казалось почти идеалом, перестает удовлетворять. Потом и это проходит :D. Простите, пофилософствовать потянуло.

3) Когда человек осваивает новый язык, он, естественно, ищет в нем способы решения старых задач. Именно поэтому мало прочитать LRM. Но сводить этот поиск к эффекту привычки -- неправильно. Это активное освоение идиоматики языка.

Здесь же замечу, что чистых языков мало, они слишком не практичны. Я бы, пожалуй, назвал Forth -- обратная польская запись в чистом виде, может быть Lisp -- как функциональный язык. Я не знаю ни одного чистого ОО языка! Все известные мне "ОО" языки срочно становятся традиционными, когда речь заходит об арифметике (ух, как не ОО!). Более того, они испытывают непреодаленные трудности в реализации именно объектной модели -- к примеру, множественные ассоциации и объекты (методы) связанные с ассоциацией (их приходиться приклеивать лейкопластырем к одному из объектов).

Поэтому появление шаблонов -- вряд ли эрозия. Скорее, требование жизни. Я уже пытался обратить Ваше внимание на то, что шаблоны новее ОО языков, добавляются в них после создания (за исключением C#). Рискну высказать идею -- появяться способы потребовать в шаблоне реализацию классом-параметром необходимого интерфейса, или набора интерфейсов. И, таким образом, будет заметно улучшена диагностика шаблонов. Или же шаблоны исчезнут, если будут найдены лучшие методы выполнения функций, которые они выполняют сейчас (так исчезла передача параметра по наименованию -- вряд ли многие вспомнят что это такое или чем она плоха).

4) Ваша концепция базового класса -- "самый родной член" -- несколько неортодоксальна, по меньшей мере, не общепринята. Одно время в плохих книжках было модно вводить класс Точка с методом переместить(), а затем из него выводить классы Круг, Квадрат -- в которых эта точка служит центром. На сегодняшний день самой популярной является концепция "разновидности" -- то есть, если есть класс Человек, мы из него можем вывести класс Мужчина -- ибо Мужчина есть разновидность Человека, всяк Мужчина -- Человек. В противоположность этому, мы не можем вывести класс Мужчина из класса Голова -- хотя у большинства и есть голова на плечах. Мы можем также вывести класс Мужчина из класса Самец, и, понятно, что Мужчина имеет и черты Самца, и черты Человека. Но ни Человек, ни Самец не являются "самыми родными членами" -- это классы, к которым можно отнести мужчин. Врядли можно сказать однозначно, чего в Мужчине больше -- Человека или Самца (зависит от ситуации, не так ли?). Поэтому приходиться соглашаться, что больше, чем один класс. А интерфейсов у Мужчины много, и не все они наследуются из классов-предков -- например, Отец есть весьма специфический интерфейс.

5) Что же непонятно с разницей передачи класса и объекта класса? Мне нужно описать новый объект класса -- мне нужен класс. Никакой экземпляр класса мне класс не заменит. И для создания нового объекта мне нужен класс -- чтобы не писать в каждом классе изготовитель (не конструктор) копии.

6) Мне трудно говорить за Страуструпа -- я не знаю его, никогда не встречался. Но то, что он мог -- это однозначно. Но не захотел. Я вообще a priori считаю, что авторы языков склонны к весьма серьезно мотивированным решениям, хотя и совершают иногда ошибки. Именно поэтому мне интереснее спросить -- почему в языке так, а не иначе, а не заявлять -- "Так (не)правильно!".

 Профиль  
                  
 
 
Сообщение23.03.2006, 07:17 


01/01/06
35
Может, если говорить о практичности, то будущее за мультипарадигменными языками? Попытки то делаются, пусть даже пока в учебных целях.

 Профиль  
                  
 
 
Сообщение23.03.2006, 08:41 
Заслуженный участник
Аватара пользователя


17/10/05
3709
:evil:
temp писал(а):
Может, если говорить о практичности, то будущее за мультипарадигменными языками? Попытки то делаются, пусть даже пока в учебных целях.

Я тоже так считаю. "Чистые" языки imho хороши для обкатки и демонстрации идей, но не на практике.

 Профиль  
                  
 
 
Сообщение23.03.2006, 13:15 
Заслуженный участник
Аватара пользователя


16/03/06
406
Moscow
незванный гость писал(а):
1) В С++ возможно "виртуальное" наследование:
Код:
class A
  : public BB
  : virtual public CC
{    } ;

В случае BB предки будут размножаться. В случае CC -- не будут.

Не знал такого.

Цитата:
2) Вы большой сторонник чистоты языка. Это тоже не ново:

Нет, не так. Я просто перешёл с Си++ на Джаву и первое время, как и у всех, ощущал нехватку определённых возможностей из Си++. Но со временем я начал понимать, как их получить на Джаве и какой в этом есть резон. Только резон. Я не предлагаю ничего абсолютизировать. Уж точно не Джаву и не Си++. Может быть, когда-нибудь, будет создан идеальный язык. Но в этом случае никаких споров по этому поводу возникать не будет, так как это будет всем очевидно.

Кроме того, я периодически дрейфовал между другими языками, например, Бейсиком, T-SQL-ем, PHP, Perl-ом и так далее. В итоге я уже знаком с тем, какие ощущения истинны, а какие возникают лишь с непривычки.

Цитата:
Поэтому появление шаблонов -- вряд ли эрозия. Скорее, требование жизни.

Я согласен, что это требование жизни. Именно это и есть эрозия.

Цитата:
Я уже пытался обратить Ваше внимание на то, что шаблоны новее ОО языков, добавляются в них после создания (за исключением C#). Рискну высказать идею -- появяться способы потребовать в шаблоне реализацию классом-параметром необходимого интерфейса, или набора интерфейсов.

Беглый взгляд на Вашу ссылку про generics-ы показал, что в джаве так и есть. Там в угловых скобках написано T implemets ...

Цитата:
4) Ваша концепция базового класса -- "самый родной член" -- несколько неортодоксальна, по меньшей мере, не общепринята.

Ну в Си++ же прослеживается, что память базового класса расположена в начале памяти дочернего. То есть, так же, как и у члена. Единственная разница, что обращаться к членам члена нужно с префиксом "имя_члена.".

Цитата:
Одно время в плохих книжках было модно вводить класс Точка с методом переместить(), а затем из него выводить классы Круг, Квадрат -- в которых эта точка служит центром. На сегодняшний день самой популярной является концепция "разновидности"

Это понятно. Но программно базовый класс просто физически содержится в дечернем, как и член.

Цитата:
5) Что же непонятно с разницей передачи класса и объекта класса?

Я этого не путал. Видимо, просто, неудачно выразился.

Рассмотрим процесс написания наследника. В этом процессе наследник ПОЛУЧАЕТ базовый класс, а не его объект, Вы согласны?

 Профиль  
                  
 
 
Сообщение23.03.2006, 18:52 
Заслуженный участник
Аватара пользователя


17/10/05
3709
:evil:
Dims писал(а):
Цитата:
Я уже пытался обратить Ваше внимание на то, что шаблоны новее ОО языков, добавляются в них после создания (за исключением C#). Рискну высказать идею -- появяться способы потребовать в шаблоне реализацию классом-параметром необходимого интерфейса, или набора интерфейсов.

Беглый взгляд на Вашу ссылку про generics-ы показал, что в джаве так и есть. Там в угловых скобках написано T implemets ...

Боюсь, что не все так просто. Java пока позволяет. Хорошо бы требовать. Но Java -- недостаточно ОО. В частности, декларация класса не является интерфейсом с точки зрения языка. Отсюда -- дуализм extends / implements в generics (впрочем, это утверждение не всегда верно. Иногда действительно хочется работать с объектом определенного класса. Я даже готов придумать примеры). Другая проблема -- элементарные типы и вовсе не имеют интерфейсов. В результате -- полумеры.

Dims писал(а):
Цитата:
4) Ваша концепция базового класса -- "самый родной член" -- несколько неортодоксальна, по меньшей мере, не общепринята.

Ну в Си++ же прослеживается, что память базового класса расположена в начале памяти дочернего. То есть, так же, как и у члена. Единственная разница, что обращаться к членам члена нужно с префиксом "имя_члена.".

Вы смешиваете реализацию и описание языка. С точки зрения реализации, удобно размещать так, как Вы описываете. Я не уверен, что Стандарт (описание) языка Вам это гарантирует. С точки зрения ОО -- порядок размещения не существеннен.

Я сталкивался с экзотическими компьютерами и экзотическими компиляторами. Поверьте, это смешно и грустно, когда фирма, производящая объективно лучшее переносимое ПО, фактический монополист рынка, признает, что они не могут работать в данной среде, потому что заложились на нестандартные, но типичные свойства реализаций.

Dims писал(а):
Цитата:
Одно время в плохих книжках было модно вводить класс Точка с методом переместить(), а затем из него выводить классы Круг, Квадрат -- в которых эта точка служит центром. На сегодняшний день самой популярной является концепция "разновидности"

Это понятно. Но программно базовый класс просто физически содержится в дечернем, как и член.

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

Dims писал(а):
Цитата:
5) Что же непонятно с разницей передачи класса и объекта класса?

Я этого не путал. Видимо, просто, неудачно выразился.

Речь шла о необходимости шаблонов, и Вы заявили, что вместо шаблона достаточно передать экземпляр параметром (на что и получили возражение dikun).

Хорошо, давайте рассмотрим пример -- решение уравнения методом деления попоплам.
Код:
float find_root(float a, float b, double(*f)(float), float eps)
{
  float c = (a + b)/2;
 
  assert(f(a) < 0 && 0 < f(b));
  while ((b - a) > eps) {
    (f(c) < 0? a: b) = c;
    c = (a + b) /2;
  }
  return c;
}
(в примере много предположений, это пример на шаблоны, а не на приличное программирование -- я убрал многия и многия проверки из кода). Теперь вопрос -- как нам переписать этот алгоритм (без шаблонов), чтобы он работал для любых типов (как области определения, так и области значений функции f())? То есть, чтобы можно было применить как ко встроенным типам -- float, double, так и к пользовательским -- Rational, PrecisionFloat, ArchimedеanField? Я думаю, что Вы согласитесь, писать каждый раз этот код не след. Какое же ОО решение?

Кстати, а к какому классу Вы бы отнесли его в Java? NumericalComputations, с только статическими методами? И в чем высокий ОО смысл?

~~~

ОО богатая и выразительная концепция. Она очень облегчает разработку больших систем. Но панацея? -- позвольте. Машина Тьюринга тоже все выражает.

 Профиль  
                  
 
 
Сообщение23.03.2006, 21:12 
Заслуженный участник
Аватара пользователя


16/03/06
406
Moscow
незванный гость писал(а):
Теперь вопрос -- как нам переписать этот алгоритм (без шаблонов), чтобы он работал для любых типов (как области определения, так и области значений функции f())?


Примерно так:

Код:
interface GenericFloat {
   GenericFloat Sum(GenericFloat a);
   GenericFloat Divide(GenericFloat a) throws DivisionByZero;
   ...
}

interface SingleParameterFloatFunction ...

GenericFloat find_root(GenericFloat a, GenericFloat b, SingleParameterFloatFunction f, GenericFloat eps) {

   GenericFloat c = (a.Sum(b)).Divide(2);

   ...

}

class ArchimedeanField extends GenericFloat {
...
}

void main() {

   GenericFloat a = new ArchimedianField(...) ...
   ...

   GenericFloat res = find_root(a...);

}



Цитата:
То есть, чтобы можно было применить как ко встроенным типам -- float, double, так и к пользовательским -- Rational, PrecisionFloat, ArchimedеanField? Я думаю, что Вы согласитесь, писать каждый раз этот код не след. Какое же ОО решение?

Встроенные типы - не в счёт. Это отклонение.

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

Цитата:
Кстати, а к какому классу Вы бы отнесли его в Java? NumericalComputations, с только статическими методами? И в чем высокий ОО смысл?

Я бы отнёс его к классу SingleParameterFloatFunction. Или сделал class Equation extends SingleParameterFloatFunction, то есть, чтобы у функции (или у более широкого её понятия) был метод такой -- "найти корень".

Хотя это зависит от задачи. ООП подразумевает рассмотрение предметной области и выделения в ней объектов. Если бы я писал математическую библиотеку, то я выделил бы в ней такие объекты, как "функция", "отношение", "уравнение", "численный метод" и т.п.

Цитата:
ОО богатая и выразительна концепция. Она очень облегчает разработку больших систем. Но панацея?

Я не говорил, что это панацея. И даже не говорил, что это лучшее средство. Я просто говорю, что в ОО есть определённый вкус и Джава реализует его лучше, чем Си++.

 Профиль  
                  
 
 
Сообщение23.03.2006, 21:20 
Заслуженный участник
Аватара пользователя


16/03/06
406
Moscow
незванный гость писал(а):
Dims писал(а):
Цитата:
4) Ваша концепция базового класса -- "самый родной член" -- несколько неортодоксальна, по меньшей мере, не общепринята.

Ну в Си++ же прослеживается, что память базового класса расположена в начале памяти дочернего. То есть, так же, как и у члена. Единственная разница, что обращаться к членам члена нужно с префиксом "имя_члена.".

Вы смешиваете реализацию и описание языка.

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

Можно тоже самое объяснить и логически. Что такое член -- это свойство объекта. Ясно, что свойство не обязано быть простым (цвет, рост), но может быть и сложным (отпечатки пальцев). А что такое предок в наследнике? Это просто группа свойств, общая и для предка и для наследника. Но группу свойств можно рассматривать и как одно составное свойство. Так что предок -- это свойство наследника.

Пример. Пишем класс 3-вектора. Каждая координата, очевидно, становится членом. Но кроме векторов, которые являются тензорами первого ранга, есть ещё и тензоры нулевого ранга -- скаляры. Как написать класс скаляра? Можно написать его с единственным членом -- числом. А можно сделать его классом, производным по отношению к числу.

То есть, в ситуации, когда член один, ясно видно, что его можно сделать и предком.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 87 ]  На страницу Пред.  1, 2, 3, 4, 5, 6  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group