Thinking in Java 구조 기 호출 순서
//: polymorphism/Sandwich.java
// Order of constructor calls.
package polymorphism;
import static net.mindview.util.Print.*;
class Meal {
Meal() { print("Meal()"); }
}
class Bread {
Bread() { print("Bread()"); }
}
class Cheese {
Cheese() { print("Cheese()"); }
}
class Lettuce {
Lettuce() { print("Lettuce()"); }
}
class Lunch extends Meal {
Lunch() { print("Lunch()"); }
}
class PortableLunch extends Lunch {
PortableLunch() { print("PortableLunch()");}
}
public class Sandwich extends PortableLunch {
private Bread b = new Bread();
private Cheese c = new Cheese();
private Lettuce l = new Lettuce();
public Sandwich() { print("Sandwich()"); }
public static void main(String[] args) {
new Sandwich();
}
} /* Output:
Meal()
Lunch()
PortableLunch()
Bread()
Cheese()
Lettuce()
Sandwich()
*///:~
이 예 에서 다른 종류 로 복잡 한 종 류 를 만 들 었 고 모든 종 류 는 자신 을 설명 하 는 구조 기 를 가지 고 있다.그 중에서 가장 중요 한 유형 은 Sandwich 로 3 층 상속(Object 의 은밀 한 상속 도 포함 하면 4 층)과 3 명의 멤버 대상 을 반영 한다.main()에 Sandwich 대상 을 만 들 면 출력 결 과 를 볼 수 있 습 니 다.이것 또한 이 복잡 한 대상 호출 구조 기 는 아래 의 순 서 를 따라 야 한 다 는 것 을 나타 낸다.
1)기본 구조 기 를 호출 합 니 다.이 절 차 는 끊임없이 반복 적 으로 돌아 갈 것 이다.먼저 이런 차원 구조의 뿌리 를 구성 한 다음 에 다음 층 의 도 출 류 등 을 통 해 최저 층 의 도 출 류 를 알 수 있다.
2)성명 순서에 따라 구성원 의 초기 화 방법 을 호출 합 니 다.
3)내 보 내기 구조 기의 주 체 를 호출 합 니 다.
구조 기의 호출 순 서 는 매우 중요 하 다.계승 을 진행 할 때,우 리 는 이미 기본 클래스 의 모든 것 을 알 고 있 으 며,기본 클래스 를 방문 하여 Public 와 proctected 의 구성원 으로 성명 할 수 있 습 니 다.내 보 내기 클래스 에서 기본 클래스 의 모든 구성원 이 유효 하 다 고 가정 해 야 한 다 는 뜻 이다.하나의 표준 방법 은 구조 동작 이 발생 하면 대상 의 모든 부분의 구성원 이 구 축 될 수 있다 는 것 이다.그러나 구조 기 내부 에 서 는 사용 할 구성원 이 모두 구축 되 었 는 지 확인 해 야 한다.이 를 확보 하기 위해 서 는 기 존 구조 기 를 먼저 호출 하 는 것 이 유일한 방법 이다.그러면 내 보 내기 구조 기 에 들 어 갈 때 기본 클래스 에서 우리 가 방문 할 수 있 는 구성원 들 은 모두 초기 화 됩 니 다.또한 구조 기 에 있 는 모든 구성원 이 효과 가 있다 는 것 을 아 는 것 도 구성원 대상 이 클래스 내 에서 정 의 를 내 릴 때(예 를 들 어 상례 의 b,c,l)가능 하 다 면 초기 화 해 야 하기 때문이다(즉,조합 방법 을 통 해 대상 을 클래스 내 에 두 어야 한 다 는 것 이다).이 규칙 을 따 르 면 모든 기본 구성원 과 현재 대상 의 대상 이 초기 화 될 수 있 습 니 다.안 타 깝 게 도 이런 방법 은 모든 상황 에 적용 되 지 않 는 다 는 점 은 다음 절 에서 볼 수 있다.
----------------------------------------------------------------------------
4
//: polymorphism/PolyConstructors.java
// Constructors and polymorphism
// don't produce what you might expect.
import static net.mindview.util.Print.*;
class Glyph {
void draw() { print("Glyph.draw()"); }
Glyph() {
print("Glyph() before draw()");
draw();
print("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
private int radius = 1;
RoundGlyph(int r) {
radius = r;
print("RoundGlyph.RoundGlyph(), radius = " + radius);
}
void draw() {
print("RoundGlyph.draw(), radius = " + radius);
}
}
public class PolyConstructors {
public static void main(String[] args) {
new RoundGlyph(5);
}
} /* Output:
Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5
*///:~
Glyph.draw()방법 은 덮어 쓰 도록 설계 되 었 으 며,이러한 덮어 쓰 기 는 RoundGlyph 에서 발생 합 니 다.그러나 Glyph 구조 기 는 이 방법 을 호출 하여 RoundGlyph.draw()를 호출 하 게 되 었 습 니 다.이것 은 우리 의 목적 인 것 같 습 니 다.그러나 출력 결 과 를 보면 Glyph 의 구조 기 가 draw()방법 을 호출 할 때 radius 는 기본 초기 값 1 이 아니 라 0 이라는 것 을 알 수 있 습 니 다.이 로 인해 화면 에 점 만 그 렸 거나 아무것도 없 을 수 있 습 니 다.우 리 는 눈 을 부 릅 뜨 고 프로그램 이 작 동 하지 않 는 원인 을 찾 으 려 고 할 수 밖 에 없 었 다.앞의 절 에서 말 한 초기 화 순 서 는 완전 하지 않 은 데 이것 이 바로 이 수수 께 끼 를 해결 하 는 관건 이다.초기 화 된 실제 과정 은:
1)다른 모든 사물 이 발생 하기 전에 대상 에 게 분 배 된 저장 공간 을 바 이 너 리 0 으로 초기 화 합 니 다.
2)앞에서 말 한 바 와 같이 기본 구조 기 를 호출 한다.이 때 덮어 쓴 draw()방법 을 호출 합 니 다.(RoundGlyph 구조 기 를 호출 하기 전에 호출 해 야 합 니 다)절차 1 때문에 radius 의 값 이 0 인 것 을 발견 할 수 있 습 니 다.
3)성명 순서에 따라 구성원 의 초기 화 방법 을 호출 합 니 다.
4)내 보 내기 클래스 의 구조 체 를 호출 합 니 다.
이렇게 하면 모든 것 이 쓰레기 로 만 남 겨 두 는 것 이 아니 라 0 으로 초기 화 되 는 것 이 장점 이다.그 중에서'조합'을 통 해 내부 에 포 함 된 대상 인용 을 포함 하고 그 값 은 null 입 니 다.따라서 이 인용 을 초기 화 하 는 것 을 잊 으 면 실행 중 이상 이 발생 합 니 다.출력 결 과 를 볼 때 다른 모든 물건 의 값 이 0 이라는 것 을 발견 할 수 있 습 니 다.이것 은 보통 문 제 를 발견 한 증거 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.