2014-12-26 2 views
2

private в Java обеспечивает инкапсуляцию уровня класса. Возможно ли инкапсулировать объект? Или это бесполезно?Инкапсулировать объекты в Java?

Например, если мы определим класс как,

public class Person { 

     private String ssn; 

     private ArrayList<Person> friends = new ArrayList<Person>(); 

     public void addFriend (Person stranger) { 

      friends.add(stranger); 

      // but here I have access to her ssn 
      System.out.println(stranger.ssn); 
     } 
} 

Как бы оградить доступ к ssn из stranger в методе addFriend() выше, когда требуется, чтобы объект по stranger «s передается ей в качестве параметра?

+0

Вы понимаете, что находитесь в классе «Личность»? У вас также есть доступ к 'stranger.ID'; 'чужой' - это« Человек ». –

+2

@ElliottFrisch Я думаю, что он это делает, и это его вопрос.Ну, если это так: нет, нет способа скрыть поле класса для других экземпляров того же класса – Dici

+0

@ElliottFrisch Да, как указал Дичи. –

ответ

2

В Java нет модификатора частного доступа «экземпляр», т.е. где вы можете ограничить доступ только полями/методами экземпляра .

И, возможно, вам это не понадобится. Вы находитесь в своем классе Person. Вы разработчик. Что вам нужно скрывать от себя?

+1

Есть ли языки, которые занимаются? –

+1

@Alex [Scala например.] (Http://www.tutorialspoint.com/scala/scala_access_modifiers.htm) –

3

private означает, что вы имеете доступ к этому члену от этого класса, а не только например.

Доступ только ssn изнутри Person, а не из любого другого типа. Вы не можете обойти это, чтобы ограничить это только этим экземпляром.

2

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

public interface Person { 
    int getID(); 
} 

public class PersonWithSsn implements Person { 
     private int ID; 
     private String ssn; 

     private ArrayList<Integer> friends = new ArrayList<Integer>(); 

     public int getID() { 
      return ID; 
     } 
     public void addFriend (Person stranger) { 
      friends.add(stranger.getID()); 
      // You no longer have access to ssn here 
      //System.out.println(stranger.ssn); 
     } 
} 
+0

Это немного бессмысленно. Если 'Stranger' является' PersonWithSsn', все, что вам нужно сделать, это отбросить, а затем получить доступ к 'ssn' как обычно. –

+1

@pbabcdefp По той же логике любой другой способ защиты SSN от доступа будет бесполезен, поскольку существуют API-интерфейсы отображения. Конечно, на Java вы можете добраться до вещей, которые вы не должны видеть. Однако это не главное. Что происходит с актерским составом, когда кто-то проходит другую реализацию «Личности» - это совсем другая история. – dasblinkenlight

+0

Я должен согласиться, что это довольно неприятный хак. Да, почти все возможно через отражение, но кастинг - это не отражение; этот код по-прежнему «неправильный» –

3

Идея инкапсуляции не то же самое, идея безопасности данных.

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

По этой причине он реализован на уровне класса. Если вы программист, вы, как правило, должны быть в состоянии доверять себе или членам вашей команды. Здесь есть несколько уровней доверия, но опять же, мы говорим о том, чтобы доверять им, чтобы уважать контракт класса.

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

1

Вы могли бы пройти этот инкапсулируя ваши определения отдельно, затем передавая правильное определение метода:

class Person { 
    private HiddenDefinitions hiddenDef; 
    private PublicDefinitions publicDef; 

    public void addFriend(PublicDefinitions def) { 

    } 
} 

class PublicDefinitions { 
    private String name; 
    private int id; 

    public int getId() { 
      return id; 
    } 

    public String getName() { 
      return name; 
    } 
} 

class HiddenDefinitions { 
    private String ssn; 

    private String getSSN() { 
      return ssn; 
    } 

    public void setSSN(String ssn) { 
      this.ssn = ssn; 
    } 
} 

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

Смежные вопросы