Подтвердить что ты не робот

Параметры и наследование конструктора

Новый для ООП, и я смущен тем, как конструкторы производного класса работают при наследовании от базового класса в С#.

Сначала базовый класс:

class BaseClass
{
    private string BaseOutput = null;

    public BaseClass(string BaseString)
    {
        BaseOutput = BaseString;
    }

    public virtual void PrintLine()
    {
        Console.WriteLine(BaseOutput);
    }
}

Вот производный класс:

class SubClass : BaseClass
{
    private string SubOutput = null;

    public SubClass(string BaseString, string SubString) : base(BaseString)
    {
        SubOutput = SubString;
    }

    public override void PrintLine()
    {
        Console.WriteLine(SubOutput);
    }
}

Наконец, основная часть программы:

class Program
{
    static void Main(string[] args)
    {
        BaseClass theBase = new BaseClass("Text for BaseClass");
        SubClass theSub = new SubClass("2nd param", "Text for SubClass");

        theBase.PrintLine();
        theSub.PrintLine();

        Console.ReadKey();
    }
}

Я не понимаю, почему при вызове конструктора для производного класса я должен также передать параметр, который нужен базовому классу. Разве поле BaseOutput в производном классе не должно оставаться равным null, если ему не присвоено значение? Почему не может быть что-то вроде этой работы:

public SubClass(string SubString) : base(BaseString)

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

public SubClass(string AnotherString, string SubString) : base(BaseString)

Наконец, когда вы сделаете это правильно и введите это...

public SubClass(string BaseString, string SubString) : base(BaseString)

... Каков первый параметр в используемом конструкторе SubClass? Он не назначается или не используется ни в каких методах для моего производного класса. Почему я вообще должен его там даже поставить?

4b9b3361

Ответ 1

Что вы не можете сделать:

public SubClass(string SubString) : base(BaseString)

Что было бы BaseString?

Вы можете сделать:

public SubClass(string SubString) : base("SomeFixedString")

или

public SubClass(string SubString) : base(SubString)

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

Что касается сохранения одного и того же имени, вы этого не делаете. Вы можете сделать:

public SubClass(string AnotherString, string SubString) : base(AnotherString)

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

Ответ 2

Если вы хотите инициализировать BaseString значением по умолчанию, передайте это значение конструктору базового класса (таким образом, вам не нужно передавать этот параметр в конструктор производного класса)

public SubClass(string SubString) : base(null)

Или определить конструктор без параметров в базовом классе.

Также о присвоении параметров - не имеет значения, какое имя имеет параметр, который вы передаете производному конструктору. Единственное, что имеет значение, это значение, которое вы передаете базовому конструктору.

public SubClass(string AnotherString, string SubString) : base(AnotherString)

Ответ 3

public SubClass(string BaseString, string SubString) : base(BaseString)

Этот конструктор в производном классе говорит, что когда вы получаете два аргумента BaseString и SubString, вызовите конструктор базового класса с BaseString.

Таким образом, делая

public SubClass(string a, string b) : base(BaseString)

не работает, потому что вы говорите ему, чтобы вызвать конструктор базового класса с BaseString, но нет аргумента, называемого BaseString.

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

public BaseClass() { }

Ответ 4

Если вы хотите предоставить возможность производному классу NOT установить BaseString, вам необходимо предоставить конструктор по умолчанию в базовом классе следующим образом:

public BaseClass()
{

}

Теперь в производном классе вы можете вызвать конструктор без аргументов в базовом классе следующим образом:

public SubClass(string AnotherString)
     : base()
{
    // base() => explicit call to default construct in the base class.
    // Do something else
}

Это обеспечивает хорошую практику разработки программного обеспечения: если вы хотите предоставить возможность не устанавливать строку базового класса, тогда сделайте это в базовом классе. Другие "хаки", подобные передаче null в качестве аргумента базовому конструктору, служат только для того, чтобы возиться с внутренними элементами базового класса способами, которые не должны выполняться из подклассов.