객체 지향 3 가지 주요 특성, 코드로 3 가지 주요 특성을 설명하십시오
< /p>
OO (Object Oriented) 는 현대 소프트웨어 기술의 본질이다. 초기 SmallTalk 에서 중천인 Java 에 이르기까지 객체 지향 사상이 스며든다. < /p>
OO 에는 캡슐화, 상속 및 다형성이라는 세 가지 주요 기능이 있습니다. 객체 지향 사상을 파악하려면 < /p>
의 세 가지 주요 특징을 깊이 이해해야 한다. 여기서 나는 가능한 한 개념에 대해 적게 이야기하고, 단지 하나의 생활 속의 예와 한 단락의 코드로 그것들을 설명하려고 노력한다. < /p>
1, 캡슐화 (Encapsulation)
패키지란 외부에 직접 사용할 수 없도록 무언가를 포장하고 숨기는 것으로, 특정 방법으로만 액세스할 수 있습니다. OO 는 모든 것을 "개체" 로 간주하며 모든 개체에는 특성과 동작이 있습니다. 해당 특성을 멤버 변수 (MemberVarible) 라고 하고 해당 동작을 멤버 함수 (Member Function) 라고 하며 캡슐화된 특성은 특정 동작을 통해서만 액세스할 수 있습니다. < /p>
호텔에서 흔히 볼 수 있는 찻잎을 보셨죠. 종이봉투로 찻잎을 싸서 다시 묶는 것이 실입니다. 사용할 때는 물컵에 담가 담그면 됩니다. 이런 장점은 찻잎 찌꺼기와 티때를 가득 채우지 않는다는 것이다. < /p>
좋습니다! 이것은 패키지의 예입니다. < /p>
우리가 차를 마시는 목적은 차의 향을 즐기는 것이다. 그래서 찻잎의 맛 (Flavour) 은 찻잎이 가지고 있는 가장 < /p>
의 중요한 특징 중 하나이다. 그러나 우리는 그 맑은 향기를 직접 즐길 수 없다. 왜냐하면 바깥의 종이봉투에 의해' 포장' 되었기 때문이다. 유일한 방법은 "Dilute" 입니다. 찻주머니를 끓는 물에 던지면 그 맛이 나와서 물에 녹아들게 됩니다. (데이비드 아셀, Northern Exposure (미국 TV 드라마), 음식명언) < /p>
봉지 차를 하나의 개체로 취급하면 멤버 변수 Flavour 와 멤버 함수 Dilute
를 제공합니다. 그리고 Flavour 는 프라이빗 (Private) 이므로 직접 삼키는 것이 아니라 멤버 편지 < /p>
숫자 Dilute 를 통해서만 Flavour 를 즐길 수 있습니다. < /p>
다음은 C++ 코드로 이 예를 설명합니다.
classctea
{
private: //맛
cstring m _ color; //색상
.....//등 기타 속성
private:
voidctea (); //생성자
void ~ ctea (); //구문 분석 함수
public:
cstringdilute (); //차 만들기
.....//등 다른 방법 < /p>
}
cstringctea:: dilute () < 객체의 일부 속성을 Private 로 선언하여 숨기면 해당 객체가 제공하는 특정 < /p>
메서드를 통해서만 액세스할 수 있습니다.
< /p>
2, 상속
패키지만 하는 경우 객체 지향 언어가 아닌 언어도 부분적으로 수행할 수 있습니다. 예를 들어 C 에서는 구조 (Struct), < /p>
VB 에서 사용자 정의 유형 (Type) 을 사용하여 일부 변수를 캡슐화할 수 있습니다. < /p>
OO 의 가장 매력적인 특징은 상속이다. 일반적으로 후손이 조상의 어떤 특징을 가지고 있다는 것을 계승이라고 하는데, 물론 후손들은 자기만의 특징을 가질 수 있다. 예를 들어, 식칼. < /p>
요리칼 (cutlery) 은 강철 (Steel) 으로 만들어졌고, 강철은 금속 (Metal) 이고, 금속은 대천세계의 물질 (Substance) 이다. 따라서 식칼의 일부 특성은 물질이 가지고 있는 일반 속성으로 거슬러 올라갈 수 있다. 바로 이 이유 때문에 MFC 의 모든 클래스가 CObject 에서 상속됩니다. < /p>
이것이 상속입니다. 식칼은 강철의 특성을 직접 상속하고 강철은 금속의 특성을 상속합니다. 다음 코드는 < /p>
이 복잡하고 독특한 상속 관계를 설명합니다.
classcsubstance
< pvoidcsubstance ();
void ~ csubstance (); < /p>
// ... (나는 문과인데 구체적인 속성은 말할 수 없다)
}
classcmetal: public csubbal
void ~ c metal ();
//......
}
classcsteel: public cmetal
void ~ c steel ();
//......
}
classccutlery: public csteel
voidccutlery ();
void ~ ccutlery ();
//......
public:
voidcut (); < /p>
}
여기서 실체는 기본 클래스 (Base class) 라고 하고 나머지는 파생 클래스 (Derived class) 라고 합니다. 파생 클래스와 기본 클래스는 "Is kind of" 의 관계입니다. 하위 클래스와 해당 상위 클래스 간의 복잡한 함수 호출 관계는 이 문서에서 다루지 않습니다. < /p>
상속은 트리 계층 관계입니다. 하위 클래스는 상위 클래스의 멤버 변수 및 멤버 함수를 상속하는 동안 < /p>
자체 멤버 변수 및 멤버 함수를 정의할 수도 있습니다.
예를 들어, Metal 은 Substance 의 일반 특성을 상속하는 것 외에도 확장성과 같은 고유한 속성을 가지고 있습니다. CCutlery 는 CSteel 의 특성을 상속한 후 블레이드 (Blade), 날카로운 (Sharpness), 컷 (Cut) 등의 자체 멤버를 가지고 있습니다. < /p>
객체 지향 기술은 실생활에 대한 추상이며, 생활 속의 경험을 이용하여 프로그램 설계의 논리를 생각할 수 있다. < /p>
3, 다형성
다형성에 대해 논의하기 전에 "가상" 이 무엇인지 이해해야 합니다. C++/MFC 는 가상으로 다형성을 실현합니다. 왜 "가상" 이라는 개념은? < /p>
Class Cincect // 곤충류
{
private:
<; //발 수.....//기타 멤버 변수
private:
voidcincect ();
void ~ cincect ();
public:
void Bite ()//사람을 물다
{
...... 하지만 모든 곤충이 < /p>
사람을 물는 방법이 같은 것은 아니다. (게다가 잠자리와 같이 전혀 물지 않는 것도 있다.) 예를 들어 모기는 입으로 < /p>
빨대로 사람을 물고 개미는 입으로 끼운다. < /p>
곤충이라는 범주에서 Cant (개미), Cmosquito (모기) 라는 두 가지 범주가 파생되었다.
classcant: public cincect//개미 클래스
{
......
모기류
{
......
}
이들은 모두 Cincect 의 모든 구성원을 상속하며 물론 Bite < 도 상속합니다 이제 문제가 생겼습니다. < /p>
역시 곤충에서 물려받았는데, 우리가 Bite () 동작을 사용할 때 개미와 모기의 고유한 물린 방식을 어떻게 구분할 수 있을까요? < /p>
방법 중 하나는 "::"기호를 사용하여 특정 참조가 그 참조임을 나타내는 것이지만 이렇게 하면 유연성이 크게 상실됩니다. < /p>
또 다른 방법은 "가상" 입니다. 키워드 virtual 을 사용하여 Bite () 를 가상 함수로 선언한 다음 각 < /p>
파생 클래스에서 재정의하여 각각의 물린 메서드를 설명하면 호출 시 결과가 나타나지 않습니다.
따라서 위의 예는 < /p>
Class Cincect // 곤충류
{
private:
로 덮어쓸 수 있습니다 //발 수.....//기타 멤버 변수
private:
voidcincect ();
void ~ cincect ();
public:
virtual bite () {}//사람을 물지만 이 멤버 함수만 선언합니다.
/ 파생 클래스가 스스로 < /p>
// 각자의 물린 방법 정의
}
classcant: public cincect//개미 클래스 < /p>
} p >
cant:: bite ()
{
.....//개미별 P >
클래스 c mosquito: public CIN cect//모기류
{
......
< /p>
}
c mosquito:: bite () < /p>
{
..../ < /p>
이것은 객체 지향 특징 3: 다형성입니다. 기본 클래스의 동일한 멤버는 서로 다른 파생 클래스에서 < /p>
< P > 다른 형태를 가질 수 있으므로 큰 천세계의 많은 "객체" 를 더 잘 추상화하고 설명할 수 있습니다. 1. 다형성 이해 < /p>
2. 가상 방법 정의 방법 < /p>
3. 가상 방법 다시 로드 방법 < /p>
4. 프로그램에서 다형성을 사용하는 방법
런타임에 기본 클래스에 대한 포인터를 통해 파생 클래스를 구현하는 메서드를 호출할 수 있습니다. 객체 그룹을 배열에 배치한 다음 해당 메서드를 호출할 수 있습니다. 이 경우 다형성이 반영되며 동일한 유형의 객체가 아니어도 됩니다. 물론, 만약 그것들이 모두 어떤 클래스에서 상속된다면, 너는 이 파생 클래스들을 모두 하나의 배열에 넣을 수 있다. 이들 객체에 모두 같은 이름의 메서드가 있는 경우 각 객체에 대해 같은 이름의 메서드를 호출할 수 있습니다. 이 단원에서는 이러한 작업을 완료하는 방법을 소개합니다.< /p>
1. 목록 9-1. 가상 메서드가 있는 기본 클래스: drawingobject.cs
using system;
public classdrawing object
{
public virtual void draw () < /p>
}
}
설명 < /p>
listing 9-1 은 DrawingObject 클래스를 정의합니다. 이것은 다른 객체가 상속할 수 있는 기본 클래스입니다. 이 클래스에는 Draw () 라는 메서드가 있습니다. Draw () 메서드에는 기본 클래스의 파생 클래스가 메서드를 다시 로드할 수 있음을 나타내는 virtual 수정자가 있습니다. DrawingObject 클래스의 Draw () 메서드는 다음과 같은 작업을 수행합니다. 출력 문 "I'm just a generic drawing object." 를 콘솔에 출력합니다. < /p>
2. listing 9-2. 오버로드 메소드가 있는 파생 클래스: Line.cs, Circle.cs, and square.cs
us
public classline: drawing object
{
public override void draw (
}
}
public classcircle: drawing object
}
}
public classsquare: drawing object
< /p>
}
}
설명 < /p>
listing 9-2 는 세 가지 클래스를 정의합니다. 세 클래스 모두 DrawingObject 클래스에서 파생됩니다. 각 클래스에는 동일한 이름의 Draw () 메서드가 있으며, 이러한 Draw () 메서드 각각에는 오버로드 수정자가 있습니다. 다시 로드 수정자를 사용하면 기본 클래스 유형의 포인터 변수를 통해 클래스를 참조하는 경우 런타임에 기본 클래스의 가상 메서드를 다시 로드할 수 있습니다.
< /p>
3. 목록 9-3. 다형성을 구현하는 프로그램: drawdemo.cs
using system;
public classdraw demo
{
public static int main (string [] an)
dobj [0] = new line ();
dobj [1] = new circle ();
dobj [2] = new square ();
dobj [3] = new drawingobject ();
foreach (drawing object drawobj in dobj)
{
drawobj.draw >
}
복귀 0; < /p>
}
}
설명 < /p>
listing 9-3 은 listing 9-1 과 listing 을 사용하는 다형성의 구현을 보여준다 DrawDemo 클래스의 Main () 메서드에서 DrawingObject 클래스의 객체인 배열을 만듭니다. DObj 라는 이 배열은 네 가지 DrawingObject 유형의 객체로 구성됩니다. < /p>
다음으로 dObj 배열을 초기화합니다. Line, Circle 및 Square 클래스는 모두 DrawingObject 클래스의 파생 클래스이므로 dObj 배열 요소의 유형으로 사용할 수 있습니다. C# 에 이런 기능이 없다면 각 클래스에 대한 배열을 만들어야 합니다. 상속된 특성을 사용하면 파생 객체를 기본 클래스 멤버처럼 사용할 수 있으므로 프로그래밍 작업량을 줄일 수 있습니다. < /p>
배열이 초기화된 후 foreach 루프를 실행하여 배열의 각 요소를 찾습니다. 각 루프에서 dObj 배열의 각 요소 (객체) 는 Draw () 메서드를 호출합니다. 다형성은 런타임 시 각 객체의 Draw () 메서드를 개별적으로 호출한다는 것입니다. DObj 배열의 참조 객체 유형은 DrawingObject 이지만 파생 클래스가 DrawingObject 클래스를 다시 로드하는 가상 메서드인 Draw () 에는 영향을 주지 않습니다. DObj 배열에서는 DrawingObject 기본 클래스에 대한 포인터를 통해 파생 클래스에서 오버로드된 Draw () 메서드를 호출합니다. < /p>
결과는
I' m a line.
I' m a circle.
입니다 마지막 줄에서는 DrawingObject 클래스의 가상 메서드인 Draw () 가 실행됩니다. 이는 끝까지 배열의 네 번째 요소가 DrawingObject 클래스의 객체이기 때문입니다. < /p>
요약 < /p>
다형성에 대해 알고 나면 파생 클래스에서 기본 클래스 가상 메서드를 다시 로드하는 방법을 구현할 수 있습니다. 가상 메서드와 오버로드된 파생 클래스 메서드 간의 관계는 C# 의 다형성을 반영합니다. < /p >