静的メソッドが非静的データを使用できない理由がわかりません。誰が問題が何であり、なぜそれができないのかを説明できますか?
静的メソッドが非静的データを使用できない理由がわかりません。誰が問題が何であり、なぜそれができないのかを説明できますか?
回答:
ほとんどのオブジェクト指向言語では、クラス内でメソッドを定義すると、インスタンスメソッドになります。キーワードを使用してそのクラスの新しいインスタンスを作成すると、new
そのインスタンスに固有の新しいデータセットが初期化されます。そのインスタンスに属するメソッドは、そのインスタンスで定義したデータを処理できます。
対照的に、静的メソッドは個々のクラスインスタンスを認識しません。静的メソッドは、CまたはC ++のフリー関数に似ています。クラスの特定のインスタンス化に関連付けられていません。これが、インスタンス値にアクセスできない理由です。値を取得するインスタンスはありません!
静的データは静的メソッドに似ています。宣言された値にはstatic
インスタンスが関連付けられていません。インスタンスごとに存在し、メモリ内の1か所でのみ宣言されます。変更された場合、そのクラスのすべてのインスタンスで変更されます。
A 静的メソッドにアクセスすることができます静的データを彼らは両方のクラスの特定のインスタンスとは独立して存在しているため。
インスタンスメソッドと比較して、静的メソッドを呼び出す方法を確認すると役立つ場合があります。次のクラスがあったとしましょう(Javaのような擬似コードを使用):
class Foo {
// This static value belongs to the class Foo
public static final string name = "Foo";
// This non-static value will be unique for every instance
private int value;
public Foo(int value) {
this.value = value;
}
public void sayValue() {
println("Instance Value: " + value);
}
public static void sayName() {
println("Static Value: " + name);
}
}
Foo foo1 = new Foo(10);
Foo foo2 = new Foo(20);
foo1.sayValue(); // Prints "Instance Value: 10" - called on foo1
foo2.sayValue(); // Prints "Instance Value: 20" - called on foo2
Foo.sayName(); // Prints "Static Value: Foo" - called on Foo (not foo1 or foo2)
などから来るコメントで指摘して、静的な方法がある非静的データを扱うことのできる、それが明示的に渡さなければなりません。Foo
クラスに別のメソッドがあると仮定しましょう:
public static Foo Add(Foo foo1, Foo foo2) {
return new Foo(foo1.value + foo2.value);
}
Add
まだ静的でありvalue
、独自のインスタンスはありませんが、Fooクラスのメンバーであるためvalue
、渡されたインスタンスfoo1
およびfoo2
インスタンスのプライベートフィールドにアクセスできます。この場合、両方の渡された値の追加された値で新しい を返すためにそれを使用していFoo
ます。
Foo foo3 = Foo.Add(foo1, foo2); // creates a new Foo with a value of 30
this
-referenceが利用できないだけです。理解することは非常に重要だと思います。
仮説的なサンプルで説明しましょう。
簡単なクラスを想像してください:
class User
{
User(string n) { name = n; };
string name;
}
次に、このクラスの2つのインスタンスを作成します。
User Bones = new User("Bones");
User Jim = new User("Jim");
今、考えてみてください-ユーザーに新しい静的メソッドを追加した場合、例えば:
static string GetName();
そしてあなたはそれを呼ぶ:
string x = User::GetName()
xには何が含まれますか?「ジム」、「骨」、または他の何か?
問題は、静的メソッドがオブジェクトではなくクラスで定義された単一のメソッドであることです。その結果、どのオブジェクトに適用されるかわかりません。これが特別な理由です。静的メソッドは、たとえばCの関数のような個別の物と考えるのが最善です。Javaのような言語がクラス内に含まれていることは、主にJavaがクラス外に存在することを許可しないという問題であるため、このような関数は何らかの方法でクラス内に強制する必要があります(main()クラス内でも、すべての意味で、それが単一のスタンドアロン関数であるべきだと言っている場合)。
フィールドデータを使用できます。次のJavaコードを検討してください。
class MyBean {
private String myString;
static void myStaticMethod() {
myString = "tada";/*not allowed; if this was possible how would
be different from a field without static?*/
MyBean myBean = new MyBean();//allowed if associated with an instance
myBean.myString = "tada";
}
}
static
。
ここでの問題は理解の問題だと思います。
技術的な観点からは、オブジェクト内から呼び出される静的メソッドは、インスタンスフィールドを非常に見ることができます。そもそもこれが問題の原因であると強く思う。
問題は、オブジェクトの外部からメソッドを呼び出すことができることです。その時点では、それらを提供するインスタンスデータはありません。したがって、コンパイラがコードを解決する方法はありません。インスタンスデータを許可すると矛盾が発生するため、インスタンスデータを許可してはなりません。
オブジェクト指向ではない次元に存在する静的メソッドと考えてください。
「オブジェクト指向の次元」では、クラスは複数のエゴ(インスタンス)を生成できます。各エゴは、その状態によって自身の良心を持っています。
フラットでオブジェクト指向でない次元では、クラスはオブジェクト指向次元に住んでいる彼らのエゴを忘れています。彼らの世界は、OOPがまだ発明されていないかのように、クラスが小さな手続き型プログラムであり、静的データが単なるグローバル変数であるかのように、フラットで手続き型です。
これを説明する最も簡単な方法は、いくつかのコードを見て、そのコードが生成することを期待する結果を検討することだと思います。
// Create three new cars. Cars have a name attribute.
Car car1 = new Car("Mazda3");
Car car2 = new Car("FordFocus");
Car car3 = new Car("HondaFit");
// Now we would like to print the names of some cars:
// First off why don't we try this:
Car.printCarName();
// Expected behaviour:
// If we think about what we are trying to do here it doesn't
// really make sense. What instance of car name should this
// print? Should it print Mazda3? FordFoucs?
// What is the expected behaviour? If we are going to have a
// static call on car call printCarName it should probably do
// something like print all car names or a random car name or
// throw an error.
//Now lets try this instead:
Car.printCarName(car1);
// Expected Behaviour:
// Luckily the expected behaviour is very clear here. This
// should print Mazda3. This works as expected.
// Finally lets try this:
car1.printMyName();
// Expected Behaviour:
// Same as previous example, however this is the *right* way
// to do it.
完全を期すために、ここに車のクラスがあります:
public class Car{
public String name;
public Car(String name){
this.name = name;
}
public static printCarName(){
print "Not sure what to do here... Don't know which car you are talking about.";
}
public static printCarName(Car c){
print c.name;
}
public /*NOT static*/ printMyName(){
print this.name;
}
}
他の答えはほとんどすべてを言っていますが、追加したい「詳細」があります。
静的メソッド(Javaのメソッドなど)には、this
通常は名前で直接アクセスできるメンバーを持つ暗黙的なオブジェクトが関連付けられていません(を介してアクセス可能)。
それは、彼らが非静的データにアクセスできないという意味ではありません。
class MyClass {
public static void foo(MyOtherClass object) {
System.out.println(object.member);
}
}
class MyOtherClass {
public int member = 10;
}
これは詳細に過ぎませんが、読んだときにあなたの質問がおかしいと感じました。「静的データのみを使用できます」は制限が多すぎます。
ところで、私はコードをテストしませんでした。私が言っていることを例示するために、ここに書いただけです。