델파이의 다형성 분석
1 다형성은 무엇입니까? 2
1.1 개념 2
1.2 다형성의 의미 2
1.3 델파이에서 다형성을 구현하는 방법은 무엇입니까? 2
1.3.1 상속 2
1.3.2 가상 방법, 동적 방법 및 추상 방법, VMT/DMT, 정적 바인딩 및 동적 결합 2
1.3.3 과부하 및 다형성 2
1.4 다형성 종에 대한 토론 2
1.4.1 2 단계 다형성 2
1.4.2 안전하지 않은 다형성 2
2 VCL2에서 다형성의 응용
2.1 건축 및 파괴 방법 2
2.2 tstrings2
2.3 기타 (영혼을 추가하십시오) 2
추상적 인 다형성은 객체 지향적 인 영혼이 객체 지향적 인 기술의 열쇠 중 하나입니다.
키워드 다형성, 상속, 객체 지향, VCL, 가상 메소드, 재정의
질문
다형성은 객체 지향의 영혼이며, 다형성을 이해하는 것은 객체 지향 기술을 마스터하는 열쇠 중 하나입니다. 그러나 다형성은 정확히 무엇입니까? 다형성의 의미는 무엇입니까? 다형성을 달성하는 방법? 다형성의 개념을 이해할 수 있지만 사용 방법과 언제 사용 해야하는지 모르겠습니까? 이 기사를 자세히 읽으십시오.
전문가 분석
세계 (물체, 즉 객체)는 끊임없이 변화하고있다. 컴퓨터 언어로. 어떤 사람들은 객체 지향 프로그램을 C 언어로 작성하지만, 작문 방법은 객체 지향 (OO)의 출현이 매우 지루하다고 결론을 내립니다. 전체 소프트웨어 산업은 지구의 변화가있었습니다. 프로그래밍 언어의 변화, Smalltalk, Java, Object Pascal, C#등과 같은 일련의 객체 지향 프로그래밍 언어; VC, Delphi 및 BCB 등과 같은 지향적 인 개발 도구가 나타 났으며, VCL, .NET 프레임 워크 및 일부 상용 클래스 라이브러리와 같은 많은 우수한 클래스 라이브러리가 등장했습니다. 오리엔테이션 디자인 (OOD), 객체 지향 분석 (OOA) 및 객체 지향 데이터베이스 (OODB)), 객체 지향 기술은 전체 소프트웨어 필드에 거의 침투했으며 프로그래머의 사고 방식도 근본적인 변화를 겪었습니다! 일부 OO 정화 이론가의 눈에는 모든 것이 대상입니다! 나는이 견해에 동의하지 않지만. 그러나이 방법은 사람들의 사고 습관과 가장 일치한다고 생각합니다. 프로그래머는 비즈니스 논리에 대한 생각에 집중할 수 있으며 컴퓨터는 객체 지향 지침 (객체 지향적 인 컴파일러에 의해 완료됨)을 완료 할 수 있습니다 그때부터 뇌, 나는 해방되었다! 이것은 혁명입니다!
객체 지향의 핵심 내용은 객체, 캡슐화, 상속, 다형성 및 메시지 메커니즘은 실제 세계의 다양성을 설명하는 것입니다 마스터 다형성, 당신은 실제로 객체 지향 기술을 마스터하지 않을 것입니다.
1 다형성은 무엇입니까?
1.1 개념
다형성의 개념에 대한 여러 가지 의견이 있으며, 다음은 몇 가지 대표적인 진술입니다.
"포인터 또는 기본 클래스에 대한 참조로 둘 이상의 유형을 조작하는이 능력은 다형성으로 말합니다 (C ++ Primer, 838 페이지). 즉, 기본 클래스에 대한 포인터/참조를 사용하여 다중 클래스 (기본 클래스 및 파생 클래스)의 객체를 작동하는 기능을 다형성이라고합니다. 언어 구현의 관점에서 고려됩니다.
"다형성은 인터페이스를 구현에서 분리하는 또 다른 차원을 제공하고, 어떻게"( "Java in Java"3rd edtion)에서 무엇을 분해하기 위해, 즉 다형성은 또 다른 종류의 분리 인터페이스와 구현 (즉, "해야 할 일"및 구현을 제공합니다. ""별도의 "규모를 수행하는 방법. 설계 관점에서 고려됩니다.
"동일한 표현을 사용하여 다른 작업을 나타내는 능력을 다형성이라고합니다."(객체 지향 방법 원칙 및 연습 3 판, p. 16). 간단히 말해, 다형성은 "동일한 표현, 다른 작업"이거나 "동일한 명령, 다른 작업"이라고 말할 수 있습니다. 이것은 객체 지향적 의미의 관점에서 나온 것입니다.
세 가지 진술은 다른 관점에서 다형성의 본질을 설명합니다. 세 번째 진술은 특히 정확합니다.
이 문장의 의미를 먼저 설명하겠습니다.
동일한 표현 - 기능 호출
다른 작업 - 다른 개체에 따라 다른 작업이 있습니다.
예를 들어, 회사에는 다른 책임 (프로그래머, 영업 사원, 문서 관리자 등)이있는 다양한 직원이 있습니다. 각각의 작업을 "일하는"것으로 추상화하면 관계는 다음과 같습니다.
직원
/ |. / —— heritance 관계
프로그래머 영업 사원 문서 관리자
근무 시간이 매일 오면 다음과 같은 명령을 발행하는 것과 같습니다.
"직원. 작업 시작"(동일한 표현)
각 직원 이이 명령 (동일한 명령)을받은 후, 그는 "일하기 시작"하지만, 그들이하는 일은 각각의 작업이며, 프로그래머는 "코딩"을 시작하고 영업 사원은 "연락처 비즈니스"를 시작하고 문화 관리자가 시작하겠습니다. 문서 구성”. 즉, "동일한 표현식 (함수 호출), 다른 작업 (런타임 기간 동안 다른 객체에 따라 실행).
다형성의 언어 구현의 관점에서, 다형성은 기본 클래스 포인터 또는 파생 클래스를 가리키는 대상에 대한 참조로 가상 방법을 호출함으로써 달성된다. 다음은 객체 파스칼 언어의 구현입니다.
temployee = class // 초록 직원을 추상적 수업으로 만듭니다
공공의
절차 스타트 워크; 가상; 초록;
{추상 기능 (즉, C ++의 순수한 가상 함수)은 아무것도하지 않습니다. 실제 의미는 먼저 인터페이스를 예약하는 것입니다. 과부하는 파생 클래스에서이를 구현합니다. }
끝;
tprogramer = class (Temployee) // 프로그래머
공공의
절차 시작 작업;
끝;
tbusinessman = class (Temployee) // 영업 사원
공공의
절차 시작 작업;
끝;
tdocmanager = class (Temployee) // 텍스트 관리자
공공의
절차 시작 작업;
끝;
절차 tprogramer.startworking;
시작하다
showmessage ( '코딩');
끝;
{tbusinessman}
절차 tbusinessman.startworking;
시작하다
showmessage ( '링크 비즈니스');
끝;
{tdocmanager}
절차 tdocmanager.startworking;
시작하다
showmessage ( '문서 관리');
끝;
절차 tform1.Button1click (sender : tobject);
Const
열거 = 3;
var
직원 : Temployee의 배열;
I : 정수;
시작하다
setLength (직원, ENUM);
직원 [0] : = tprogramer.create;
// 방금 생성 된 tprogramer 객체를 가리려면 기본 클래스 직원 [0]을 참조하십시오.
직원 [1] : = tbusinessman.create;
// 방금 만든 tbusinessman 객체를 가리려면 기본 클래스 직원 [1]을 참조하십시오.
직원 [2] : = tdocmanager.create;
// 방금 생성 된 tdocmanager 객체를 가리려면 기본 클래스 직원 [2]을 참조하십시오.
i : = 0에서 길이 (직원) -1 do의 경우
직원 [i] .StartWorking; // 실행 기간 동안 실제 객체 유형에 따라 해당 방법의 동적 바인딩.
{언어 구현 다형성의 관점에서, 다형성은 기본 클래스 포인터 또는 기준 객체를 파생 클래스를 가리키면 가상 방법을 호출함으로써 구현됩니다. 직원 []는 기본 클래스 객체에 대한 배열을 말하며, 그 멤버는 각각 가상 메소드를 호출 할 때 다형성이 구현됩니다.
끝;
시도해보십시오
위의 코드 중 일부 (또는 데모 프로그램)를 입력하고 컴파일 및 실행 및 버튼을 클릭하여 다형성의 마법 효과를 볼 수 있습니다.
1.2 다형성의 의미
캡슐화와 상속의 의미는 코드 재사용을 구현하는 반면, 다형성의 의미는 인터페이스 재사용 (동일한 표현식)을 구현한다는 것입니다. 유능한. 유연성은 현실 세계를 반영 할 수 있습니다.
예를 들어, 더 나은 관리를 위해 프로그래머는 C ++ 프로그래머 및 델파이 프로그래머로 나뉩니다. …
직원
/ |. / —— heritance 관계
프로그래머 영업 사원 문서 관리자
/ / —— 단점 관계
C ++ 프로그래머 델파이 프로그래머
프로그래머가 TCPPPROGRAMER 및 TDELPHIPROGRAMER의 두 개의 파생 클래스를 추가 한 후, 호출 방법은 여전히 변경되지 않았으며 여전히 "직원, 작업을 시작했습니다.
…
setLength (직원, Enum+2);
직원 [enum] : = tcppprogramer.create;
// tcppprogramer 객체를 만들고 기본 클래스 참조 직원 [enum]을 가리 킵니다.
직원 [enum+1] : = tdelphiprogramer.create;
…
{부문. 시작}}
i : = 0에서 길이 (직원) -1 do의 경우
직원 [i] .StartWorking; // 인터페이스가 변경되지 않았기 때문에 여전히 동일합니다.
…
1.3 델파이에서 다형성을 구현하는 방법은 무엇입니까?
다형성을 달성하는 데 필요한 조건은 상속, 가상 방법, 동적 결합 (또는 지연 바인딩)입니다.
1.3.1 상속
상속은 "AKO (A is is a)" "프로그래머와 같은 클래스 간의 관계"는 "직원 인"이면적 관계를 나타냅니다. Delphi에서는 단일 상속 만 지원됩니다 (인터페이스에 의해 구현 된 다중 상속을 고려하지 않음). 이는 여러 상속의 유연성이 없으므로 큰 이점을 가져다 줄 수 있습니다. 파생 된 클래스 객체 (또는 그 반대)는 소위 "다형성 순열 원리"입니다.
힌트
UML에서 :
Ako : 일종의 수단 상속 관계
APO : 조합 관계를 나타냅니다
ISA : ISA는 대상과 그에 속하는 클래스의 관계를 나타냅니다.
1.3.2 가상 방법, 동적 방법 및 추상 방법, VMT/DMT, 정적 바인딩 및 동적 바인딩
모든 방법에 대해서는 물체에 흔적이 없습니다. 메소드 포인터 (항목 주소)는 클래스에 저장되며 실제 코드는 코드 세그먼트에 저장됩니다. 정적 메소드 (Virtual Methods)의 경우, 컴파일러는 컴파일 타임에 대한 정적 바인딩이라고하는 컴파일 시간에 객체의 참조 유형을 기준으로 객체 메소드의 입력 주소를 직접 결정합니다. 컴파일러는 속한 실제 클래스를 결정할 수 없으므로이 방법의 입력 주소는 런타임 중 VMT 테이블 입력 주소 (즉, 객체의 첫 4 바이트)를 통해서만 결정할 수 있습니다 지연 묶음).
가상 방법
가상 메소드는 상환 될 수있는 메소드를 나타내며 기본 클래스에서 기본 구현이 필요합니다. 이 클래스는 자체 가상 메소드 포인터를 저장하는 것 외에도 모든 기본 클래스의 가상 메소드 포인터를 저장합니다.
선언 방법 :
절차 메소드 이름; 가상;
이것은 델파이 컴파일러에 알리는 것과 같습니다.
이 메소드는 파생 클래스에 과부하 될 수 있으며 가상 메소드는 오버로드 후에도 여전히 발생합니다.
컴파일 기간 동안 메소드의 입력 주소를 결정하지 마십시오. 런타임 동안 방법의 입력 주소는 동적 바인딩을 통해 결정됩니다.
기본 클래스에서 기본 구현을 제공하십시오.
동적 방법
동적 메소드와 가상 방법은 본질적으로 가상 방법과 달리 동적 메소드 포인터만을 저장하므로 가상 메소드는 동적 메모리보다 더 빠릅니다. 그러나 이것은 사용자에게 완전히 투명합니다.
선언 방법 :
절차 이름; 동적;
추상 방법
기본 클래스에서 기본 구현을 제공 할 필요가없는 특수 가상 메소드는 C ++의 순수한 가상 함수와 동일한 통화 인터페이스에만 사용됩니다. 추상 방법을 포함하는 클래스를 추상 클래스라고합니다.
선언 방법 :
절차 이름; 가상; 초록;
VMT/DMT
Delphi에서 VMT (Virtual Method Table)는 실제로 다형성을 더 잘 설명하는 것이 아니며, 실제로는 논리적 인 정의를 제공합니다. 기본 클래스의 가상 방법. 객체의 처음 4 바이트에 저장된 "VMT Entry 주소"는 실제로 해당 클래스의 주소입니다 (데모 프로그램 참조). 실제 클래스에서 가상 메소드 주소를 찾을 수 있습니다.
obj (객체 이름) 실제 객체가 속한 클래스
VMT 입력 주소
데이터 구성원
클래스 가상 메소드 테이블의 VMT 입력 주소
데이터 멤버 템플릿 정보
정적 방법 등
가상 방법 (VMT)
동적 방법 (DMT)
그림 3 객체 이름, 개체 및 클래스의 관계
DMT는 VMT와 유사하며 논리적 인 개념은 클래스의 동적 메소드 포인터 만 저장되지만 기본 클래스의 동적 메소드의 주소는 없지만 속도는 저장됩니다. 가상 방법만큼 빠르지는 않습니다. 시간을 희생하고 공간을 교환하는 전략은 일반적으로 권장되지 않습니다.
설명 할 위의 예를 인용하십시오.
직원 [i] .StartWorking;
직원 [i]는 위의 프로그램에서 알 수 있듯이 TPROGRAMER 객체를 가리키거나 다른 객체 일 수 있습니다. 따라서 컴파일 중에 실제 객체를 알 수 없으므로 메소드 주소를 결정할 수 없습니다. 물론 실행 기간 동안, 나는 객체의 "진정한 얼굴"을 알고 있습니다. 호출되는 기능, 즉 다형성이 실현됩니다.
1.3.3 과부하 및 다형성
많은 Netizens는 기능 과부하가 일종의 다형성이라고 생각하지만 그렇지 않습니다. "다른 작업"의 경우 과부하가 동일한 호출 방법을 제공 할 수는 없지만 매개 변수는 다릅니다! 다형성을 구현하는 전제는 동일한 표현입니다! 예를 들어, 직원 [i] .Startworing, Overloaded Call에는 매개 변수 또는 매개 변수 유형이 다릅니다. 과부하는 언어 메커니즘 일 뿐이며 C에는 과부하가 발생하지만 C는 다형성이 없으며 C는 객체 지향 프로그래밍 언어가 아닙니다. 과부하 기능이 가상 메소드가 아닌 한, 컴파일러는 매개 변수 유형 또는 정적 바인딩에 따라 함수의 입력 주소를 결정할 수 있습니다! C ++의 아버지를 인용하십시오. "어리석지 마십시오. 동적 바인딩이 아니라면 다형성이 아닙니다."
1.4 다형성 종에 대한 토론
1.4.1 2 단계 다형성
객체 수준 : 기본 클래스 포인터/참조를 사용하여 파생 된 클래스 객체를 가리키고 가장 일반적으로 사용되는 가상 메소드 (또는 동적 메소드, 초록 메소드)를 호출하십시오.
클래스 레벨 : 클래스 참조 (객체가 아닌 클래스에 대한 참조)를 사용하여 파생 클래스를 가리키고 가상 클래스 방법 (또는 동적 클래스 방법, 추상 클래스 방법)을 호출하며 객체가 생성 한 다형성에 일반적으로 사용됩니다 (생성자는 생성자가이기 때문에 일반적으로 사용됩니다. 일종의 "특별한"유형 방법을 위해, 델파이의 구조와 파괴에 대한 다른 작업을 참조하십시오. "섹션 2.1).
힌트
클래스 참조는 클래스 자체가 아닌 클래스 또는 객체 참조의 참조 변수입니다. 객체 이름이 객체 참조를 나타내는 것처럼 클래스 이름은 클래스 참조를 나타냅니다. 델파이에서는 클래스도 객체로 처리되기 때문입니다. 클래스 참조 유형은 클래스 참조 유형이며 클래스 참조 유형의 선언 방법입니다.
클래스 참조 유형 이름 = 클래스 이름의 클래스
VCL 소스 코드에서 다음과 같은 많은 수업 참조 선언을 볼 수 있습니다.
tclass = tobject 클래스;
tcomponentclass = tcomponent의 클래스;
tcontrolclass = tcontrol의 클래스;
알아채다
클래스 메소드에서,이 메소드의 자체 내재는 객체 참조가 아니라 클래스 참조이다.
1.4.2 안전하지 않은 다형성
다형성은 또한 기본 클래스 객체에 대한 파생 클래스 포인터/참조를 사용하여 구현할 수 있습니다!
절차 tform1.btnbadpolyclick (sender : tobject);
var
CPPPROGRAMER : TCPPPROGRAMER; // CPP 프로그래머 참조 정의, 파생 클래스에 대한 참조!
시작하다
{*****************************성명******************* ******************
기본 클래스 객체에 대한 파생 클래스 포인터/참조로 구현 된 다형성. 그것은 병리학 적 다형성입니다!
이 다형성 방법은 강력한 방법으로 덮인 매우 작은 것 (기본 클래스 객체)과 같습니다.
따라서 제품 (파생 클래스 참조)의 출현은 많은 잠재적 불안 요인 (예 : 액세스 예외)을 가져옵니다.
가치가 거의 없습니다. "파일"예제는 델파이의 다형성의 본질, 다형성의 본질을 설명하는 것을 목표로합니다. 다형성의 특성 : 런타임 동안 실제 객체에 따라 객체를 작동시키기 위해 법적 (일반적으로 기본 클래스) 포인터/참조를 사용하여 다른 작업을 실행합니다. 방법 또는보다 생생한 진술 : 객체 자체는 자체 작업 방법을 결정합니다. 대상. 이를 통해 인터페이스 및 구현을 분리하여 인터페이스 재사용이 가능합니다.
***************************************************************************************** 누군가 ******* ************************************}
CPPPROGRAMER : = TCPPPROGRAMER (TPROGRAMER.CREATE);
{이 병리학 적 다형성을 달성하기 위해 객체 참조는 TCPPProgramer 유형에 시전됩니다.
따라서 컴파일러의 확인을 피합니다}
cppprogramer.startworking;
{tprogramer.startworking tcppprogramer.startworking 대신 통화되었습니다
이것은 기본 클래스 객체에 대한 파생 클래스 포인터/참조로 구현 된 다형성입니다. }
cppprogramer.free;
cppprogramer : = tcppprogramer (tdocmanager.create);
cppprogramer.startworking;
{통화는 tdocmanager.startworking입니다.
이것은 기본 클래스 객체에 대한 파생 클래스 포인터/참조로 구현 된 다형성입니다. 이 방법은 매우 안전하지 않습니다.
그리고 필요하지 않습니다}
cppprogramer.free;
끝;
시도해보십시오
이러한 종류의 다형성에 대한 이해를 얻기 위해서는이 사용 방법이 잠재적 인 불안감 (예 : 접근 예외)을 사용하는 것이 좋습니다 ? 어떤 상황에서 액세스 예외가 발생합니까? (데모 프로그램 참조)
2 VCL에서 다형성의 응용
2.1 건축 및 파괴 방법
시공 방법의 다형성
생성자는 "특수한"클래스 방법으로 간주 될 수 있으므로 TComponent의 모든 파생 클래스는 가상 클래스 방법으로 재정의되므로 생성자의 다형성을 실현하려면 Delphi에서 클래스 예제가 있습니다. 각 프로젝트 파일에는 다음과 유사한 코드가 있습니다.
application.createform (tform1, form1);
방법의 정의 :
절차 tapplication.createform (instanceClass : tcomponentClass; var 참조);
var // instanceClass는 클래스 참조입니다.
인스턴스 : tcomponent;
시작하다
인스턴스 : = tcomponent (instanceClass.newinstance);
{NewInstance 방법 선언 : 클래스 기능 NewInstance; InstanceClass는 클래스 수준 다형성을 구현하는 클래스 참조입니다. 따라서 구성 요소 생성을위한 인터페이스 재사용을 실현}}
tcomponent (참조) : = 인스턴스;
노력하다
instance.create (self); // 생성자를 호출하여 초기화하십시오
제외하고
tcomponent (참조) : = nil; // "Wild"포인터 제거! 좋은
들어올리다;
끝;
{생성 된 창이 아직 기본 양식이 없으면 방금 생성 된 양식을 기본 양식으로 설정}}
if (fmainform = nil) 및 (인스턴스는 tform)
시작하다
tform (인스턴스). handleneed;
fmainform : = tform (인스턴스); // 기본 양식을 설정합니다
{실제로 프로젝트 옵션 (프로젝트-> 옵션)에서 기본 양식을 설정하는 것은 실제로 모든 양식 작성 문 앞에 프로젝트 파일의 해당 양식 문입니다. }
끝;
끝;
2) 파괴 방법의 다형성에 대해서는 "델파이의 구조 및 파괴에 대한 분석", 섹션 3.3을 참조하십시오.
2.2 tstrings
문자열 배열 처리는 델파이 컨트롤에서 매우 일반적입니다. 일반적으로 델파이의 문자열 배열 아키텍처 설계 덕분에 일부 항목 속성이있는 일부 항목 속성이있는 일부 항목 속성이 있습니다. 이것은 성공적인 디자인입니다.
많은 컨트롤은 Combobox, TStringgrid 등과 같은 문자열 배열을 사용하지만 각 컨트롤의 문자열 배열은 다르므로 Delphi는 문자열 배열을 추상화하므로 많은 관련 클래스가 나타납니다. 기본 클래스 TSTRING은 다양한 통화에 대한 인터페이스 만 제공하므로 특정 구현은 파생 클래스에서 전적으로 구현 될 수 있으므로 TSTRINGS는 추상 클래스로 정의됩니다.
기본 클래스 TStrings 클래스의 일반적인 방법의 정의를 살펴 보겠습니다 (단위 라인 442 클래스 참조) :
tstrings = class (tpersistent)
보호
...
기능 get (Index : Integer) : String;
절차 put (색인 : 정수; const s : String);
기능 getCount : 가상;
…
공공의
함수 추가 (const s : string) : virtual;
{문자열 목록의 끝에 문자열 S를 추가}}
절차 추가 (문자열 : tstrings);
{문자열 목록 끝에 문자열 추가}
절차 삽입물 (Index : 정수; string);
{추상 방법, 인덱스 위치에 새 문자열을 삽입}}
절차가 명확합니다.
{모든 문자열을 청소}
절차 삭제 (Index : Integer);
{특정 위치에서 문자열 삭제}
함수 indexof (const s : string) : 정수;
{문자열 목록에서 S의 위치 얻기}
함수 indexofname (const name : string) : Integer;
{지정된 이름 부분을 가진 양식 이름 = 값으로 첫 번째 문자열의 위치를 반환합니다}
함수 indexofobject (aobject : tobject) : 정수;
{aobject : 문자열 목록에있는 객체로 개체의 위치를 가져옵니다}
절차로드 프롬 파일 (const filename : String);
{지정된 파일의 텍스트 줄로 목록을 채 웁니다}
절차로드 프롬 스트림 (스트림 : tstream);
{스트림에서 읽은 텍스트 줄로 목록을 채 웁니다}
절차 savetostream (stream : tstream);
{텍스트 속성의 값을 스트림 객체에 씁니다}
속성 문자열 [색인 : 정수] : 문자열 읽기 get write put;
{목록의 문자열을 해당 위치별로 참조하십시오}
속성 값 [const name : string] : 문자열 읽기 getValue write setValue;
{형식 이름 = value를 가진 문자열에서 주어진 이름과 관련된 문자열의 값 부분을 나타냅니다.}
…
끝;
TSTRINGS의 정의에서, 보호 된 대부분의 보호 및 공개 방법은 가상 방법 또는 추상적 인 방법임을 알 수 있습니다. (일부, tstringlist-> tstringgridstring을 추가하십시오)
2.3 기타 (영혼을 추가하십시오)
아직 다형성을 이해하지 못하면 다형성의 본질을 기억하십시오.
"동일한 표현, 다른 작업"(간단합니다)
OOP 언어의 구현의 관점에서, 다형성은 기본 클래스의 포인터/참조를 사용하여 (파생 된 클래스) 객체를 수행하고 실행 기간 동안 실제 객체에 따라 다른 작동 방법을 수행하는 것입니다 보다 생생한 진술 : 객체는 자체 작업 방법을 결정합니다 그 자체. 이를 통해 인터페이스 및 구현을 분리하여 인터페이스 재사용이 가능합니다.
사실, 다형성은 간단합니다! 다형성을 사용할 때 무엇에주의를 기울여야합니까? 두 가지 제안은 다음과 같습니다.
비즈니스 로직을 분석 한 다음 관련 사항을 "개체"로 추상화 한 다음 객체 방법을 사용하여 비즈니스 로직을 캡슐화하십시오. 기본 클래스에서 다형성을 가진 일부 작업을 기본 클래스에서 구현할 필요가없는 가상 추상 방법으로 선언 한 다음 파생 클래스에 과부하를 표시합니다 (오버라이드) 사용될 때 기본 클래스의 포인터는 자연스럽게 실제 세계에서 다형성을 실현합니다. 다형성을 위해 다형성을 달성하지 마십시오. 이것은 공식적인 접근법이며 의미가 없습니다.
기본 클래스와 파생 클래스간에 자연스러운 "커플 링"관계가 있기 때문에 기본 클래스를 수정하면 "전신 전신"에 도달하는 데 이어질 것입니다. 따라서 기본 클래스의 기능적 구현을 약화시키고 필요한 경우 "추상 클래스"로 설계하고 안정적인 인터페이스를 보장해야합니다.
관련 질문
델파이의 다형성에 대해 논의하십시오 : http://www.delphhibbs.com/delphhibbs/dispq.asp?lid=1753965
다형성 정보 : http://www.delphhibbs.com/delphhibbs/dispq.asp?lid=1854895
다형성이란 무엇입니까? 일일 프로그래밍에서의 용도는 무엇입니까? http://www.delphibbs.com/delphibbs/dispq.asp?lid=960465
과부하와 재정의 차이점은 무엇입니까? http://www.delphibs.com/delphibs/dispq.asp?lid=296739
파생 클래스의 포인터가 기본 클래스 객체를 가리키는 문제 http://www.delphibs.com/delphibs/dispq.asp?lid=2104106을 가리 킵니다.
(마지막 질문은 내가 다형성을 깊이 연구 할 때 Delphibbs에 대해 언급되었는데, 이로 인해 격렬한 토론을 일으켰습니다.