Существует ли язык с объектно-ориентированными уровнями доступа?
-
22-07-2019 - |
Вопрос
Распространенное заблуждение об уровне доступа в Java, C#, C++ и PHP заключается в том, что он применяется к объектам, а не к классам.То есть (скажем) объект класса X не может видеть частные члены другого X.На самом деле, конечно, уровень доступа основан на классах, и один объект X может легко ссылаться на частные члены другого.
Существует ли язык с объектно-ориентированными уровнями доступа?Являются ли они вместо или в дополнение к доступу на основе классов?Какое влияние эта функция оказывает на дизайн программы?
Решение
Ruby имеет объектно-ориентированный уровень доступа.Вот цитата из Programming Ruby:
Разница между «защищенным» и «частным» довольно тонкая и отличается от Ruby, чем на наиболее распространенных языках.Если метод защищен, он может быть вызван любым экземпляром определяющего класса или его подклассов.Если метод является частным, его можно назвать только в контексте вызывающего объекта-никогда невозможно напрямую доступ к частным методам другого объекта, даже если объект имеет тот же класс, что и вызывающий абонент.
И вот источник: http://whytheluckystiff.net/ruby/pickaxe/html/tut_classes.html#S4
Пример разницы между Java и Ruby
Джава
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)
Другие советы
Основная причина, по которой ни один язык не поддерживает это на семантическом уровне, заключается в том, что различные потребности слишком различны, чтобы найти общий знаменатель, достаточно большой для такой функции.Сокрытие данных само по себе плохо, и оно становится только хуже, когда вам нужен еще более детальный контроль.
У такого языка были бы свои преимущества: например, вы могли бы пометить определенные данные как личные для всех, кроме объекта, который их создал (отличным примером могут быть пароли:Даже код, работающий в том же приложении, не мог их прочитать).
К сожалению, эта «защита» будет поверхностной, поскольку на уровне ассемблера защиты не будет.Чтобы быть эффективным, аппаратное обеспечение должно его поддерживать.В данном случае, вероятно, на уровне одного байта в оперативной памяти.Это сделало бы такое приложение чрезвычайно безопасным и мучительно медленным.
В реальном мире вы найдете это в чип TPM на вашей материнской плате и, в очень грубой форме, с таблицами MMU процессора.Но это на уровне страницы 4K, а не на уровне байтов.Существуют библиотеки для обработки обоих, но это не считается «языковой поддержкой», IMO.
В Java есть что-то подобное в виде API безопасности.Вы должны обернуть рассматриваемый код в опекуна, который запрашивает текущий SecuityManager
разрешен ли доступ или нет.
В Python вы можете добиться чего-то подобного с помощью декораторов (для методов и функций) или реализовав __setattr__
и __getattr__
для доступа к полям.
Вы можете реализовать это в C #, имея некоторый метод, способный обходить стек и проверять, какой объект является вызывающим, и выдавать исключение, если это не текущий класс. Я не знаю, почему вы хотели бы, но я думал, что я выброшу это там.