Вопрос про конструкторы
От: Juiceek Украина  
Дата: 04.02.08 13:53
Оценка:
Почему не наследуются конструкторы?
Re: Вопрос про конструкторы
От: _Morpheus_  
Дата: 04.02.08 14:14
Оценка: :)
Здравствуйте, Juiceek, Вы писали:

J>Почему не наследуются конструкторы?


кто вам такое сказал?
... << RSDN@Home 1.2.0 alpha rev. 676>>
Re[2]: Вопрос про конструкторы
От: Lloyd Россия  
Дата: 04.02.08 14:20
Оценка: +1
Здравствуйте, _Morpheus_, Вы писали:

J>>Почему не наследуются конструкторы?


_M_>кто вам такое сказал?


А неушто наследуются?
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re: Вопрос про конструкторы
От: nikov США http://www.linkedin.com/in/nikov
Дата: 04.02.08 14:21
Оценка:
Здравствуйте, Juiceek, Вы писали:

J>Почему не наследуются конструкторы?


Потому что так предписано стандартом.

10.3.3 Inheritance
A class inherits the members of its direct base class type. Inheritance means that a class implicitly contains all members of its direct base class type, except for the instance constructors, destructors and static constructors of the base class.

Re[2]: Вопрос про конструкторы
От: Juiceek Украина  
Дата: 04.02.08 14:24
Оценка:
Здравствуйте, nikov, Вы писали:

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


J>>Почему не наследуются конструкторы?


N>Потому что так предписано стандартом.


N>

N>10.3.3 Inheritance
N>A class inherits the members of its direct base class type. Inheritance means that a class implicitly contains all members of its direct base class type, except for the instance constructors, destructors and static constructors of the base class.


Да, но есть же все-таки определенная логика в этом?
Я вот все думаю и никак не могу придумать, что бы могло помешать этому.
Re[3]: Вопрос про конструкторы
От: _FRED_ Черногория
Дата: 04.02.08 14:36
Оценка: 1 (1)
Здравствуйте, Juiceek, Вы писали:

J>Да, но есть же все-таки определенная логика в этом?

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

Есть. ИМХО, польза така: наследуемые конструкторы могут помочь только в случае, когда в наследниках не требуется "переопределять" (дополнять, добавлять какую-то логику) унаследованные конструкторы, что встречается катострафически редко, например, в собственных исключениях:
    [Serializable]
    public class MyException : Exception
    {
      public MyException() { }
      public MyException(string message) : base(message) { }
      public MyException(string message, Exception inner) : base(message, inner) { }
      protected MyException(SerializationInfo info, StreamingContext context) : base(info, context) { }
    }

В большенстве же случаях наследники добавляют к базовому классу члены, которые непло хо бы инициализировать какими-то значениями в конструкторе => конструкторы по-любому придётся "переопределять". Так же очень часто (по моим наблюдениям) в наследниках не требуются многие конструкторы предков => нужен был бы синтаксис явного "скрытия" базовых конструкторов или же изменения им области видимости. Тогда бы кто-то потребовал бы такой же "фенечки" и для методов, что выглядело бы глупо.

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

Подобной функциональности не сложно добиться (если её ещё нет) в Nemerle, например.
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Вопрос про конструкторы
От: nikov США http://www.linkedin.com/in/nikov
Дата: 04.02.08 14:41
Оценка: 5 (2) +2
Здравствуйте, Juiceek, Вы писали:

J>Да, но есть же все-таки определенная логика в этом?

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

Да, логика есть. Допустим есть цепочка наследования Derived : Base. Если бы конструкторы наследовались, то при вызове конструктора в виде Derived d = new Derived(...), overload resolution производился бы среди множества, содержащего как конструкторы, определенные в классе Derived, так и унаследованные им от класса Base. Если overload resolution выбирает конструктор класса Base, то что должно произойти? Можно представить два варианта:
1) Создается экземпляр класса Base и вызывается выбранный конструктор, определенный в классе Base. Это плохо, потому что полученный объект нельзя было бы присвоить переменной d, которая имеет тип Derived.
2) Создается экземпляр класса Derived и вызывается выбранный конструктор, определенный в классе Base. Это тоже не всегда хорошо, потому что этот конструктор ничего не знает о полях, добавленных в классе Derived, и они не будут инициализированы никакими осмысленными значениями, а просто будут иметь значения по умолчанию. Если это поведение является желательным, то в класс Derived нужно явно добавить конструктор с такой же сигнатурой, как конструктор класса Base, просто делегирующий вызов базовому классу с помощью constructor-initializer в виде : base(...).
Другими словами, назначение этого правила — снизить риск ошибок при вызове конструкторов, и сделать семантику более ясной.
Re[3]: Вопрос про конструкторы
От: _Morpheus_  
Дата: 04.02.08 14:51
Оценка: -2 :)
Здравствуйте, Lloyd, Вы писали:

_M_>>кто вам такое сказал?


L>А неушто наследуются?



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

using System;

public class A
{
    public A()
    {
        Console.WriteLine("A()");
    }
    public A(string str)
    {
        Console.WriteLine("A(string): {0}", str);
    }
}

public class B : A
{
    public B()
    {
        Console.WriteLine("B()");
    }
}

public class C : A
{
    public C() : base()
    {
        Console.WriteLine("C()");
    }
}

public class D : A
{
    public D(string str)
    {
        Console.WriteLine("D(string): {0}", str);
    }
}

public class E : A
{
    public E(string str) : base(str)
    {
        Console.WriteLine("E(string): {0}", str);
    }
}

class Program
{
    static void Main()
    {
        Console.WriteLine("==implicit no params==");
        B b = new B();
        Console.WriteLine("==explicit no params==");
        C c = new C();
        Console.WriteLine("==implicit with params==");
        D d = new D("paramStr");
        Console.WriteLine("==explicit with params==");
        E e = new E("paramStr");
    }
}


результат:
==implicit no params==
A()
B()
==explicit no params==
A()
C()
==implicit with params==
A()
D(string): paramStr
==explicit with params==
A(string): paramStr
E(string): paramStr


на мой взгляд, если бы не наследовался конструктор — были бы проблемы, т.к. если конструктор базового класса не отработает, то какието поля определенные в базовом классе как private могут быть не инициализированы, а из наследника они будут недоступны, что сделает наследника непригодным к использованию...
... << RSDN@Home 1.2.0 alpha rev. 676>>
Re: Вопрос про конструкторы
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 04.02.08 14:57
Оценка:
Здравствуйте, Juiceek, Вы писали:

J>Почему не наследуются конструкторы?

Не так давно обсуждалось: Почему конструкторы не наследуются
Автор: eiNtiel
Дата: 11.09.07
.
Re[4]: Вопрос про конструкторы
От: Lloyd Россия  
Дата: 04.02.08 14:59
Оценка:
Здравствуйте, _Morpheus_, Вы писали:

_M_>на мой взгляд, если бы не наследовался конструктор — были бы проблемы, т.к. если конструктор базового класса не отработает, то какието поля определенные в базовом классе как private могут быть не инициализированы, а из наследника они будут недоступны, что сделает наследника непригодным к использованию...


Значит так и запишем, что значит "наследуется" ты не знаешь.
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[5]: Вопрос про конструкторы
От: _Morpheus_  
Дата: 04.02.08 16:32
Оценка:
Здравствуйте, Lloyd, Вы писали:

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


_M_>>на мой взгляд, если бы не наследовался конструктор — были бы проблемы, т.к. если конструктор базового класса не отработает, то какието поля определенные в базовом классе как private могут быть не инициализированы, а из наследника они будут недоступны, что сделает наследника непригодным к использованию...


L>Значит так и запишем, что значит "наследуется" ты не знаешь.


ну так просвяти неграмотных
... << RSDN@Home 1.2.0 alpha rev. 676>>
Re[4]: Вопрос про конструкторы
От: nikov США http://www.linkedin.com/in/nikov
Дата: 04.02.08 16:51
Оценка:
Здравствуйте, _Morpheus_, Вы писали:

_M_>хм, если не наследуются, почему тогда в следующем примере, во всех случаях, отрабатывает конструктор базового класса?


_M_>на мой взгляд, если бы не наследовался конструктор — были бы проблемы, т.к. если конструктор базового класса не отработает, то какието поля определенные в базовом классе как private могут быть не инициализированы, а из наследника они будут недоступны, что сделает наследника непригодным к использованию...


Конструктор базового класса отрабатывает не потому, что он наследуется, а потому что он неявно вызывается из конструктора производного класса в силу следующего правила:

10.11.1 Constructor initializers
.......
If an instance constructor has no constructor initializer, a constructor initializer of the form base() is implicitly provided. Thus, an instance constructor declaration of the form

C(...) {...}
is exactly equivalent to
C(...): base() {...}

Re[6]: Вопрос про конструкторы
От: _FRED_ Черногория
Дата: 04.02.08 16:59
Оценка:
Здравствуйте, _Morpheus_, Вы писали:

_M_>ну так просвяти неграмотных



class A {
  public A() {}
  public A(string text) {}
  public A(int number) {}

  public void Method() {}
}

class B : A {
}

static class Program
{
  static void Main() {
    var b = new B(); // Это вызов не унаследованного, а созданного в B компилятором конструктора класса B
    b.Method(); // Это вызов унаследованного метода из класса A. 
                // Сигнатура этого метода, его наличие вообще, тип возвращаемого параметра и т.п. могут быть
                // изменены в классе A без переделки класса B, так как метод "принадлежит" A, а B его никак не использует.
                // Для сравнения: скрытие конструктора по-умолчанию у А потребует передки класса B.

    // Так как конструкторы не наследуются, то следующие вызовы не корректны
    var b2 = new B("test");
    var b3 = new B(4);
  }
}


Если бы конструкторы наследовались, то вызовы
    var b2 = new B("test");
    var b3 = new B(4);

были бы корректными. Так же добавление нового конструктора _к А_, например
public A(string text, int number) {}

позволило бы создавать экземпляры B (и других классов-наследников) вот так:
var b4 = new B("test", 8);

без изменения кода классов-наследников (в даннос случае без изменения кода класса В), по аналогии с добавлением нового открытого метода к классу А, который можно вызывать через всех наследников без изменения их кода.
Help will always be given at Hogwarts to those who ask for it.
Re[6]: Вопрос про конструкторы
От: Lloyd Россия  
Дата: 04.02.08 18:39
Оценка:
Здравствуйте, _Morpheus_, Вы писали:

L>>Значит так и запишем, что значит "наследуется" ты не знаешь.


_M_>ну так просвяти неграмотных


здесь
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[7]: Вопрос про конструкторы
От: _Morpheus_  
Дата: 05.02.08 09:16
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>>>Значит так и запишем, что значит "наследуется" ты не знаешь.


_M_>>ну так просвяти неграмотных


L>здесь


что такое наследование я знаю, по теме там ответа не нашел,
я спрашивал почему наследования конструктора нет, несмотря на то, что в следующем коде конструктор наследуется:
public class B : A
{
public B(string str) : base(str)
{
}
}

насколько я понял, речь шла несколько о другом — о том что если конструктор явно не наследуется, то в наследниках он не доступен...
... << RSDN@Home 1.2.0 alpha rev. 676>>
Re[8]: Вопрос про конструкторы
От: Lloyd Россия  
Дата: 05.02.08 09:21
Оценка:
Здравствуйте, _Morpheus_, Вы писали:

L>>здесь


_M_>что такое наследование я знаю, по теме там ответа не нашел,


Видимо не совсем.

_M_>я спрашивал почему наследования конструктора нет, несмотря на то, что в следующем коде конструктор наследуется:

_M_>public class B : A
_M_>{
_M_> public B(string str) : base(str)
_M_> {
_M_> }
_M_>}

Это никакое не наследование. Это тупо вызов.
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[9]: Вопрос про конструкторы
От: _Morpheus_  
Дата: 05.02.08 09:28
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Это никакое не наследование. Это тупо вызов.


а какое отношение к этому "тупо вызов" имеет синтаксис наследования?
... << RSDN@Home 1.2.0 alpha rev. 676>>
Re[10]: Вопрос про конструкторы
От: _Morpheus_  
Дата: 05.02.08 09:33
Оценка:
и раз это "тупо вызов", то почему его нельзя сделать так:
public class B : A
{
    public B(string str)
    {
        base(str);
    }
}


... << RSDN@Home 1.2.0 alpha rev. 676>>
Re[10]: Вопрос про конструкторы
От: Lloyd Россия  
Дата: 05.02.08 09:36
Оценка:
Здравствуйте, _Morpheus_, Вы писали:

L>>Это никакое не наследование. Это тупо вызов.


_M_>а какое отношение к этому "тупо вызов" имеет синтаксис наследования?


Какой еще "синтаксис наследования" ты о чем вообще?
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[11]: Вопрос про конструкторы
От: Lloyd Россия  
Дата: 05.02.08 09:36
Оценка: +1
Здравствуйте, _Morpheus_, Вы писали:

_M_>и раз это "тупо вызов", то почему его нельзя сделать так:

_M_>
_M_>public class B : A
_M_>{
_M_>    public B(string str)
_M_>    {
_M_>        base(str);
_M_>    }
_M_>}
_M_>


_M_>


Чтобы исключить вопросы почему нельзя перед base(str); тупо написать свой код.
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[11]: Вопрос про конструкторы
От: _Morpheus_  
Дата: 05.02.08 09:44
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>>>Это никакое не наследование. Это тупо вызов.


_M_>>а какое отношение к этому "тупо вызов" имеет синтаксис наследования?


L>Какой еще "синтаксис наследования" ты о чем вообще?


public B(string str) : base(str)
... << RSDN@Home 1.2.0 alpha rev. 676>>
Re[11]: Вопрос про конструкторы
От: _FRED_ Черногория
Дата: 05.02.08 09:44
Оценка: +1
Здравствуйте, _Morpheus_, Вы писали:

_M_>и раз это "тупо вызов", то почему его нельзя сделать так:

_M_>public class B : A
_M_>{
_M_>    public B(string str)
_M_>    {
_M_>        base(str);
_M_>    }
_M_>}

_M_>

В некоторых языках можно. И всё равно в этих языках нет наследования конструкторов, так что этот пример ничего не показывает.
Help will always be given at Hogwarts to those who ask for it.
Re[12]: Вопрос про конструкторы
От: Lloyd Россия  
Дата: 05.02.08 09:49
Оценка:
Здравствуйте, _Morpheus_, Вы писали:

L>>Какой еще "синтаксис наследования" ты о чем вообще?


_M_>
_M_>public B(string str) : base(str)
_M_>


Это вызов, а никакой не "синтаксис наследования".
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[13]: Вопрос про конструкторы
От: _Morpheus_  
Дата: 05.02.08 10:04
Оценка:
Здравствуйте, Lloyd, Вы писали:

_M_>>
_M_>>public B(string str) : base(str)
_M_>>


L>Это вызов, а никакой не "синтаксис наследования".



Хорошо, если это вызов, то почему я не могу сделать такой вызов?
public class A
{
    public A()
    {
    }
    
    public A(string str)
    {
    }

    protected void Method(string str)
    {
    }
}

public class B : A
{
    public B() : base.Method(str)
    {
    }
}
... << RSDN@Home 1.2.0 alpha rev. 676>>
Re[14]: Вопрос про конструкторы
От: Lloyd Россия  
Дата: 05.02.08 10:07
Оценка:
Здравствуйте, _Morpheus_, Вы писали:

L>>Это вызов, а никакой не "синтаксис наследования".


_M_>Хорошо, если это вызов, то почему я не могу сделать такой вызов?


Потому что Method — не коструктор.
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[15]: Вопрос про конструкторы
От: _Morpheus_  
Дата: 05.02.08 10:16
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Потому что Method — не коструктор.


такое объяснение было бы логично для термина "наследование", а в данном случае рассматривается термин "вызов".
раз это простой вызов, почему же нельзя вызвать метод?
... << RSDN@Home 1.2.0 alpha rev. 676>>
Re[16]: Вопрос про конструкторы
От: Lloyd Россия  
Дата: 05.02.08 10:20
Оценка: -1
Здравствуйте, _Morpheus_, Вы писали:

L>>Потому что Method — не коструктор.


_M_>такое объяснение было бы логично для термина "наследование", а в данном случае рассматривается термин "вызов".

_M_>раз это простой вызов, почему же нельзя вызвать метод?

Потому что нельзя.
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[17]: Вопрос про конструкторы
От: Lloyd Россия  
Дата: 05.02.08 10:28
Оценка:
Здравствуйте, Lloyd, Вы писали:

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


L>>>Потому что Method — не коструктор.


_M_>>такое объяснение было бы логично для термина "наследование", а в данном случае рассматривается термин "вызов".

_M_>>раз это простой вызов, почему же нельзя вызвать метод?

L>Потому что нельзя.


С чем же несогласен -VaS- ?
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[16]: Вопрос про конструкторы
От: _FRED_ Черногория
Дата: 05.02.08 10:37
Оценка:
Здравствуйте, _Morpheus_, Вы писали:

L>>Потому что Method — не коструктор.

_M_>такое объяснение было бы логично для термина "наследование", а в данном случае рассматривается термин "вызов".
_M_>раз это простой вызов, почему же нельзя вызвать метод?

А просто потому это 17.10.1 Constructor initializers и 10.10.1 Constructor initializers. Method Initializers сделаны не были, так так нужны редко, но при желании, думаю в Немерле или на IL реализовать не сложно если нужно. Но никакого отношения к наследованию конструкторов это по-прежнему не имеет
Help will always be given at Hogwarts to those who ask for it.
Re[17]: Вопрос про конструкторы
От: _Morpheus_  
Дата: 05.02.08 10:39
Оценка: :)
Здравствуйте, Lloyd, Вы писали:

_M_>>раз это простой вызов, почему же нельзя вызвать метод?


L>Потому что нельзя.


я почемуто считал что такой синтаксис можно называть наследованием конструктора (еще со времен c++), можно откуда вы подчерпнули информацию согласно которой это нельзя называть наследованием?
... << RSDN@Home 1.2.0 alpha rev. 676>>
Re[18]: Вопрос про конструкторы
От: Lloyd Россия  
Дата: 05.02.08 10:46
Оценка: +4
Здравствуйте, _Morpheus_, Вы писали:

_M_>>>раз это простой вызов, почему же нельзя вызвать метод?


L>>Потому что нельзя.


_M_>я почемуто считал что такой синтаксис можно называть наследованием конструктора (еще со времен c++),


"еще со времен c++" это не называется наследованием конструкторов.
Вот в Object Pascal-е, если мне не изменяет память что-то похожее на наследование конструкторов было.

_M_>можно откуда вы подчерпнули информацию согласно которой это нельзя называть наследованием?


Ну с такой логикой и прыщ на заднице можно назвать наследованием.
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[18]: Вопрос про конструкторы
От: Mab Россия http://shade.msu.ru/~mab
Дата: 05.02.08 12:49
Оценка: +1
Здравствуйте, _Morpheus_, Вы писали:

Спецификацию языка почитайте, там все понятно написано. Чего разводить балаган на пустом месте
Re[19]: Вопрос про конструкторы
От: Hacker_Delphi Россия  
Дата: 06.02.08 01:08
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>"еще со времен c++" это не называется наследованием конструкторов.

L>Вот в Object Pascal-е, если мне не изменяет память что-то похожее на наследование конструкторов было.
Не что-то похожее, а наследование конструкторов, насколько я помню.. причем именно такое, какого тебя (судя по всему) хочется...
единственное — при перекрытии надо обязательно предка вызывать, но как раз в случае наследования это и правильно
... << RSDN@Home 1.2.0 alpha rev. 789>>
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
Re[18]: Вопрос про конструкторы
От: Sinclair Россия https://github.com/evilguest/
Дата: 06.02.08 05:26
Оценка: +1
Здравствуйте, _Morpheus_, Вы писали:

_M_>я почемуто считал что такой синтаксис можно называть наследованием конструктора (еще со времен c++)

Ключевое слово — "почему-то". Такой синтаксис называется "вызов конструктора предка".
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.