자바 학습 노트 - 디자인 모델: 리 씨 교체 원칙
11976 단어 디자인 모드
문제: 왜 하위 클래스 는 부모 클래스 가 이미 실 현 된 방법 을 수정 하거나 덮어 쓰 지 않 습 니까?
리 씨 교체 원칙 의 정의 위반 리 씨 교체 원칙 에 위반 하여 '자 류 는 하나의 아버지 류 이 고 아버지 류 가 나타 날 수 있 는 곳 의 자 류 는 반드시 나타 날 수 있다' 는 정 의 를 내 렸 다. 자 류 와 아버지 류 의 실현 방법 기능 이 다 르 면 자 류 는 반드시 아버지 류 를 완전히 교체 할 수 있 는 것 이 아니다 (기능 이 일치 하지 않 음).
만약 에 아버지 류 에서 이미 실 현 된 방법 이 여러 개의 하위 클래스 에 의 해 임의로 덮어 쓰 이 고 다시 쓰 면 이 계승 체계 에서 같은 방법 이 여러 개의 서로 다른 실현 에 대응 하 게 될 것 이다.즉, 서로 다른 하위 유형의 다 형 유형 을 사용 할 때 같은 방법 으로 성명 하면 서도 서로 다른 실현 (기능) 장면 에 직면 하 게 된다. 그러면 전체 계승 체계 가 혼 란 스 럽 고 모호 해 질 것 이다. 특히 이 계승 체계의 다 형 을 자주 사용 할 때 오류 가 발생 할 가능성 이 커진다. 예 를 들 어:
//
public class Parent {
// :
public int function(int a, int b) {
return (a + b);
}
}
// 1
public class Son1 extends Parent {
// getSum() :
@Override
public int function(int a, int b) {
return (a - b);
}
}
// 2
public class Son2 extends Parent {
// getSum() :
@Override
public int function(int a, int b) {
return (a / b);
}
}
// :
public class Test1 {
public static void main(String[] args) {
// 1:
Parent parent = new Parent();
// 2:
int num = son1.function(1, 2);
}
}
// :
public class Test2 {
public static void main(String[] args) {
// 1:
Son1 son1 = new Son1();
// 2: , 。
int num = son1.function(1, 2);
}
}
다시 말 하면 하나의 계승 체계 에서 아버지 류 의 일부 방법 이 빈번 한 이불 류 의 실현 이 필요 하 다 면 각 하위 류 에서 해당 하 는 방법 을 각각 정의 하 는 것 이 바람 직 하 다.중복 코드 에 속 하지 않 으 며, 해당 하위 클래스 에서 서로 다른 기능 의 코드 로 '이름 을 보고 의 미 를 안다' 는 방법 으로 서명 할 수 있 기 때문이다.
이해 2: 2 에 대해 자 류 는 자신의 '특색' 을 가 질 수 있다.
자 류 는 부 류 를 바탕 으로 자신 만 의 독특한 기능 을 증가 시 킬 수 있다.이런 종 류 는 더 많은 기능 을 완성 할 수 있 고 부 류 를 완전히 투명 하 게 교체 할 수 있다.
이해 3: 3, 방법 재 업로드 규칙
1. 방법의 선행 조건 과 선행 조건 은 무엇 입 니까?
방법, 즉 어떤 행위 나 기능 을 가 진 코드 를 봉인 하 는 것 이다.선행 조건, 즉 방법의 형 삼 은 방법 기능 의 실현 을 위해 필요 한 데 이 터 를 전달 하 는 것 이다.후장 조건, 즉 방법의 반환 값 으로 기능 방법의 최종 결 과 를 얻는다.
2. 왜 방법의 형 삼 과 반환 값 을 '조건' 이 라 고 부 릅 니까?
방법의 매개 변수 와 반환 값 은 이 방법의 '실현 규칙', 즉 실현 방법의 기능 에 필요 한 전제 조건 과 최종 적 으로 어떤 유형의 결 과 를 얻 는 지 정의 하 는 것 이다.구체 적 으로 어떻게 실현 하 든 간 에 방법의 전제 와 결과 제약 만 만족 시 키 면 된다.통속 적 인 것 은 '어떤 일 을 완성 하려 면 먼저 무엇 을 가 져 야 하고, 마지막 에 무엇 을 가 져 야 하 는가' 이다.
3. 방법의 재 업로드 와 재 작성 은 무엇 입 니까?
(1) 하위 클래스 덮어 쓰기 부모 클래스 방법 규칙: 방법 명 이 같 고 매개 변수 가 같 으 며 이상 축소, 권한 확대, 반환 값 이 같 거나 축소 합 니 다.만족 하지 않 으 면 덮어 쓰 기 를 하지 않 습 니 다 [방법 조건 이 같 고 구체 적 인 실현 방식 이 다 릅 니 다].다시 쓴 방법 으로 원래 의 방법 을 바 꾸 고 원래 의 방법 은 바 뀌 었 다.
이상 축소: 하위 클래스 방법 에서 던 진 이상 은 부모 클래스 성명 의 이상 과 같 거나 하위 클래스 이상 이 어야 합 니 다.하위 클래스 방법 이 부모 클래스 보다 이상 하 다 고 밝 히 면 하위 클래스 는 부모 클래스 를 완전히 투명 하 게 교체 할 수 없습니다.예 를 들 어 부모 클래스 성명 은 빈 포인터 이상 을 던 졌 고 하위 클래스 는 Exception 이상 을 던 졌 습 니 다. 그러면 하위 클래스 를 사용 하여 부모 클래스 를 교체 할 때 기 존 프로그램의 이상 캡 처 체 제 는 하위 클래스 방법 으로 던 지 는 이상 을 제어 할 수 없습니다.
//
public class Parent {
// ,
public int function(int a, int b) throws NullPointerException {
return (a + b);
}
}
//
public class Son extends Parent {
// , : Exception
@Override
public int function(int a, int b) throws Exception {
return (a - b);
}
}
// :
public class Test1 {
public static void main(String[] args) {
// 1:
Parent parent = new Parent();
try {
//
int sum = parent.function(1, 2);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
}
// :
public class Test2 {
public static void main(String[] args) {
// 1:
Son son = new Son();
try {
// ,
int sum = son.function(1, 2);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
}
반환 값 이 같 거나 축소 되 었 습 니 다. 하위 클래스 가 실현 하 는 방법 은 반환 값 유형 이 부모 클래스 와 같 거나 축소 되 어야 합 니 다.아버지 가 과일 류 가 실현 하 는 반환 치가 아버지 류 보다 크 면 자 류 는 아버지 류 를 완전히 투명 하 게 교체 할 수 없 을 것 이다.예 를 들 어 부모 클래스 의 반환 값 은 List 이 고, 하위 클래스 는 Collection 을 되 돌려 줍 니 다. 그러면 원래 프로그램 은 하위 클래스 의 반환 값 을 사용 할 수 없습니다.이때 하위 클래스 는 부모 클래스 를 완전히 투명 하 게 교체 하지 못 할 수 있 습 니 다. 즉, 하위 클래스 가 부모 클래스 를 교체 한 후에 원래 프로그램의 운행 상황 에 영향 을 줄 수 있 고 원래 방법의 사후 조건 제약 을 깨 뜨 릴 수 있 습 니 다.
//
public class Parent {
// , List
public List function() {
return new ArrayList();
}
}
//
public class Son extends Parent {
// , : Set
@Override
public Collection function(int a, int b) {
return new LinkedHashSet<>();
}
}
// :
public class Test1 {
public static void main(String[] args) {
// 1:
Parent parent = new Parent();
// 2: List
List list = parent.function();
}
}
// :
public class Test2 {
public static void main(String[] args) {
// 1:
Son son = new Son();
// 2: List , Set 。
List list = son.function();
}
}
매개 변수 가 같 습 니 다. 부모 류 의 방법 정 의 는 '규칙 계약' 을 정의 하 는 것 입 니 다. 이 기능 이나 행 위 를 실현 하려 면 반드시 만족 해 야 합 니 다.
(2) 방법 재 부팅 의 규칙: 방법 명 이 같 고 매개 변수 목록 이 다 릅 니 다 - > 매개 변수 목록 에 따라 그 방법 을 실행 합 니 다.기 존 방법의 매개 변수 범 위 는 비교적 단일 하 므 로 이 방법의 조건 수용 범 위 를 늘 려 야 하 며, 과부하 되 는 원래 방법 과 새로운 방법 이 모두 존재 하여 호출 할 수 있다.[서로 다른 조건, 서로 다른 실현]
4. 다시 싣 고 다시 쓰 는 의미?
5. 재 업로드 와 재 작성 으로 인 한 결과?
6. 왜 하위 클래스 는 부모 클래스 를 다시 불 러 올 때 선행 조건 의 확대 가 필요 합 니까?[중요 한 장면]
하위 클래스 방법 과 부모 클래스 의 방법 매개 변 수 는 다음 과 같은 세 가지 상황 이 존재 할 수 있 습 니 다.
//
public class Parent {
// , Collection
public String function(Collection coll) {
return " ";
}
}
//
public class Son extends Parent {
// , : Set
@Override
public String function(List list) {
return " ";
}
}
// :
public class Test1 {
public static void main(String[] args) {
// 1:
Parent parent = new Parent();
// 2: List
List list = new ArrayList<>();
String str = parent.function(list); //
......
// 3: Set
Set set = new LinkedHashSet<>();
String str = parent.function(set); //
}
}
// :
public class Test2 {
public static void main(String[] args) {
// 1:
Son son = new Son();
// 2: List ,
List list = new ArrayList<>();
String str = son.function(list); //
......
// 3: Set
Set set = new LinkedHashSet<>();
String str = son.function(set); //
}
}
매개 변 수 를 입력 할 때 매개 변수 범위 가 하위 클래스 방법의 범위 안에 있 으 면 하위 클래스 방법 을 실행 합 니 다.만약 에 매개 변수 범위 가 하위 클래스 방법의 범위 보다 크 고 부모 클래스 방법의 매개 변수 범위 보다 작다 면 이때 실행 하 는 것 은 부모 클래스 의 방법 이다.
따라서 하위 클래스 를 사용 하여 부모 클래스 를 교체 한 후 같은 대상 을 사용 하여 같은 방법 을 호출 하면 다른 결과 가 나온다.이때 하위 클래스 는 부모 클래스 를 완전히 투명 하 게 교체 하지 못 할 수 있 습 니 다. 즉, 하위 클래스 가 부모 클래스 를 교체 한 후에 원래 프로그램의 운행 상황 에 영향 을 줄 수 있 습 니 다.
//
public class Parent {
// , Collection
public String function(Collection coll) {
return " ";
}
}
//
public class Son extends Parent {
// , : Object
@Override
public String function(Object obj) {
return " ";
}
}
// :
public class Test1 {
public static void main(String[] args) {
// 1:
Parent parent = new Parent();
// 2: List
List list = new ArrayList<>();
String str = parent.function(list); //
......
// 3: Set
Set set = new LinkedHashSet<>();
String str = parent.function(set); //
}
}
// :
public class Test2 {
public static void main(String[] args) {
// 1:
Son son = new Son();
// 2: List ,
List list = new ArrayList<>();
String str = son.function(list); //
......
// 3: Set
Set set = new LinkedHashSet<>();
String str = son.function(set); //
}
}
이해 3: 4, 방법 재 작성 규칙
하위 클래스 에서 부모 클래스 방법 을 다시 쓸 때 하위 클래스 방법의 반환 값 이 부모 클래스 보다 크 면 하위 클래스 는 부모 클래스 를 완전히 교체 하지 못 할 수 있 습 니 다. 부모 클래스 를 교체 하면 원래 프로그램의 운행 에 영향 을 줄 수 있 습 니 다.
//
public class Parent {
// , List
public List function() {
return new ArrayList();
}
}
//
public class Son extends Parent {
// , : Set
@Override
public Collection function(int a, int b) {
return new LinkedHashSet<>();
}
}
// :
public class Test1 {
public static void main(String[] args) {
// 1:
Parent parent = new Parent();
// 2: List
List list = parent.function();
}
}
// :
public class Test2 {
public static void main(String[] args) {
// 1:
Son son = new Son();
// 2: List , Set 。
List list = son.function();
}
}
리 씨 교체 원칙 은 본질 적 으로 '자 류 는 부 류 를 교체 한 후에 원래 프로그램의 운행 상태 에 영향 을 주어 서 는 안 된다' 는 말 이다.
실제 개발 에 서 는 확장 가능 한 기능 을 달성 하기 위해 다 형 을 자주 사용한다.하위 클래스 의 기능 확장 에 있어 서 리 씨 교체 원칙 을 지 키 지 않 으 면 확 장 된 하위 클래스 를 사용 하여 기 존의 부모 클래스 를 교체 할 때 원래 프로그램의 운행 상태 에 영향 을 줄 수 있 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
디자인 모델 의 공장 모델, 단일 모델자바 는 23 가지 디자인 모델 (프로 그래 밍 사상/프로 그래 밍 방식) 이 있 습 니 다. 공장 모드 하나의 공장 류 를 만들어 같은 인 터 페 이 스 를 실현 한 일부 종 류 를 인 스 턴 스 로 만 드 는 것...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.