Вопрос про конструкторы
От: 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>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.