частный объект против частного класса

Существует ли понятие object-private в любом ООП-языке?? Я имею в виду более строгий, чем классический частный доступ?

Private (или class-private) ограничивает доступ к самому классу. Только методы, являющиеся частью одного и того же класса, могут получить доступ к закрытым членам.

object-private : ограничивает доступ к самому объекту. Только объекты методов, которые могут получить доступ к членам, и их невозможно будет написать:

public class Person {

private String secret;
public String othersSecret;

public void snoop(Person p) {
    othersSecret = p.secret; //will be prohibited by the compiler
}

ИЗМЕНИТЬ:

Если он существует, не могли бы вы привести несколько примеров... если нет, как вы думаете, интересно ли иметь такую ​​функцию?? и можно ли смоделировать это на других языках ООП??

РЕДАКТИРОВАТЬ 2: Спасибо, ребята, все ответы были очень поучительны...

Пока временное заключение:

Понятие частный экземпляр существует на 2 языках:

1 - Smalltalk после нескольких часов гугления :) Я нашел язык, лежащий в основе этой концепции !!

Состояние объекта всегда является частным для этого объекта. Другие объекты могут запрашивать или изменять это состояние, только отправляя соответствующие запросы (сообщения) объекту.

2 — Руби благодаря Логану:

Один человек резюмировал различия, сказав, что в C++ «частный» означает «частный для этого class», в то время как в Ruby это означает «приватный для этого экземпляра». Что это означает, в C++ из кода в классе A вы можете получить доступ к любому частному методу для любого другого объекта типа A. В Ruby вы не можете: вы можете получить доступ к закрытым методам только для вашего экземпляра объекта, а не для любого другого экземпляр объекта (класса A).


person wj.    schedule 28.12.2009    source источник
comment
Я просто отредактировал свой пост, чтобы быть более понятным... я спрашиваю о теории... на любом языке ООП...   -  person wj.    schedule 28.12.2009
comment
одна из вещей, которые заставили меня пойти "да?" над С#, AFAIK поддерживает только частный класс.   -  person Johannes Rudolph    schedule 28.12.2009
comment
@Johannes: 'class-private' - это обычный способ, которым языки ООП (C #, java ...) обрабатывают инкапсуляцию ... до сих пор я вижу только Ruby (спасибо Логану), который разрешает 'object-private' ...   -  person wj.    schedule 28.12.2009
comment
@wj: не стесняйтесь использовать Smalltalk в своем собственном ответе. meta.stackexchange.com/questions/12513/   -  person outis    schedule 28.12.2009
comment
@outis: спасибо за подсказку! я не знаю, было ли возможно/рекомендовано отвечать на наши собственные вопросы ... сделаю это в следующий раз ;)   -  person wj.    schedule 28.12.2009
comment
Если у вас есть Smalltalk, вы также можете добавить Self и Strongtalk и Newspeak и все остальные его потомки.   -  person akuhn    schedule 29.12.2009


Ответы (7)


В ruby ​​приватное поведение для каждого объекта является единственным приватным (вы должны использовать protected, чтобы получить приватное поведение класса).

Например. foo.rb:

 class A
    private
    def a=(x)
            @a=x
    end
    public
    def a
            @a
    end

    def b(c)
            c.a = 2
    end
 end

 a1 = A.new
 a2 = A.new
 a1.b(a2)

Запустив его, мы получим

 foo.rb:12:in `b': private method `a=' called for #<A:0xb7c9b6e0> (NoMethodError)
    from foo.rb:18

Конечно, есть способы обойти это, но они почти всегда есть.

person Logan Capaldo    schedule 28.12.2009
comment
Очень интересный пример!! Мне интересно, есть ли другие языки, поддерживающие это... и почему это не является стандартом для других языков ООП... - person wj.; 28.12.2009
comment
Есть все виды объектно-ориентированных функций, которые появляются только на некоторых языках. См. CLOS для некоторых интересных (например, мультиметодов, метаклассов и комбинации методов (например, :before, :after и :around), последние два из которых предвосхищают аспектно-ориентированное программирование). - person outis; 28.12.2009
comment
@outis: что мне больше всего нравится в CLOS, так это линеаризация вызовов при множественном наследовании, когда мы используем call-next-method ... большой до CLOS;) - person wj.; 29.12.2009

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

public interface IPerson
{
    void communicateFormally();
}

public class Person : IPerson 
{
    private String secret;
    public String othersSecret;

    public void snoop(IPerson p) {
      othersSecret = p.secret; //will be prohibited by the compiler
    }
    ...
}

Теперь это может быть «взломано» уродливым составом, но я думаю, что это проблема одного взлома.

person Rotsor    schedule 28.12.2009
comment
но это даст нам функцию pivate-интерфейса... на самом деле это не частный объект, такой как рубиновый пример Logan Capaldo... - person wj.; 28.12.2009

После нескольких часов гугления я нашел язык, лежащий в основе этой концепции: Smalltalk.

Состояние объекта всегда является частным для этого объекта. Другие объекты могут запрашивать или изменять это состояние, только отправляя соответствующие запросы (сообщения) объекту.

person wj.    schedule 28.12.2009
comment
См. pdf Инкапсуляция и наследование в объектно-ориентированных языках программирования eprints.kfupm.edu.sa /37524/1/37524.pdf - person igouy; 29.12.2009
comment
См. Принципы проектирования, лежащие в основе Smalltalk cs.virginia.edu/~evans/cs655. /readings/smalltalk.html - person igouy; 29.12.2009

В Java, который выглядит так, как будто вы пишете, «частный» означает закрытый для класса. Невозможно принудительно включить объектно-приватный режим. Причина этого в том, что "частный" — это способ обеспечения инкапсуляции, а не безопасности.

person Avi    schedule 28.12.2009

Я не думаю, что такое различие между классом и объектом private существует для наиболее распространенных языков OO, таких как C#, C++, Python, Java, Objective-C... Честно говоря, я не могу вспомнить язык, который на самом деле имеет эту особенность.

person rui    schedule 28.12.2009

Да, вы можете создавать объекты в Java, содержащие переменные экземпляра, которые не могут видеть другие экземпляры этого интерфейса. Тривиальный пример:

class Secretive { }
Secretive s = new Secretive() {
    int unknowable = 42;
};
Secretive t = new Secretive() {
    String unfathomable = "banana";
};
person Jonathan Feinberg    schedule 28.12.2009
comment
Это не совсем так. В вашем примере вы создаете два новых анонимных класса и создаете по одному экземпляру каждого. Таким образом, каждый экземпляр может иметь данные, которые являются частными для его (анонимного) класса, но это не совсем то же самое, что иметь данные, закрытые для экземпляра. - person Daniel Pryden; 28.12.2009

    public class Person
    {
        private String privateSecret;
        public String PublicInformation;

        public void Snoop(Person p)
        {
            // will be allowed by the .NET compiler
            p.PublicInformation = p.privateSecret;
        }
    }

просто используйте свойства или поля только для чтения для обеспечения безопасности.

Вы также можете использовать метод доступа internal для инкапсуляции вашего класса в сборку.

Вы также можете использовать некоторые методы запрета, такие как этот.

person serhio    schedule 28.12.2009
comment
это также будет разрешено javac и всеми компиляторами oop, которые я знаю ... Я спрашиваю, есть ли язык, который предлагает другой уровень инкапсуляции, запрещающий это ... - person wj.; 28.12.2009
comment
@Paolo: Это не странно, это обычный способ, которым языки ООП обрабатывают инкапсуляцию ... вот почему я задал свой вопрос :) - person wj.; 28.12.2009