7

Java、C#、C++、および PHP のアクセス レベルに関する一般的な誤解は、それがクラスではなくオブジェクトに適用されるというものです。つまり、(たとえば) クラス X のオブジェクトは、別の X のプライベート メンバーを見ることができません。実際、もちろん、アクセス レベルはクラス ベースであり、1 つの X オブジェクトは別のオブジェクトのプライベート メンバーを簡単に参照できます。

オブジェクトベースのアクセス レベルを持つ言語は存在しますか? それらはクラスベースのアクセスの代わりですか、またはそれに加えてですか? この機能はプログラムの設計にどのような影響を与えますか?

4

3 に答える 3

6

Ruby にはオブジェクト ベースのアクセス レベルがあります。以下は、プログラミング Ruby からの引用です。

「保護」と「非公開」の違いはかなり微妙で、Ruby と一般的な OO 言語の違いはほとんどありません。メソッドが保護されている場合は、定義クラスまたはそのサブクラスの任意のインスタンスから呼び出すことができます。メソッドがプライベートの場合、呼び出し元オブジェクトのコンテキスト内でのみ呼び出すことができます。オブジェクトが呼び出し元と同じクラスであっても、別のオブジェクトのプライベート メソッドに直接アクセスすることはできません。

ソースは次のとおりです: 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)
于 2009-08-05T13:50:27.930 に答える
0

どの言語もセマンティック レベルでこれをサポートしていない主な理由は、さまざまなニーズがあまりにも異なり、そのような機能に十分な大きさの共通分母を見つけることができないためです。データの隠蔽はそのままでも十分に悪いものであり、さらにきめ細かな制御が必要な場合にのみ悪化します。

このような言語には利点があります。たとえば、特定のデータを、それを作成したオブジェクト以外の誰に対してもプライベートとしてマークできます (パスワードは良い例です。同じアプリケーションで実行されているコードでさえ、それらを読み取ることはできません)。

残念ながら、アセンブラ レベルでは保護が存在しないため、この「保護」は表面的なものになります。効率的であるためには、ハードウェアがそれをサポートする必要があります。この場合、おそらく RAM の 1 バイトのレベルです。これにより、そのようなアプリケーションは非常に安全になり、非常に遅くなります。

現実の世界では、これはメインボードのTPM チップにあり、非常に粗い形で CPU の MMU テーブルにあります。しかし、それはバイト レベルではなく、4K ページ レベルです。両方を処理するライブラリがありますが、それは「言語サポート」IMO とは見なされません。

Java にはSecurity APIの形でこのようなものがあります。SecuityManagerアクセスが許可されているかどうかを現在に尋ねるガーディアンで問題のコードをラップする必要があります。

Python では、デコレーター (メソッドと関数用) を使用するか、フィールド アクセス用の__setattr__とを実装することで、同様のことを実現できます。__getattr__

于 2009-08-05T14:07:06.317 に答える
-1

スタックをウォークし、呼び出し元がどのオブジェクトであるかをチェックし、現在のクラスでない場合は例外をスローできるメソッドを用意することで、C# でこれを実装できます。なぜあなたがそうしたいのかわかりませんが、私はそれをそこに捨てようと思いました.

于 2009-08-05T13:53:25.523 に答える