]:->
102 / 96 / 19
Регистрация: 12.11.2013
Сообщений: 398
1

Нарушен принцип инкапсуляции

17.01.2014, 11:44. Показов 826. Ответов 5
Метки нет (Все метки)

Под спойлером ссылка на цитату из книги Хорстмана. Не могу до конца разобраться с этим...вроде объявили мы метод как private, но говорят, что "принцип инкапсуляции нарушен"...метода setHire в классе нет, но private поле все равно изменяется...почему такое возможно?

Кликните здесь для просмотра всего текста
Внимание! Будьте осторожны при создании методов доступа, возвращающих ссылки на из-
меняемый объект. Создавая класс Emloyee, мы нарушили это правило: метод getHirebay()
возвращает объект Date.

class Employee
{
public Date getHire(); , '
{
return hireDay;
}
private Date hireDay;
}

Это нарушает принцип инкапсуляции! Рассмотрим пример неверного кода:

Employee harry «....;
Date d - harry.getHireDayO;
double tenYearsInMilliSeconds - 10 * 365.25 * 24 * 60 * 60 * 1000; .. ,
d.setTime(d.getTime() - (long) tenYearsInMilliSeconds);
// Значение объекта изменено.

Причину ошибки трудно уловить. Обе ссылки d и harry .hireDay относятся к одному и тому
же объекту. Применение модифицирующего метода к объекту d автоматически из-
меняет состояние Объекта, содержащегося в классе Employee!
Чтобы вернуть ссылку на изменяемый объект, его нужно сначала клонировать. Клон — это точ-
ная копия объекта, расположенная в другом месте памяти. Детали клонирования рассмотре-
ны в главе 6. Ниже приведен исправленный код.

class Employee
{
public Date hetHireDayO
{
return (Date) hireDay.clone();
}

В качестве эмпирического правила: используйте метод clone () «если вам нужно скопировать
изменяемое поле данных.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.01.2014, 11:44
Ответы с готовыми решениями:

Изучение инкапсуляции и абстракции
Всем доброго вечера у меня очередная лабораторка. Завдання. Створити на мові Java клас, який...

Код с использованием Наследования,Инкапсуляции,Полиморфизма
Кому не сложно,напишите код с использованием Наследования,Инкапсуляции,Полиморфизма Самый простой...

нужна программа с использованием наследования, инкапсуляции, полиморфизма
СРОчНО!! нужна программа с использованием наследования, инкапсуляции, полиморфизма!! простая...

В чем заключается принцип инкапсуляции
Доброго времени суток, изучаю Си шарп по Шилдту,столкнулся с проблемой,абсолютного непонимания...

5
31 / 31 / 6
Регистрация: 11.07.2013
Сообщений: 241
17.01.2014, 12:07 2
Цитата Сообщение от dan41k Посмотреть сообщение
.вроде объявили мы метод как private
метод публичный, поле приватное. Но дело в том, что поле ссылочного типа
Цитата Сообщение от dan41k Посмотреть сообщение
d.setTime(d.getTime() - (long) tenYearsInMilliSeconds);
Тут кажется, что поменяли время только для обьекта d, но вместе с ним незаметно поменялось и время для Гарика. Дело в том, что переменная d указывает на тот же обьект, что и переменная hireDay(обе переменные ОДНОВРЕМЕННО указывают на один обьект в памяти) и изменяя обьект для одной ссылки, он поменяется и для другой.
Цитата Сообщение от dan41k Посмотреть сообщение
метода setHire в классе нет, но private поле все равно изменяется...почему такое возможно
сверху

Ну и собственно нужно клонировать.
0
]:->
102 / 96 / 19
Регистрация: 12.11.2013
Сообщений: 398
17.01.2014, 12:14  [ТС] 3
Цитата Сообщение от OxomHuK Посмотреть сообщение
метод публичный, поле приватное. Но дело в том, что поле ссылочного типа
да, ошибся. имел ввиду поле...

Цитата Сообщение от OxomHuK Посмотреть сообщение
Ну и собственно нужно клонировать.
а можно каким-то образом сделать так, чтобы методы класса не могли изменять переменную? И клон создается только для того, чтобы перехватить изменение поля?
0
942 / 686 / 229
Регистрация: 28.04.2013
Сообщений: 1,924
17.01.2014, 12:49 4
dan41k, Вот представьте что создаете объект класса.

Вы создали класс под именем Class в нем несколько полей.

Когда вы создаете объект класса.
Java
1
Class myClass =  new Class();
Вот эта строка резервирует область в памяти. (я предполагаю что это как минимум память под все поля, объявленные в класса + какие то технические байты (может быть сдвиг, адрес последнего байта области или что то еще) (Я особо не забивал пока себе этим голову, думаю если это важно Эксперты об этом расскажут =) )
и в переменную myClass записывается только адрес первого байта этой области. Это и есть ссылка.

если вы объявите:

Java
1
private myClass1;
то вы "защищаете" саму ссылку. т.е переменную в которой хранится адрес, а не саму область с данными.

Java
1
2
3
4
//грубый пример
private Class myClass1;
public Class myClass2;
myClass2 = myClass1; //вы myClass2 присвоили тот адрес в памяти, который хранится в переменной myClass1
myClass1 мы из другого класса не увидим, за то myClass2 легко, и следовательно с информацией которая хранится в области памяти на которую ссылаются эти оба объекта можно делать что угодно.
1
]:->
102 / 96 / 19
Регистрация: 12.11.2013
Сообщений: 398
17.01.2014, 12:59  [ТС] 5
Вроде разобрался. Спасибо
0
942 / 686 / 229
Регистрация: 28.04.2013
Сообщений: 1,924
17.01.2014, 13:32 6
На всякий случай еще дополню примерном
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class HelloWorld {
    public static void main(String[] args) {
        Addition addition = new Addition();
        
        int tmp = addition.add(2,2);
        //в переменную tmp записалась КОПИЯ ЗНАЧЕНИЯ переменной summ из класса Addition
        //Что бы мы не делали с переменной tmp значение summ не изменится.
    }
}
 
class Addition {
    public int add(int a, int b) {
        summ = a + b;
        return summ;
    }
    private int summ;
}
если бы будете возвращать объект то станет так:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class HelloWorld {
    public static void main(String[] args) {
        Addition addition = new Addition();
 
        INT tmp = addition.add(2,2);
        //В этом случае в переменной tmp будет записана КОПИЯ АДРЕСА области памяти, где хранятся
        //данные объекта сумм.
 
        //т.к как адреса одиниковые, то
        tmp.setS(16);
        //изменит значение и в объекте summ, хоть он и приватный
        Addition.getSumm();
    }
}
 
class Addition {
    public INT add(int a, int b) {
        summ.setS(a + b);
        return summ;
    }
    public static void getSumm()
    {
        System.out.println("Значение поля s объяетка summ = " + summ.getS());
    }
    private static INT summ = new INT();
}
 
class INT{
    int getS() {
        return s;
    }
 
    void setS(int s) {
        this.s = s;
    }
 
    private int s;
}
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.01.2014, 13:32

Продемонстрировать принцип иерархии, наследования классов и инкапсуляции данных
Продемонстрировать принцип иерархии, наследования классов и инкапсуляции данных.

Нарушен ли solid ?
Привет. Есть например сущности предметной области Нож и Складной Нож. Как вы думаете нужно...

Выгрзука в Excel из DataGridView. Нарушен порядок столбцов
Здравствуйте. Выгружаю данные из БД на DataGridView. Затем из DataGridView делаю экспорт в Excel....

Нарушен баланс мощности при выводе звука
Доброго времени суток всем ценителям открытого кода! Имеется Lucid, Creative SB Live! Value,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.