정적 메소드가 정적이 아닌 데이터를 사용할 수없는 이유를 이해하지 못합니다. 아무도 문제가 무엇인지, 왜 우리가 할 수 없는지 설명 할 수 있습니까?
정적 메소드가 정적이 아닌 데이터를 사용할 수없는 이유를 이해하지 못합니다. 아무도 문제가 무엇인지, 왜 우리가 할 수 없는지 설명 할 수 있습니까?
답변:
대부분의 OO 언어에서 클래스 내부에 메소드를 정의하면 인스턴스 메소드가 됩니다. 키워드 를 통해 해당 클래스 의 새 인스턴스 를 만들면 new
해당 인스턴스에만 고유 한 새 데이터 세트가 초기화됩니다. 그러면 해당 인스턴스에 속하는 메소드가 사용자가 정의한 데이터로 작업 할 수 있습니다.
대조적으로 정적 메소드 는 개별 클래스 인스턴스를 무시합니다. 정적 메소드는 C 또는 C ++의 무료 함수와 유사합니다. 클래스의 특정 인스턴스화와 관련이 없습니다. 이것이 인스턴스 값에 액세스 할 수없는 이유입니다. 가치를 얻을 수있는 사례가 없습니다!
정적 데이터 는 정적 방법과 유사합니다. 선언 된 값 static
에는 연관된 인스턴스가 없습니다. 모든 인스턴스에 대해 존재 하며 메모리의 단일 위치에서만 선언됩니다. 변경되면 해당 클래스의 모든 인스턴스에 대해 변경됩니다.
정적 메서드가 액세스 할 수있는 정적 데이터를 둘 다 클래스의 특정 인스턴스 독립적으로 존재하기 때문이다.
인스턴스 메소드와 비교하여 정적 메소드를 호출하는 방법을 살펴 보는 것이 도움이 될 수 있습니다. 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)
주석에서 COME FROM이 지적한 것처럼 정적 메소드 는 비 정적 데이터로 작업 할 수 있지만 명시 적으로 전달해야합니다. 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
사용할 수 없습니다. 이해하는 것이 매우 중요하다고 생각합니다.
가상의 샘플로 설명해 드리겠습니다.
간단한 수업을 상상해보십시오.
class User
{
User(string n) { name = n; };
string name;
}
이제이 클래스의 인스턴스를 2 개 만듭니다.
User Bones = new User("Bones");
User Jim = new User("Jim");
이제 생각하십시오-User에 새로운 정적 메소드를 추가하면 다음과 같이됩니다.
static string GetName();
그리고 당신은 그것을 호출 :
string x = User::GetName()
x는 무엇을 포함 할 것인가? "짐", "뼈"또는 다른 것?
문제는 정적 메소드가 객체가 아니라 클래스에 정의 된 단일 메소드라는 것입니다. 결과적으로 어떤 객체에 적용되는지 알 수 없습니다. 이것이 특별한 이유입니다. 정적 메소드를 C의 함수와 같은 개별적인 것으로 생각하는 것이 가장 좋습니다. Java와 같은 언어가 클래스 내부에 포함되어 있다는 것은 주로 클래스 외부에 존재하는 것을 허용하지 않는 Java의 문제이므로 이와 같은 함수는 어떤 방식으로 클래스 내부에서 강제해야합니다 (main ()이 강제로 수행되는 것과 약간 비슷합니다) 모든 의미에서 단일, 독립형 기능이어야한다고 말할 때 클래스 내부에서도).
필드 데이터를 사용할 수 있습니다. 다음 자바 코드를 고려하십시오.
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
.
여기서 문제는 이해의 문제라고 생각합니다.
기술적 인 관점에서 객체 내에서 호출 된 정적 메소드는 인스턴스 필드를 볼 수 있습니다. 이것이 처음에 문제를 일으킨 원인이라고 생각합니다.
문제는 객체 외부에서 메소드를 호출 할 수 있다는 것입니다. 이 시점에서 인스턴스 데이터를 제공 할 인스턴스 데이터가 없으므로 컴파일러가 코드를 해결할 수있는 방법이 없습니다. 인스턴스 데이터를 허용하면 모순이 발생하므로 인스턴스 데이터를 허용해서는 안됩니다.
이것을 설명하는 가장 쉬운 방법은 일부 코드를보고 코드가 어떤 결과를 기대할 수 있는지 고려하는 것입니다.
// 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;
}
나는 이것이 세부 사항이라는 것을 알고 있지만 그것을 읽을 때 귀하의 질문이 이상하다는 것을 알았습니다. "정적 데이터 만 사용할 수 있습니다"는 너무 제한적입니다.
그건 그렇고, 나는 코드를 테스트하지 않았으며, 내가 말한 것을 예시하기 위해 여기에 썼습니다.