Доступ к данным из различных экземпляров одного класса
В 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 39 40 41 42 43 44 45 46 |
public class Main { public static void main(String[] args) { Employee boss = new Employee("Boss", 1000); Employee vasya = new Employee("Vasya", 100); System.out.println( "Boss salary: " + boss.getSalary() ); System.out.println( "Vasya salary: " + vasya.getSalary() ); boolean vasyaIsBoss = vasya.equals( boss ); System.out.println( "Vasya is Boss: " + vasyaIsBoss ); System.out.println( "Boss salary: " + boss.getSalary() ); System.out.println( "Vasya salary: " + vasya.getSalary() ); } } class Employee { private int salary; private String name; Employee(String name, int salary) { this.name = name; this.salary = salary; } public int getSalary() { return salary; } @Override public boolean equals(Object emp) { Employee e = (Employee) emp; e.salary = 200; // Change Boss salary return name.equals(e.name); } } |
Результат выполнения:
1 2 3 4 5 6 7 |
Boss salary: 1000 Vasya salary: 100 Vasya is Boss: false Boss salary: 200 Vasya salary: 100 |
Как видите, объект Vasya, не только может читать приватные свойства объекта Boss, но так же может и менять их!!! Красота! 🙂
Мне на ум сразу пришла мысль, передать копию объекта, например так:
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 39 40 41 42 43 44 45 46 47 48 49 50 51 |
public class Main { public static void main(String[] args) { Employee boss = new Employee("Boss", 1000); Employee vasya = new Employee("Vasya", 100); System.out.println( "Boss salary: " + boss.getSalary() ); System.out.println( "Vasya salary: " + vasya.getSalary() ); boolean vasyaIsBoss = vasya.equals( boss.clone() ); System.out.println( "Vasya is Boss: " + vasyaIsBoss ); System.out.println( "Boss salary: " + boss.getSalary() ); System.out.println( "Vasya salary: " + vasya.getSalary() ); } } class Employee { private int salary; private String name; Employee(String name, int salary) { this.name = name; this.salary = salary; } public int getSalary() { return salary; } @Override public boolean equals(Object emp) { Employee e = (Employee) emp; e.salary = 200; // Change Boss salary return name.equals(e.name); } @Override public Employee clone() { return new Employee(name, salary); } } |
Результат работы теперь тот, который я бы хотел ожидать:
1 2 3 4 5 6 7 |
Boss salary: 1000 Vasya salary: 100 Vasya is Boss: false Boss salary: 1000 Vasya salary: 100 |
Еще один тест, аналогичный первому, только с экземплярами потомков этого класса:
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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
public class Main { public static void main(String[] args) { Employee boss = new Employee("Boss", 1000); Employee2 vasya = new Employee2("Vasya", 100); System.out.println( "Boss salary: " + boss.getSalary() ); System.out.println( "Vasya salary: " + vasya.getSalary() ); boolean vasyaIsBoss = vasya.equals( boss ); System.out.println( "Vasya is Boss: " + vasyaIsBoss ); System.out.println( "Boss salary: " + boss.getSalary() ); System.out.println( "Vasya salary: " + vasya.getSalary() ); } } class Employee { private int salary; private String name; Employee(String name, int salary) { this.name = name; this.salary = salary; } public int getSalary() { return salary; } @Override public boolean equals(Object emp) { Employee e = (Employee) emp; e.salary = 200; // Change Boss salary return name.equals(e.name); } } class Employee2 extends Employee { Employee2(String name, int salary) { super(name, salary); } } |
Результат, такой же как и в первом случае:
1 2 3 4 5 6 7 |
Boss salary: 1000 Vasya salary: 100 Vasya is Boss: false Boss salary: 200 Vasya salary: 100 |
и еще один пример:
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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
public class Main { public static void main(String[] args) { Employee boss = new Employee("Boss", 1000); Employee2 vasya = new Employee2("Vasya", 100); System.out.println( "Boss salary: " + boss.getSalary() ); System.out.println( "Vasya salary: " + vasya.getSalary() ); boolean vasyaIsBoss = vasya.equals( boss ); System.out.println( "Vasya is Boss: " + vasyaIsBoss ); System.out.println( "Boss salary: " + boss.getSalary() ); System.out.println( "Vasya salary: " + vasya.getSalary() ); } } class Employee { protected int salary; protected String name; Employee(String name, int salary) { this.name = name; this.salary = salary; } public int getSalary() { return salary; } @Override public boolean equals(Object emp) { Employee e = (Employee) emp; e.salary = 200; return name.equals(e.name); } @Override public Employee clone() { return new Employee(name, salary); } } class Employee2 extends Employee { Employee2(String name, int salary) { super(name, salary); } @Override public boolean equals(Object emp) { Employee e = (Employee) emp; e.salary = 300; return name.equals(e.name); } } |
Результат:
1 2 3 4 5 6 7 |
Boss salary: 1000 Vasya salary: 100 Vasya is Boss: false Boss salary: 300 Vasya salary: 100 |
Как видите, в этом случае мне пришлось поменять модификаторы доступа к переменным в родительском классе с private на protected, т.к. наследуемый класс не имеет доступа к private переменным родительского класса. А так же я переопределил equals.
Выводы:
- Нужно всегда помнить, что различные экземпляры одного класса имеют доступ ко всем методам и полям друг друга!
- Потомки имеют доступ ко всем методам родительского класса, если метод наследуется из родителя!
- Потомки не имеют доступ к приватным методам родительского класса, при доступе к ним из класса наследника!
- В случае если нужно передать объект и его надо защитить, то нужно передавать его копию!
Author: | Tags: /
| Rating:
2 comments.
Write a comment