Доступ к данным из различных экземпляров одного класса

В 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: | Rating: / | Tags:
 
                    
                
2 comments.
Write a comment