powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / ООП
25 сообщений из 47, страница 1 из 2
ООП
    #34209780
BrokenPot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имеется базовый класс BaseClass.

У базового класса имеется конструктор с одним параметром New(id as guid)

Возникла необходимость в создании класса-наследника DerivedClass

Однако выходит так, что у класса-наследника должен быть конструктор с тремя параметрами New(id as guid, idperiod as guid, idbranch as integer)
...
Рейтинг: 0 / 0
ООП
    #34209794
BrokenPot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не могу сообразить, как такое следует делать, не переписывая целиком весть конструктор.
...
Рейтинг: 0 / 0
ООП
    #34209902
BrokenPotИмеется базовый класс BaseClass.

У базового класса имеется конструктор с одним параметром New(id as guid)

Возникла необходимость в создании класса-наследника DerivedClass

Однако выходит так, что у класса-наследника должен быть конструктор с тремя параметрами New(id as guid, idperiod as guid, idbranch as integer)


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
 class  BaseClass {

  public  BaseClass(id as guid) {
   bla-bla-bla...
 }
}



 class  DerivedClass extend BaseClass {
  private  DerivedClass(id as guid) {
   bla-bla you can't use that, haha
 }
  public  DerivedClass(id as guid, idperiod as guid, idbranch as integer) {
   bla-bla-bla...
 }
}
...
Рейтинг: 0 / 0
ООП
    #34209994
BrokenPot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
То есть, нужно все-таки наново переписывать весь конструктор?
...
Рейтинг: 0 / 0
ООП
    #34210018
BrokenPotТо есть, нужно все-таки наново переписывать весь конструктор?
Бозе мой.
Ну напиши

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
 class  DerivedClass extend BaseClass {
  private  DerivedClass(id as guid) {
    super (id);
 }

  public  DerivedClass(id as guid, idperiod as guid, idbranch as integer) {
   bla-bla-bla...
 }
}
...
Рейтинг: 0 / 0
ООП
    #34210508
Фотография fixxer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
(меня всё равно забанят) BrokenPotТо есть, нужно все-таки наново переписывать весь конструктор?
Бозе мой.
Ну напиши

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
 class  DerivedClass extend BaseClass {
  private  DerivedClass(id as guid) {
    super (id);
 }

  public  DerivedClass(id as guid, idperiod as guid, idbranch as integer) {
   bla-bla-bla...
 }
}


тогда уж так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
 class  DerivedClass extend BaseClass {
 
  public  DerivedClass(id as guid, idperiod as guid, idbranch as integer) {
    super (id);
   bla-bla-bla...
 }
}
...
Рейтинг: 0 / 0
ООП
    #34210555
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BrokenPotНе могу сообразить, как такое следует делать, не переписывая целиком весть конструктор.
Вызывать (использовать) прежний из нового. Как это делать - см. описание используемого языка.
...
Рейтинг: 0 / 0
ООП
    #34210617
BrokenPot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Беда в том, что в конструкторе базового класса происходит добавление в некие коллекции неких элементов.

Это происходит с использованием параметра, передаваемого в конструктор базового класса.

В классе-наследнике также должно происходить добавление неких, но других, элементов, также с использованием, но уже трех, параметров, которые должны передаваться в конструктор класса-наследника.

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

Получается, что нужно весь конструктор переписывать по новой, но этого, во-первых, не хочется, во-вторых - переписывание представляется нарушением объектной модели, ведь конструктор класса-наследника почти ничем не должен отличаться от конструктора базового класса, только лишь в части добавления других элементов и передачи этим элементам своих дополнительных параметров.
...
Рейтинг: 0 / 0
ООП
    #34210858
BrokenPot
Получается, что нужно весь конструктор переписывать по новой, но этого, во-первых, не хочется, во-вторых - переписывание представляется нарушением объектной модели, ведь конструктор класса-наследника почти ничем не должен отличаться от конструктора базового класса, только лишь в части добавления других элементов и передачи этим элементам своих дополнительных параметров.
Я вам привел пример.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
class DerivedClass extend BaseClass {
 private DerivedClass(id as guid) {
   super(id);
 }

 public DerivedClass(id as guid, idperiod as guid, idbranch as integer) {
   bla-bla-bla...
 }
}

Обратите особое внимание на модификаторы видимости.
В объекте-наследнике доступ к конструктору с одним параметров в приинципе запрещен извне.
Что вы баламутите? :)
...
Рейтинг: 0 / 0
ООП
    #34210928
BrokenPot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я не баламутю.

А в тебе бла-бла-бла присутствует вызов конструктора базового класса?
...
Рейтинг: 0 / 0
ООП
    #34210932
BrokenPot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в теле
...
Рейтинг: 0 / 0
ООП
    #34211286
BrokenPot
А в теле бла-бла-бла присутствует вызов конструктора базового класса?
Хм...

Могу лишь посоветовать вынести BaseClass и ExtClass в отдельные пакеты (или как там они в твоем языке называются) - т.е. чтобы к конструктору BaseClass без параметров никто не имел доступа (кроме наследников BaseClass - т.е. ExtClass и других).

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
 public   class  xtest
{
     public  xtest()
    {
        BaseClass base =  new  BaseClass( 4 );
        ExtClass ext =  new  ExtClass( 2 , 5 , 3 );
    }
    
    
     public   static   void  main(String args[]) {
        xtest t =  new  xtest();
    }

}


 class  BaseClass
{
     protected  BaseClass() {
        // do nothing
    }
    
     public  BaseClass( int  a)
    {
        System.out.println("a = " + a);
    }
}


 class  ExtClass  extends  BaseClass
{
     public  ExtClass( int  a,  int  b,  int  c) 
    {
        System.out.println("a = " + a + ", b = " + b + ", c = " + c);
    }
}



Либо, как вариант

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
 public   class  xtest
{
     public  xtest()
    {
        BaseClass base =  new  BaseClass( 4 );
        ExtClass ext =  new  ExtClass( 2 , 5 , 3 );
    }
    
    
     public   static   void  main(String args[]) {
        xtest t =  new  xtest();
    }

}


 class  BaseClass
{
    
     public  BaseClass( int  a)
    {
         if  (a !=  0 ) {
            System.out.println("a = " + a);
        }
    }
}


 class  ExtClass  extends  BaseClass
{
     public  ExtClass( int  a,  int  b,  int  c) 
    {
         super ( 0 );
        System.out.println("a = " + a + ", b = " + b + ", c = " + c);
    }
}

...
Рейтинг: 0 / 0
ООП
    #34211640
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BrokenPotведь конструктор класса-наследника почти ничем не должен отличаться от конструктора базового класса, только лишь в части добавления других элементов и передачи этим элементам своих дополнительных параметров.
Осталось сделать единственный шаг, чтобы получить из этого ответ "как надо делать".

Вообще, отмечу, создание элементов коллекции в конструкторе коллекции и только там - малость странная постановка вопроса. Но тем не менее.....

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

Тут возникает вопрос, как передать параметры. Есть два метода. Первый - через локальные поля; конструктор наследника запоминает параметры, вызывает базовый, тот строит коллекцию, вызываемый при этом виртуальный метод читает поля. Второй - сделать объект "параметры инициализации" и передавать именно его.
...
Рейтинг: 0 / 0
ООП
    #34212039
BrokenPot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
О! Спасибо большое.

Рад получить содержательный и исчерпывающий ответ.

Особенно приятно, что он совпал с моими соображениями, которые появились, пока я ожидал ответа.
...
Рейтинг: 0 / 0
ООП
    #34213579
maXmo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
имхо, нужно делать через параметры инициализации, а то вызывать метод для ещё неинициализированного объекта – как-то не очень…
...
Рейтинг: 0 / 0
ООП
    #34213898
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maXmoимхо, нужно делать через параметры инициализации, а то вызывать метод для ещё неинициализированного объекта – как-то не очень…
Ничуть не более, нежели делать с "еще не инициализированным объектом" что-то другое.

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

Код: plaintext
1.
2.
3.
4.
 public  SomeClass  extends  BaseClass {
   public  SomeClass ( int  i) {
     super  ((i ==  1 ) ? "a" : "b");
  }
}

и

Код: plaintext
1.
2.
3.
4.
5.
 public  SomeClass  extends  BaseClass {
   public  SomeClass ( int  i) {
    String s = (i ==  1 ) ? "a" : "b";
     super  (s);
  }
}

Я понимаю, почему компилятор ругается на второй вариант, но полагаю такое поведение глупым.
...
Рейтинг: 0 / 0
ООП
    #34214017
maXmo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerПодозреваю, Вы отталкиваетесь от явы, то как сделана инициализация тампонятия не имею, как она там сделана. На практике это наверняка заработает, просто это как-то интуитивно нехорошо – вызывать какие-то левые методы до того, как конструктор отработает.
...
Рейтинг: 0 / 0
ООП
    #34214356
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maXmoпросто это как-то интуитивно нехорошо – вызывать какие-то левые методы до того, как конструктор отработает.
Левых методов в классе быть вообще не должно.

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

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

Можно вести речь о том, какие подпрограммы правильно либо неправильно вызывать из конструктора. Тут мне ява когда-то подкинула забавный сюрприз. Код был примерно следующим:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
 public  BaseClass {
   public  BaseClass() { ...; someVirtualMethod(); ...}
   public  someVirtualMethod(); { ... }
}

 public  DerivedClass {
   private  Vector someData =  null ;
   public  DerivedClass() {  super (); .... }
   public  someVirtualMethod() { ....  if  (someData ==  null ) someData =  new  Vector(); ... }
}

Прикол этого кода был в том, что в результате его выполнения сначала был вызван конструктор базового класса, он вызвал виртуальный метод и инициализацию someData, а только потом отработало присваивание someData = null. Особой логики я в таком поведении не вижу, имхо неудачная калька с C++ как раз там, где стоило чуть изменить модель. В Java5, если мне не изменяет память, как раз из-за подобных эффектов рубанули топором и компилятор стал ругаться на вполне разумный код, пришлось придумывать обходы.
...
Рейтинг: 0 / 0
ООП
    #34215521
maXmo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerлюбой фрагмент кода, если это нужно, может быть выделен в подпрограмму. Нарушение этого тезиса очевидно приводит к ситуации "подпрограмма не выделена там, где она нужна" и всем последствиям - дублированию кода, плохой сопровождаемости итп. Таким образом, если нужно выделить подпрограмму из тела конструктора - ее нужно выделять.согласен. Если нужно. Но тут явно была задача на написание конструктора в более общей форме.

softwarerСкажем, в примере выше - придумать функтор "создатель элементов коллекции" и передавать его в базовый конструктор. Формально это уже не собственный метод объекта, фактически - кривизна на пустом месте.если нужно создать объект почти произвольного типа, ответ один – фабрика. Если хочется ограничения видимости, фабрику можно сделать в виде класса, вложенного в DerivedClass из твоего примера, можно даже с модификатором private. Но тут это не понадобилось, т.к. чел хотел всё сделать в одном месте – в базовом конструкторе обобщённой формы… получилось сделать.
...
Рейтинг: 0 / 0
ООП
    #34215815
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot softwarerПодозреваю, Вы отталкиваетесь от явы, то как сделана инициализация там, меня, если честно, напрягает, по разным причинам. В частности, я уже приводил этот код:
...
Я понимаю, почему компилятор ругается на второй вариант, но полагаю такое поведение глупым.[/quot]

Ага, во всех грехах виновата java %)

з.ы.
Тоже самое сделано в языках .NET, потому что это правильно.
...
Рейтинг: 0 / 0
ООП
    #34217234
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maXmoсогласен. Если нужно. Но тут явно была задача на написание конструктора в более общей форме.
"Как оптимально решать данную конкретную задачу" можно обсуждать; пока кроме моего никаких предложений не прозвучало.

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

maXmoесли нужно создать объект почти произвольного типа, ответ один – фабрика.
Я не очень понимаю, что такое "объект почти произвольного типа", и во всяком случае задача "создать указанного наследника базового типа" - имхо к таковым не относится. И это одна из наиболее типичных задач в ООП.

Далее, у меня нет уверенности в том, что я понимаю, что Вы называете "фабрикой". Точнее, разные люди при мне определяли это понятие с существенными различиями. Если понимать фабрику как некий выделенный объект, то это очевидно не единственный ответ и очень далеко не факт, что лучший.

maXmoЕсли хочется ограничения видимости, фабрику можно сделать в виде класса, вложенного в DerivedClass
Вложенный класс инициализируется указателем на объемлющий, так что здесь мы имеем ту же самую проблему "еще не инициализированного объекта", которой Вы опасаетесь.

В целом у меня есть ощущение, что Вы советуете как раз то, что я склонен считать нагромождением "сложностей" на пустом месте.
...
Рейтинг: 0 / 0
ООП
    #34217244
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NotGonnaGetUsАга, во всех грехах виновата java %)
Прошу прощения, но по-моему у Вас mania grandioso.
...
Рейтинг: 0 / 0
ООП
    #34218218
maXmo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerНо здесь я сосредоточился на более узкой теме, вызове подпрограммы из конструктора как идее. Я так понимаю, мы пришли к согласию в том, что это может быть уместно.ну если ограничиться более узкой темой softwarerСкажем, в примере выше - придумать функтор "создатель элементов коллекции" и передавать его в базовый конструктор. Формально это уже не собственный метод объектая же предлагаю этот несобственный метод объекта выделить в другой класс, в котором он будет собственный и в котором он будет вызываться на уже сконструированном объекте.

softwarerЯ не очень понимаю, что такое "объект почти произвольного типа", и во всяком случае задача "создать указанного наследника базового типа" - имхо к таковым не относится. И это одна из наиболее типичных задач в ООП.под фабрикой я понимаю объект, создающий наследников базового класса. Создавать же указанных наследников можно просто оператором new, нет?

softwarerЕсли понимать фабрику как некий выделенный объект, то это очевидно не единственный ответ и очень далеко не факт, что лучший.ну… выделяешь ты эту логику в отдельный класс или не выделяешь, в любом случае роль фабрики выполняет тот класс, в котором этот метод содержится. Почему бы не выделить эту логику в отдельный класс? Разве это не логично? Мне это видится логичным; это распространённый метод, к тому же исчезнут всякие сюрпризы с конструкторами.

softwarerВложенный класс инициализируется указателем на объемлющийвовсе не обязательно.

softwarerВ целом у меня есть ощущение, что Вы советуете как раз то, что я склонен считать нагромождением "сложностей" на пустом месте.мне видится, что место совсем не пустое. Либо пишешь метод, который не меняет состояний окружающих объектов (и не зависит от них), либо одно их двух.
...
Рейтинг: 0 / 0
ООП
    #34218497
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maXmo softwarerСкажем, в примере выше - придумать функтор "создатель элементов коллекции" и передавать его в базовый конструктор. Формально это уже не собственный метод объектая же предлагаю этот несобственный метод объекта выделить в другой класс,
Хм. "Функтор" - это и есть "другой класс".

maXmoпод фабрикой я понимаю объект, создающий наследников базового класса. Создавать же указанных наследников можно просто оператором new, нет?
Оператором new можно создавать статически указанных наследников. Если не ошибаюсь,

Код: plaintext
1.
 Class  c = some.getClass();
Object o =  new  c();

в яве не пройдет, да и в C++ тоже.

maXmoв любом случае роль фабрики выполняет тот класс, в котором этот метод содержится. Почему бы не выделить эту логику в отдельный класс? Разве это не логично? Мне это видится логичным; это распространённый метод, к тому же исчезнут всякие сюрпризы с конструкторами.
То есть Вы понимаете фабрику примерно как я ожидал.

Описанное выделение - совершенно не факт, что логично. По общему принципу Оккама, наоборот, нужно доказывать, что оно в данном конкретном случае дает преимущества. Насчет распространенности метода.... скажем так, он распространен только потому, что закрывает один из концептуальных недостатков C++, который там никак иначе не решишь (разве что в последних версиях).

maXmo softwarerВложенный класс инициализируется указателем на объемлющийвовсе не обязательно.
Будем считать, Вам виднее. Для меня это новость.

maXmoмне видится, что место совсем не пустое. Либо пишешь метод, который не меняет состояний окружающих объектов (и не зависит от них), либо одно их двух.
Хм. Давайте так: я сейчас не хочу спорить по этому поводу. Предложите топикстартеру свое решение, пусть делает как ему больше понравится.
...
Рейтинг: 0 / 0
ООП
    #34218724
maXmo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerПо общему принципу Оккама, наоборот, нужно доказывать, что оно в данном конкретном случае дает преимущества.то есть если, скажем, мы будем писать приложение для накачки мячей, мы в нём можем мяч и насос объединить в один класс, потому что мы можем так сделать?

softwarerБудем считать, Вам виднее. Для меня это новость.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
class DerivedClass: BaseClass
{
 class StuffFactory: IStuffFactory
 {
  public object GiveMeMyStuff()
  {
   return Random.Next(); //но вообще тут может любой объект создаться
  }
 }
 public DerivedClass(): base(new StuffFactory()) //BaseClass(IStuffFactory)
 {
 }
}

softwarerПредложите топикстартеру свое решение, пусть делает как ему больше понравится.да он уже удовлетворён.
...
Рейтинг: 0 / 0
25 сообщений из 47, страница 1 из 2
Форумы / Программирование [игнор отключен] [закрыт для гостей] / ООП
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]