Где инкапсуляция? - PullRequest
       39

Где инкапсуляция?

5 голосов
/ 16 сентября 2010

Я новый программист, поэтому, пожалуйста, извините за глупость этого вопроса, как следующий код инкапсулирует частные данные?-

public class SomeClass
{
    private int age;

    public int Age
    {
        get { return age; }
        set { age = value; }
    }

    public SomeClass(int age)
    {
        this.age = age;
    }
}

Я имею в виду, без логики ограничения или логики фильтрации в свойствах, чем вышеупомянутый код отличается от следующего -

public class SomeClass
{
    public int age;

    public SomeClass(int age)
    {
        this.age = age;
    }
}

Является ли первый код, предоставляющий любойинкапсуляция вообще?

Ответы [ 6 ]

8 голосов
/ 16 сентября 2010

Он обеспечивает один фрагмент инкапсуляции: он говорит: «Есть свойство Age, которое вы можете получить и установить, но я не буду рассказывать вам, как я его реализую».

Это не очень сильная инкапсуляция, но делает отделением деталей реализации от общедоступного API.Совершенно не меняя общедоступный API, вы можете начать хранить возраст где-то еще - в двух полях short, где-то в службе, как часть поля long или чего-либо еще.Вы можете добавить логирование в свойстве, чтобы увидеть, как часто оно используется.Вы можете добавить событие, которое запускается при изменении возраста (это изменение API, но не нарушает существующих абонентов).

РЕДАКТИРОВАТЬ: Одна вещь, на которую следует обратить внимание: даже если это ничего не делает сейчас, изменение на make он делает что-то позднее, совместимо как с исходным кодом, так и с двоичным кодом.Изменение поля для использования в качестве свойства не обратно совместимо как в исходном, так и в двоичном виде.В большинстве случаев это будет совместимо с исходным кодом, но не двоично-совместимым.В некоторых случаях источник больше не будет собираться.В большем количестве зла (и надуманного, по общему признанию) будут построены обе версии, но с различными эффектами.

Также обратите внимание, что начиная с C # 3, вы можете объявить тривиальное свойство так же легко, как поле:*

У меня есть статья обо всем этом , которая предоставляет более подробную информацию.

2 голосов
/ 16 сентября 2010

Я имею в виду, без логики ограничения или логики фильтрации в свойствах, чем вышеописанная отличается от следующей

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

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

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

2 голосов
/ 16 сентября 2010

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

Но это возможно.Например, SomeClass может наложить ограничения на то, как изменяется свойство Age (например, не изменяя возраст на недопустимое значение, такое как -2 или 823).Кроме того, SomeClass не обязательно должен представлять возраст как int.Возраст может быть результатом вычисления (например, путем вычитания сегодняшней даты из даты рождения человека) или его можно сохранить в SomeClass как другой тип данных (скажем, байт, длинный или двойной).

1 голос
/ 16 сентября 2010

Инкапсулирует или переносит изменения в приватную переменную age.Закрытая переменная Age не может быть изменена внешними абонентами напрямую, только с помощью предоставленных методов public.Он настраивает интерфейс, поэтому будущие изменения на age не сломают абонентов.Преимущество для внешних абонентов в будущем, поэтому сейчас это трудно увидеть.

0 голосов
/ 10 октября 2013

Является ли первый код вообще инкапсуляцией?

НЕТ (по крайней мере, тот код, который вы написали).

2 фрагмента кода почтитак же.Первый не дает никакой полезной разницы по сравнению со вторым (поскольку код написан).

При использовании методов получения и установки вы можете ограничить доступ к закрытым переменным.Это может быть форма инкапсуляции.

т.е.

private int x

public int getInt(String password){
 if(password == 'RealPassword'){
   return x
  }
}
0 голосов
/ 16 сентября 2010

В вашем первом примере SomeClass.Age является свойством.Поле "Поддержка" является частным.Во втором примере SomeClass.age является открытым полем.Хотя во многих случаях может не быть разницы, выбор свойства над полем дает вам возможность изменить реализацию без изменения API или «формы» класса.Может быть, вы хотите что-то сделать (сохранить или уведомить) всякий раз, когда свойство изменяется - это невозможно сделать с полем.

...