На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (495) « Первая ... 138 139 [140] 141 142 ...  494 495  ( Перейти к последнему сообщению )  
> Delphi vs C++ vs C# , ну и Java немножко, где-то ближе к старшему байту номеров страниц
    Цитата korvin @
    Цитата D_KEY @
    Прочитал. Ты мне про гипотетический пример(на который тут уже ответили, повторятся не буду), а я тебе про реальное программирование. Приведи пример полезности интерфейсов в языке со множественным наследованием и абстрактными классами.

    возможность единообразно работать с разными классами, не связанными отношением наследования.
    вот есть у тебя несколько классов, с разными предками, но с некоторыми методами с одинаковыми сигнатурами, как ты напишешь одну функцию для работы с ними?

    Функции, функции... Могу завести абстрактный класс и унаследовать от него нужные классы, могу просто сделать не функцию, а шаблон функции.
      Цитата D_KEY @
      Функции, функции... Могу завести абстрактный класс и унаследовать от него нужные классы, могу просто сделать не функцию, а шаблон функции.

      можно и гланды через задний проход удалять, да...

      Добавлено
      Цитата D_KEY @
      Функции, функции... Могу завести абстрактный класс и унаследовать от него нужные классы, могу просто сделать не функцию, а шаблон функции.

      про абстрактный клас как-то не понял, пример можно?
      вот есть у тебя
      ExpandedWrap disabled
        class A { foo(), bar(), ... }
        class B { foo(), bar(), ... }
        class C { foo(), bar(), ... }

      как будет выглядеть абстрактный класс?
        Цитата korvin @
        Цитата D_KEY @
        Функции, функции... Могу завести абстрактный класс и унаследовать от него нужные классы, могу просто сделать не функцию, а шаблон функции.

        можно и гланды через задний проход удалять, да...

        А в чем принципиальная разница? Интерфейсы, кстати, несколько искажают принцип ОО-декомпозиции, поскольку заставляют объявлять искуственные сущности, представляющие собой не какое-то абстрактное понятие, а просто набор нужных методов/действий. Что-то интересное на эту тему мне попадалось, возможно, что от того же Мейера...
        Сообщение отредактировано: D_KEY -
          Цитата korvin @
          да в общем-то почти такое же, как у одного из основателей:

          Что-то не вижу, как эти слова коррелируют с вашими несколько странными утверждениями...
          Цитата korvin @
          да, она ввела меня в заблуждение, зачем Вы запутываете код? =))

          Ну, я же не знал, что вы следует соглашениям .NET'а :)
          Цитата korvin @
          лол, интерфейсы для того и нужны, чтоб для совершенно разных классов, но реализующих один интерфейс можно было написать одну функцию

          Сколько менторского пафоса то :)
          Цитата korvin @
          и передавать в нее экземпляры классов без приведений, в этом суть интерфейсов

          При чём тут приведение типов? :)
          Вы, похоже, не понимаете, что в моём последнем примере класс B реализует интерфейс IA два раза: как наследник класса A и самостоятельно - как часть реализации IB. Частный же случай, когда эти две реализации должны совпадать, т.е. когда реализация IA как части IB должна делегироваться классу A, был показан два раза: Повстанець'ом и мной.
          Теперь же я хочу увидеть на Delphi/C# решение предложенной мной задачи. Будете дальше непонятки строить или таки приведёте код?
          Цитата korvin @
          множественное наследование тут не при чем. статический полиморфизм причем. точнее даже приведение типов

          Тут как раз множественное наследование...
            Цитата korvin @
            Цитата D_KEY @
            Функции, функции... Могу завести абстрактный класс и унаследовать от него нужные классы, могу просто сделать не функцию, а шаблон функции.

            про абстрактный клас как-то не понял, пример можно?
            вот есть у тебя
            ExpandedWrap disabled
              class A { foo(), bar(), ... }
              class B { foo(), bar(), ... }
              class C { foo(), bar(), ... }

            как будет выглядеть абстрактный класс?

            Что-то я не понял, как твой псевдокод соотносится с твоим примером про функцию.
            Что принимает функция? Вот и создаешь абстрактный класс для такой сушности. Какие-то классы ты можешь унаследовать от него, какие-то - нет, воспользовавшись такими паттернами, как "адаптер", "декоратор", "прокси" и др., в зависимости от потребностей.
              Цитата korvin @
              множественное наследование тут не при чем. статический полиморфизм причем. точнее даже приведение типов

              грубо говоря (точно проверить сейчас возможности нет) в Делфи это будет так:
              ExpandedWrap disabled
                type
                  A = class
                    procedure f;
                  end;
                 
                  B = class (A)
                    procedure f; override;
                    procedure g;
                  end;
                 
                procedure A.f;
                begin
                  WriteLn( 'A.f' );
                end;
                 
                procedure B.f;
                begin
                  WriteLn( 'B.f' );
                end;
                 
                procedure B.g;
                begin
                  WriteLn( 'B.g' );
                end;
                 
                 
                 
                procedure f1 (x : A);
                begin
                  x.f;
                end;
                 
                procedure f2 (x : B);
                begin
                  x.f;
                  x.g;
                end;
                 
                 
                 
                var x : B;
                 
                begin
                  x := B.Create;
                  f1( x as A );
                  f2( x );
                end;


              Добавлено
              Цитата D_KEY @
              Что-то я не понял, как твой псевдокод соотносится с твоим примером про функцию.
              Что принимает функция? Вот и создаешь абстрактный класс для такой сушности. Какие-то классы ты можешь унаследовать от него, какие-то - нет, воспользовавшись такими паттернами, как "адаптер", "декоратор", "прокси" и др., в зависимости от потребностей.

              функция принимает объект интерфейса I, такого, что
              ExpandedWrap disabled
                interface I { foo(), bar() }

              т.е.
              ExpandedWrap disabled
                function f (x : I) { ... }
                Цитата korvin @
                грубо говоря (точно проверить сейчас возможности нет) в Делфи это будет так:

                Дык не то ведь! Функции должны принимать интерфейсы, об их конкретных реализациях они ничего не знают.
                Ну, может, если так переделаю, станет понятнее
                ExpandedWrap disabled
                  #include <iostream>
                   
                  class IA
                  {
                  public:
                    virtual void f() = 0;
                  };
                   
                  class IB : public IA
                  {
                  public:
                    virtual void g() = 0;
                  };
                   
                  class A : public IA
                  {
                  public:
                    virtual void f() { std::cout << "A::f()" << std::endl; }
                  };
                   
                  class Base : public IB
                  {
                    void f() { IB_f(); }
                  public:
                    virtual void IB_f() = 0;
                  };
                   
                  class B : public A, public Base
                  {
                  public:
                    virtual void g() { std::cout << "B::g()" << std::endl; }
                    virtual void IB_f() { std::cout << "B::f()" << std::endl; }
                  };
                   
                  void f1(IA& iface)
                  {
                    iface.f();
                  }
                   
                  void f2(IB& iface)
                  {
                    iface.f();
                    iface.g();
                  }
                   
                  int main()
                  {
                    B b;
                   
                    f1(static_cast<A&>(b));
                    f1(static_cast<IB&>(b));
                    f2(b);
                   
                    return 0;
                  }

                ExpandedWrap disabled
                  A::f()
                  B::f()
                  B::f()
                  B::g()
                  Цитата korvin @
                  функция принимает объект интерфейса I, такого, что
                  ExpandedWrap disabled
                    interface I { foo(), bar() }

                  т.е.
                  ExpandedWrap disabled
                    function f (x : I) { ... }

                  То есть у сущности даже названия нет? Подтверждаешь мои слова насчет несоответствия принципам ОО-декомпозиции :tong:
                  Ну так в чем проблема-то?
                  Еще раз повторяю, что ты можешь просто написать шаблон фунции. Чем не устраивает?
                  Можешь создать абстрактный класс, вместо интерфейса и унаследовать от него нужные классы.
                  Можешь добавить ко второму способу автоматическое создание объекта-обертки.
                    Цитата D_KEY @
                    Что-то я не понял, как твой псевдокод соотносится с твоим примером про функцию.
                    Что принимает функция? Вот и создаешь абстрактный класс для такой сушности. Какие-то классы ты можешь унаследовать от него, какие-то - нет, воспользовавшись такими паттернами, как "адаптер", "декоратор", "прокси" и др., в зависимости от потребностей.

                    , ох, еще кучу кода городить для реализации паттернов? нет уж, увольте.

                    вот пример на Go (только там нет наследования, но просто считай, что A, B, C -- некие классы без общих предков):
                    ExpandedWrap disabled
                      type A struct {
                          // ...
                      }
                       
                      func (a A) foo() {
                          // ...
                      }
                       
                      func (a A) bar() {
                          // ...
                      }
                      //--------------
                       
                      type B struct {
                          // ...
                      }
                       
                      func (b B) foo() {
                          // ...
                      }
                       
                      func (b B) bar() {
                          // ...
                      }
                      //--------------
                       
                      type C struct {
                          // ...
                      }
                       
                      func (c C) foo() {
                          // ...
                      }
                       
                      func (c C) bar() {
                          // ...
                      }

                    тогда я делаю так:
                    ExpandedWrap disabled
                      type I interface {
                          foo()
                          bar()
                      }
                       
                      func f(x I) {
                          x.foo()
                          x.bar()
                      }

                    и все...

                    Добавлено
                    Цитата MyNameIsIgor @
                    Дык не то ведь! Функции должны принимать интерфейсы, об их конкретных реализациях они ничего не знают.
                    Ну, может, если так переделаю, станет понятнее

                    тю, да я просто забыл, что f1 и f2 у тебя классами IA и IB типизируются. ну так это опять же ничего не меняет, у тебя по сути просто перекрытие метода предка. ну добавлю я интерфейсы:
                    ExpandedWrap disabled
                      type
                        IA = interface
                          procedure f;
                        end;
                       
                        IB = interface (IA)
                          procedure g;
                        end;
                       
                        A = class (IA)
                          procedure f;
                        end;
                       
                        B = class (A, IB)
                          procedure f; override;
                          procedure g;
                        end;
                       
                      procedure A.f;
                      begin
                        WriteLn( 'A.f' );
                      end;
                       
                      procedure B.f;
                      begin
                        WriteLn( 'B.f' );
                      end;
                       
                      procedure B.g;
                      begin
                        WriteLn( 'B.g' );
                      end;
                       
                       
                       
                      procedure f1 (x : IA);
                      begin
                        x.f;
                      end;
                       
                      procedure f2 (x : IB);
                      begin
                        x.f;
                        x.g;
                      end;
                       
                       
                       
                      var x : B;
                       
                      begin
                        x := B.Create;
                        f1( x as A );
                        f2( x );
                      end;

                    как-то так

                    Добавлено
                    Цитата D_KEY @
                    То есть у сущности даже названия нет? Подтверждаешь мои слова насчет несоответствия принципам ОО-декомпозиции :tong:

                    1. у какой сущности нет названия?
                    2. анонимные классы уже не в моде? а вот в SICP пишут, что создание сущности и ее именование -- совершенно ортогональные операции =)
                      Цитата korvin @
                      тю, да я просто забыл, что f1 и f2 у тебя классами IA и IB типизируются. ну так это опять же ничего не меняет, у тебя по сути просто перекрытие метода предка. ну добавлю я интерфейсы:

                      Ну, и теперь ещё в f1 запихать B, чтобы вывод с моим совпал :)
                      Сообщение отредактировано: MyNameIsIgor -
                        Цитата MyNameIsIgor @
                        Цитата korvin @
                        тю, да я просто забыл, что f1 и f2 у тебя классами IA и IB типизируются. ну так это опять же ничего не меняет, у тебя по сути просто перекрытие метода предка. ну добавлю я интерфейсы:

                        Ну, и теперь ещё в f1 запихать B, чтобы вывод с моим совпал :)

                        ExpandedWrap disabled
                            f1(x);


                        Добавлено
                        Цитата D_KEY @
                        1) Еще раз повторяю, что ты можешь просто написать шаблон фунции. Чем не устраивает?
                        2) Можешь создать абстрактный класс, вместо интерфейса и унаследовать от него нужные классы.
                        3) Можешь добавить ко второму способу автоматическое создание объекта-обертки.

                        1) и получаем в итоге то, что видели на картинке =) кстати шаблоны же на каждый тип, к которому применяются, создают отдельную функцию? вроде раньше по крайней мере было, что они генерировали кучу классов;
                        2) как будет выглядеть этот класс и какие классы я от него буду наследовать?
                        3) и как будет выглядеть описание класса этого объекта-обертки?
                          Цитата korvin @
                          , ох, еще кучу кода городить для реализации паттернов? нет уж, увольте.

                          Сразу видно понимающего в паттернах человека. Не надо их городить, если они тебе не нужны.

                          Цитата
                          вот пример на Go (только там нет наследования, но просто считай, что A, B, C -- некие классы без общих предков):
                          ExpandedWrap disabled
                            type A struct {
                                // ...
                            }
                             
                            func (a A) foo() {
                                // ...
                            }
                             
                            func (a A) bar() {
                                // ...
                            }
                            //--------------
                             
                            type B struct {
                                // ...
                            }
                             
                            func (b B) foo() {
                                // ...
                            }
                             
                            func (b B) bar() {
                                // ...
                            }
                            //--------------
                             
                            type C struct {
                                // ...
                            }
                             
                            func (c C) foo() {
                                // ...
                            }
                             
                            func (c C) bar() {
                                // ...
                            }

                          тогда я делаю так:
                          ExpandedWrap disabled
                            type I interface {
                                foo()
                                bar()
                            }
                             
                            func f(x I) {
                                x.foo()
                                x.bar()
                            }

                          и все...

                          Так ты ответишь, чем тебе не нравится:
                          ExpandedWrap disabled
                            template<typename T>
                            void f(T x)
                            {
                                x.foo();
                                x.bar();
                            }

                          ?

                          Цитата
                          Цитата D_KEY @
                          То есть у сущности даже названия нет? Подтверждаешь мои слова насчет несоответствия принципам ОО-декомпозиции :tong:

                          1. у какой сущности нет названия?
                          2. анонимные классы уже не в моде? а вот в SICP пишут, что создание сущности и ее именование -- совершенно ортогональные операции =)

                          1. У той, "тип" которой ты описываешь своим интерфейсом
                          2. Ты не понял о чем я :) Дело не в том, чтобы задать сущности явное имя, дело в создании лишней сущности тогда, когда она не нужна.
                            шаблоны тут как раз в некотором роде заменяют интерфейсы

                            Добавлено
                            Цитата D_KEY @
                            Сразу видно понимающего в паттернах человека. Не надо их городить, если они тебе не нужны.

                            прям откровение =) мне -- не нужны, ты же предлагал ими воспользоваться
                              Цитата korvin @
                              шаблоны тут как раз в некотором роде заменяют интерфейсы

                              Кто кого заменяет - это еще вопрос. Интерфейс явно вводит новый "тип" и требует, чтобы аргумент ему соответствовал. Не очень-то соответствует "утиной типизации" которая нам тут, фактически, нужна.
                              Шаблон же говрит, что тип может быть любым, но требуется, что вот такие-то операции можно осуществить с объектами этого типа.

                              Добавлено
                              Цитата korvin @
                              ты же предлагал ими воспользоваться

                              Когда потребуется :)
                                Цитата D_KEY @
                                Так ты ответишь, чем тебе не нравится:
                                ExpandedWrap disabled
                                  template<typename T>
                                  void f(T x)
                                  {
                                      x.foo();
                                      x.bar();
                                  }

                                ?

                                тем, что шаблон никак не может проверить, реализует ли переданный ему тип нужный интерфейс (методы foo и bar), потому и получаем ошибки уже после раскрытия шаблона в кучу кода. или таки может?
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (495) « Первая ... 138 139 [140] 141 142 ...  494 495


                                Рейтинг@Mail.ru
                                [ Script execution time: 0.2734 ]   [ 14 queries used ]   [ Generated: 31.07.26, 03:45 GMT ]