Java(C++のように)で友達の概念をどのように実装しますか?
Javaには、C++のfriendキーワードがありません。ただし、それをエミュレートする方法があります。実際にはるかに正確な制御を提供する方法。クラスAとBがあるとします。BはAのプライベートメソッドまたはフィールドにアクセスする必要があります。
public class A {
private int privateInt = 31415;
public class SomePrivateMethods {
public int getSomethingPrivate() { return privateInt; }
private SomePrivateMethods() { } // no public constructor
}
public void giveKeyTo(B other) {
other.receiveKey(new SomePrivateMethods());
}
}
public class B {
private A.SomePrivateMethods key;
public void receiveKey(A.SomePrivateMethods key) {
this.key = key;
}
public void usageExample() {
A anA = new A();
// int foo = anA.privateInt; // doesn't work, not accessible
anA.giveKeyTo(this);
int fii = key.getSomethingPrivate();
System.out.println(fii);
}
}
UsageExample()は、これがどのように機能するかを示しています。 Bのインスタンスは、Aのインスタンスのプライベートフィールドまたはメソッドにアクセスできません。ただし、giveKeyTo()を呼び出すことにより、クラスBはアクセスを取得できます。引数として有効なBが必要なため、他のクラスはそのメソッドにアクセスできません。コンストラクターはプライベートです。
クラスBは、キーで渡された任意のメソッドを使用できます。これは、C++のfriendキーワードよりも設定が面倒ですが、はるかにきめ細かいものです。クラスAは、どのクラスにどのメソッドを公開するかを正確に選択できます。
上記の場合、AはBのすべてのインスタンスとBのサブクラスのインスタンスへのアクセスを許可しています。後者が望ましくない場合、giveKeyTo()メソッドはgetClass()を使用して他の正確なタイプを内部的にチェックし、スローすることができます。正確にBでない場合の例外。
A.foo()
はB
によってのみ呼び出される必要があるとします。これは、B
によってのみ生成できるトークンによって調整できます。
_public class B
{
public static class ToA { private ToA(){} }
private static final ToA b2a = new ToA();
void test()
{
new A().foo(b2a);
}
}
public class A
{
public void foo(B.ToA b2a)
{
if(b2a==null)
throw new Error("you ain't B");
// ...
}
}
_
B
のみがnull以外の_B.ToA
_トークンを生成できます。 A
とB
の両方がこのトークンをサードパーティにリークしない場合、他の誰もA.foo()
を呼び出すことができません。
_A2
_もB
と友達になりたい場合は、別のトークンタイプが必要です。同じトークンタイプの場合、A
はB
からタイプのトークンを取得したため、A
はB
から_A2
_のふりをすることができます。 。
チェックはコンパイル時ではなく実行時に行われるため、完全ではありません。ただし、大したことではありません。サードパーティはA.foo()
をnull
でしか呼び出せないため、コンパイル時に確認したい無実の間違いではありません。おそらく悪意があるので、コンパイル時に呼び出し元に警告する必要はありません。
Java)では、両方(またはそれ以上)のクラスを同じパッケージに入れることができます。protected
修飾子を持つすべてのメソッドとフィールドには、そのパッケージ内のすべてのクラスから直接アクセスできます。