Есть ли язык с объектно-ориентированными уровнями доступа? - PullRequest
7 голосов
/ 05 августа 2009

Распространенным заблуждением об уровне доступа в Java, C #, C ++ и PHP является то, что он применяется к объектам, а не к классам. То есть, что (скажем) объект класса X не может видеть приватные члены другого X. На самом деле, конечно, уровень доступа основан на классе, и один объект X может легко ссылаться на закрытые члены другого.

Существует ли язык с объектными уровнями доступа? Они вместо или в дополнение к доступу на основе классов? Какое влияние эта функция оказывает на дизайн программы?

Ответы [ 3 ]

6 голосов
/ 05 августа 2009

Ruby имеет объектный уровень доступа. Вот цитата из программирования Ruby:

Разница между "защищенными" и "частный" довольно тонкий, и отличается в Ruby, чем в большинстве общие ОО языки. Если метод защищенный, он может быть вызван любым экземпляр определяющего класса или его подклассы. Если метод является частным, это может быть вызван только в контексте вызывающего объекта --- это никогда можно получить доступ к другому объекту частные методы напрямую, даже если объект того же класса, что и Вызывающий.

А вот и источник: http://whytheluckystiff.net/ruby/pickaxe/html/tut_classes.html#S4

Пример разницы между Java и Ruby

Java

public class Main {
    public static void main(String[] args) {
        Main.A a1 = new A();
        Main.A a2 = new A();

        System.out.println(a1.foo(a2));
    }

    static class A
    {
        public String foo(A other_a)
        {
            return other_a.bar();
        }

        private String bar()
        {
            return "bar is private";
        }
    }
}

// Outputs
// "bar is private"

рубин

class A
  def foo other_a
    other_a.bar
  end

  private
  def bar
    "bar is private"
  end
end

a1 = A.new
a2 = A.new

puts a1.foo(a2)

# outputs something like
# in `foo': private method `bar' called for #<A:0x2ce9f44> (NoMethodError)
0 голосов
/ 05 августа 2009

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

У такого языка были бы преимущества, например, вы могли бы пометить определенные данные как личные для всех, кроме объекта, который их создал (пароли были бы отличным примером: даже код, запущенный в том же приложении, не мог их прочитать) .

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

В реальном мире вы найдете это в микросхеме TPM на вашей материнской плате и, в очень грубой форме, в таблицах MMU ЦП. Но это на уровне страницы 4K, а не на уровне байтов. Есть библиотеки для обработки обоих, но это не считается «языковой поддержкой» IMO.

Java имеет что-то подобное в виде API безопасности . Вы должны обернуть данный код в опекуна, который спрашивает текущий SecuityManager, разрешен ли доступ.

В Python вы можете добиться чего-то похожего с декораторами (для методов и функций) или с помощью __setattr__ и __getattr__ для доступа к полю.

0 голосов
/ 05 августа 2009

Вы можете реализовать это в C #, имея некоторый метод, способный обходить стек и проверять, какой объект является вызывающим, и генерировать исключение, если это не текущий класс. Я не знаю, почему вы хотели бы, но я думал, что я брошу это там.

...