문제

다음은 프로젝트 코드의 일부입니다.

public class Body extends Point{
    public double x, y, mass;

    public Body() {
        x = y = mass = 0;
    }

    public Body(double x, double y, double mass) {
        this.mass = mass;
        this.x = x;
        this.y = y;
    }
}

public class Point {
    public double x;
    public double y;

    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }
}

나는 이것을하는 것이 만들어 질 것이라는 것을 빨리 깨달았다 X라는 바디 클래스 내부의 변수와 y라는 본문의 다른 두 변수. 이것이 어떻게 가능하고, 왜 지구상에서 Java가 그것을 허용합니까?

나는 이것이 올바른 클래스 본문 코드라고 가정합니다.

public class Body extends Point{
    public double mass;

    public Body() {
        super();
        mass = 0;
    }

    public Body(double x, double y, double mass) {
        super(x,y);
        this.mass = mass;
    }
}

시간 내 줘서 고마워

도움이 되었습니까?

해결책

어떤 의미에서, 당신은 슈퍼 클래스의 필드를 무시하고 있습니다. 그러나 필드의 과부하가 없기 때문에 우연히 수행하는 것이 훨씬 쉽습니다 (주어진 이름의 변수가 하나만 있으면 유형은 중요하지 않습니다). 이것을 변수 '숨김'또는 '섀도 잉'이라고합니다. 그래서, 당신은 맞습니다. 당신은 같은 이름의 두 필드로 끝날 것입니다.

두 번째 예제가 정확합니다. 그것들은 슈퍼 클래스에서 상속되며 개인으로 선언되지 않기 때문에 서브 클래스로 보입니다. 일반적으로 슈퍼 클래스의 필드를 직접 언급하는 것은 나쁜 관행이며, 그럴만 한 이유가 없다면 개인으로 선언해야합니다. 슈퍼 생성자를 호출하는 예가 최선의 방법입니다.

또한 같은 이름의 다른 이름으로 필드를 숨기면 여전히 super.x, super.y, vs.x, this.y로 지칭 할 수 있습니다. 가능하다면이 상황을 피해야합니다.

다른 팁

그렇습니다. 하나는 두 개의 변수가 있으며, 하나는 다른 하나를 숨기고 있습니다. 두 가지 이유를 허용하는 것이 합리적입니다.

  1. 기본 클래스가 있다고 가정 해 봅시다 Base 그리고 파생 수업 Derived 저자의 Base 전혀 모른다. 저자의 경우 Base 파생 된 클래스이기 때문에 필드를 추가 할 수 없습니다. ~할 것 같다 필드를 공유 하시겠습니까? 또는 Derived 변경할 때 컴파일을 중지하십시오 Base 실제로 정확성에 영향을 미치지 않습니까?
  2. 필드는 거의 항상 개인이어야하며,이 시점에서 이름이 복제되었는지 여부는 중요하지 않습니다. "측면"은 다른 사람의 변수에 대해 알지 못합니다.

다른 사람들이 말한 것에 더욱 : IS BodyPoint? 아니, Body 유형의 위치 특성이 있습니다 Point. 그래서 Body 아마도 확장해서는 안됩니다 Point. (구현의) 상속을 제거하면 많은 문제가 제거됩니다. 그것과 사용 private (아니다 protected!) 그리고 final 자유롭게.

이 작업을 수행하면 바디 클래스 내에서 X라는 두 가지 변수와 y라는 신체의 다른 두 변수가 생길 것임을 빨리 깨달았습니다. 이것이 어떻게 가능하고, 왜 지구상에서 Java가 그것을 허용합니까?

실제로 아니요, 당신은 같은 이름으로 두 개의 변수를 생성하지 않습니다. 분명히 컴파일러는 이것을 허용하지 않아야하며 허용하지 않아야합니다.

당신이 ~이다 수행하는 것은 기존 변수를 표시하는 것입니다 x 그리고 y, Body.x와 Body.y는 본질적으로 Point.x 및 Point.y의 이름을 겹치며 후자의 두 변수는 바디 클래스에서 완전히 접근 할 수 없습니다 ("섀도 잉"의 Java 언어 사양 정의에 대한 링크).

이름 섀도 잉은 일반적으로 나쁜 관행과 버그의 원인으로 인식되고 있으며, Javac 컴파일러 경고를 켜면 컴파일러가 이에 대해 정중하게 경고합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top