геттеры и сеттеры для суперклассов?

По-прежнему ли стандартной практикой является предоставление геттеров и сеттеров в суперклассе, чтобы подклассы могли получить доступ к атрибутам суперкласса (другими словами, установить атрибуты как частные)? Или подклассы должны напрямую обращаться к атрибутам (объявляя атрибуты защищенными)?

Есть стандартное соглашение?


person user997112    schedule 22.02.2012    source источник
comment
На каком языке? В C # и Java есть разные доступные конструкции для отображения значений, которые могут повлиять на то, как вы это сделаете на любом языке.   -  person KeithS    schedule 22.02.2012
comment
Дубликат: stackoverflow.com/questions/2279662/   -  person Robert Harvey    schedule 22.02.2012
comment
и stackoverflow.com/questions/3525765   -  person Robert Harvey    schedule 22.02.2012


Ответы (6)


Это полностью зависит от того, чего вы хотите достичь.

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

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

Если вам нужна какая-то форма проверки, вам нужны геттеры и сеттеры. Это защищает суперкласс от непреднамеренного повреждения, даже если он унаследован.

person Robert Harvey    schedule 22.02.2012

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

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

person christophmccann    schedule 22.02.2012

Проверьте два верхних ответа на этот вопрос:

Являются ли геттеры и сеттеры плохим дизайном? Встречены противоречивые советы

Не лучший ответ на ваш вопрос, но вы, очевидно, озабочены написанием хорошего объектно-ориентированного кода, поэтому вам следует подумать о них.

person Bill K    schedule 22.02.2012

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

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

person biziclop    schedule 22.02.2012

Говоря о стороне C #, если у вас есть член данных (поле или свойство), который не является общедоступным, но полезен для дочерних классов и должен быть доступен как для чтения, так и для записи, то объявите этот член как защищенный.

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

//as of C# 3.0 this can also be an auto-property
private string myValue;
protected string MyValue 
{
   get{return myValue;} 
   private set{myValue = value;}
}

Это делает MyValue полностью скрытым от классов вне иерархии наследования и доступным только для чтения для подклассов; только суперкласс может устанавливать значение. Это было бы эквивалентно закрытому полю с защищенным методом получения и частным методом установки.

В общем, как разработчик суперкласса, вам решать, как подклассы должны иметь возможность использовать то, что вы предоставляете. Если вы делаете что-то защищенное, предполагайте, что подклассы будут делать все, что им позволяет «защищенный». И в C #, и в Java есть методы, с помощью которых вы можете независимо управлять видимостью доступа для чтения и записи.

person KeithS    schedule 22.02.2012

Кажется, что в C # стандартной практикой является использование свойств с аксессорами get / set. В упрощенном виде у вас будет:

public string Name { get; set; }

Но у вас может быть более тонкий контроль над уровнем доступа, например:

public string Name { get; protected set; }

Здесь вы публично предоставляете метод get, но оставляете метод set только производным классам.

Еще одно преимущество использования средств доступа вместо прямого доступа к элементу данных заключается в том, что вы можете установить точку останова на методе get / set и посмотреть, кто его выполнил.
Это, однако, невозможно с помощью трюка { get; set; }. Вам нужно будет написать всю развернутую форму собственности:

private string m_Name = string.Empty;
public string Name
{
    get { return m_Name; }  // Put a happy breakpoint here
    set { m_Name = value; } // or here.
}

Будет безопасно отразить ту же концепцию для Java.

person AVIDeveloper    schedule 22.02.2012