문제

할 수 있는 방법은 다형성을 설명에서 이해하기 쉬운 방법이 있을까?

우리는 많이 찾을 수 있습 주제에 대한 정보를 인터넷에서 같은 책에 유형이 다형성.하지만 그것을 만들려고 간단으로 우리는 할 수 있습니다.

도움이 되었습니까?

해결책

이것은 내에서 온 것입니다 대답 비슷한 질문에서. 다음은 pseudo-c#/java의 다형성의 예입니다.

class Animal
{
    abstract string MakeNoise ();
}

class Cat : Animal {
    string MakeNoise () {
        return "Meow";
    }
}

class Dog : Animal {
    string MakeNoise () {
        return "Bark";
    }
}

Main () {
   Animal animal = Zoo.GetAnimal ();
   Console.WriteLine (animal.MakeNoise ());
}

Main () 메소드는 동물의 유형을 알지 못하고 Makenoise () 메소드의 특정 구현 동작에 따라 다릅니다.

다른 팁

두 개체는 다른 행동으로 동일한 메시지에 응답합니다. 발신자는 신경 쓰지 않아도됩니다.

간단한 팝 뚜껑이있는 모든 캔도 같은 방식으로 열립니다.
인간으로서, 당신은 당신이 찾을 수있는 모든 것을 열 수 있다는 것을 알고 있습니다.

열 때, 모든 캔이 같은 방식으로 행동하는 것은 아닙니다.
일부에는 견과류가 들어 있고 일부에는 튀어 나오는 가짜 뱀이 들어 있습니다.
결과는 캔이 "Canofnuts"또는 "canofsnakes"인 경우 어떤 유형의 캔에 달려 있지만,이를 여는 방법과는 관련이 없습니다. 당신은 당신이 당신이 캔을 열 수 있다는 것을 알고 있으며, 어떤 종류의 캔을 열었는지에 따라 결정된 일종의 결과를 얻을 수 있습니다.

punlelabledcan-> open (); // 견과류를 줄 수 있고 뱀을 줄 수 있습니다. 우리가 그것을 부를 때까지 우리는 모른다

Open ()에는 일반적인 반환 유형의 "내용"(또는 반환 유형이 없음)이 있으므로 Open은 항상 동일한 기능 서명을 갖습니다.

인간은 사용자/발신자입니다.
Open ()은 가상/다형성 기능입니다.
"Can"은 추상 기본 클래스입니다.
Canofnuts와 Canofsnakes는 "Can"클래스의 다형성 어린이입니다.
모든 캔을 열 수 있지만 구체적으로 하다 그리고 어떤 특정한 tye 내용물 반품은 어떤 종류의 것인지 정의됩니다.
PunlabledCan을 볼 때 아는 모든 것은 당신이 그것을 열 수 있다는 것입니다. 얼굴에 뱀을 터뜨리는 것과 같은 다른 행동은 특정 캔에 의해 결정됩니다.

다형성에 대한 가장 간단한 설명은 그 것입니다 IF/스위치 문을 줄이는 방법입니다..

또한 기존 클래스를 수정하지 않고 IF/스위치 명령문 (또는 다른 사람의 명세서)을 확장 할 수있는 이점이 있습니다.

예를 들어 고려하십시오 Stream .NET에서 클래스. 다형성이 없으면 각 메소드가 스위치 문을 구현하는 단일 대규모 클래스 일 것입니다.

public class Stream
{
    public int Read(byte[] buffer, int offset, int count)
    {
        if (this.mode == "file")
        {
            // behave like a file stream
        }
        else if (this.mode == "network")
        {
            // behave like a network stream
        }
        else // etc.
    }
}

대신 콘크리트 유형을 기반으로 구현을 자동으로 선택함으로써 런타임이보다 효율적인 방식으로 스위칭을 수행 할 수 있습니다.FileStream, NetworkStream), 예를 들어

public class FileStream : Stream
{
    public override int Read(byte[] buffer, int offset, int count)
    {
        // behave like a file stream
    }
}

public class NetworkStream : Stream
{
    public override int Read(byte[] buffer, int offset, int count)
    {
        // behave like a network stream
    }
}

폴리 : 많은
형태 : 형태 / 모양

배우 대 캐릭터 (또는 역할)

사과와 오렌지는 둘 다 과일입니다. 과일은 먹을 수 있습니다. 따라서 사과와 오렌지를 모두 먹을 수 있습니다.

키커? 당신은 그들을 다르게 먹습니다! 당신은 오렌지를 껍질을 벗기지 만 사과는 아닙니다.

따라서 구현은 다르지만 최종 결과는 동일합니다. 당신은 과일을 먹습니다.

는 경우와 같이 안내 오리와 같이 돌팔이 의사 오리할 수 있습니다 다음으로 취급 오리 어디서나 필요하신 오리입니다.

이것은 실제로 더 나은 기사입니다

다형성은 물체가 동일하게 "보이"할 수 있지만 다른 방식으로 행동 할 수있게합니다. 일반적인 예는 speak () 방법으로 동물 기본 클래스를 가져가는 것입니다. 개 서브 클래스는 껍질을 방출하는 반면 돼지 서브 클래스는 Oink를 방출합니다.

대부분의 사람들이 사용하는 5 초의 짧은 답변은 다른 개발자가 다형성을 주위에 머리를 낼 수 있도록 과부하 및 우선입니다.

동일한 구문, 다른 의미론.

그것을 설명하는 가장 간단한 방법 : 여러 종류의 물체에 적용 할 수있는 동사.

Hillel이 말했듯이 다른 모든 것은 단지 논평 일뿐입니다.

다형성은 일반적인 "부모"에 대한 지식에 의존함으로써 추상적으로 사물을 대우하고 있습니다 (동물과 같은 상속인을 개와 고양이의 부모로 생각하십시오).

예를 들어, 모든 동물은 산소를 호흡 할 수 있으며, 각각 다르게 할 수 있지만 동물이 호흡 할 수있는 산소를 제공하여 개와 고양이를 모두지지하는 시설을 설계 할 수 있습니다.

약간의 추가로, 동물은 "추상적"식별자이지만 (실제 "동물"이없고, 동물의 유형 만)이를 수행 할 수 있습니다.

다형성은 단일 유형의 위치에서 하나 이상의 유형의 값을 저장하는 것입니다.

이 질문에 대한 다른 답변의 대부분은 글을 쓰는 시점에서 실제로 다형성이 아니라 역동적 인 파견을 설명하고 있습니다.

동적 파견 다형성이 필요하지만 그 반대는 사실이 아닙니다. Java 또는 C#과 매우 유사한 언어를 상상할 수 있지만 System.object에는 구성원이 없었습니다. 값으로 무엇이든하기 전에 타입 캐스팅이 필요합니다. 이 명목 언어에서는 다형성이 있지만 반드시 가상 방법이나 다른 동적 디스패치 메커니즘이있는 것은 아닙니다.

동적 파견은 관련이지만 뚜렷한 개념이며, 대부분의 다른 답변에 충분히 설명되어 있습니다. 그러나 일반적으로 객체 지향 언어로 작동하는 방식 (첫 번째 ( 'this'또는 'self') 인수 유형을 기반으로 함수를 선택하는 것만으로 작동하는 유일한 방법은 아닙니다. 다중 발송 모든 인수의 유형에 따라 선택이 적용되는 경우에도 가능합니다.

마찬가지로, 과부하 해상도와 다중 발송은 서로의 정확한 유사체입니다. 오버로드 해상도는 정적 유형에 다중 디스패치이며 다중 발송은 다형성 위치에 저장된 런타임 유형에 적용되는 과부하 분해능입니다.

다형성은 일반적인 특성을 기반으로 세상을 상자로 나누고 주어진 상자의 항목을 이러한 공통 특성 만 사용하려고 할 때 상호 교환 가능한 것으로 처리합니다.

다형성은 치료 능력입니다 다른 마치 마치 마치 같은 그들 사이에 공유 된 정체성을 확립 한 다음 그것을 악용함으로써.

다형성은 동일한 방법이 여러 클래스에 적용될 때 얻는 것입니다. 예를 들어 문자열과 목록에는 "역"메소드가있을 수 있습니다. 두 방법 모두 동일한 이름 ( "역")을 갖습니다. 두 방법 모두 매우 유사한 작업을 수행합니다 (모든 문자를 반전 시키거나 목록의 요소 순서를 되돌립니다). 그러나 각 "역"방법의 구현은 다르고 클래스와 다릅니다. (즉, 문자열은 문자열처럼 역전되고 목록은 목록처럼 역전됩니다.)

은유를 사용하려면 프랑스 요리사 나 일본 요리사에게 "저녁 식사"라고 말할 수 있습니다. 각각은 자신의 특징적인 방식으로 "저녁 식사"를 수행합니다.

실질적인 결과는 객체를 받아들이고 "리버스"를 호출하는 "반전 엔진"을 만들 수 있다는 것입니다. 객체에 리버스 방법이있는 한 역전 엔진이 작동합니다.

요리사의 비유를 확장하려면 요리사에게 "저녁 식사"를하도록 지시하는 "웨이터 봇"을 만들 수 있습니다. 웨이터 봇은 어떤 종류의 저녁 식사를할지 알 필요가 없습니다. 요리사와 대화 할 필요조차 없습니다. 중요한 것은 "요리사"(또는 소방관, 또는 자동 판매기 또는 애완 동물 사료 디스펜서)가 "저녁 식사"하라는 말을 할 때 무엇을 해야하는지 알고 있다는 것입니다.

이것이 프로그래머로 당신을 구입하는 것은 코드 줄이 적고 유형 안전 또는 후기 바인딩입니다. 예를 들어 다음은 유형 안전 및 초기 바인딩 (내가 갈 때 제작 한 C와 같은 언어)의 예입니다.

class BankAccount {
    void SubtractMonthlyFee
}

class CheckingAccount : BankAccount {}

class SavingsAccount : BankAccount {}

AssessFee(BankAccount acct) {
    // This will work for any class derived from
    //   BankAccount; even classes that don't exist yet
    acct.SubtractMonthlyFee
}

main() {

    CheckingAccount chkAcct;
    SavingsAccount saveAcct;

    // both lines will compile, because both accounts
    //   derive from "BankAccount". If you try to pass in
    //   an object that doesn't, it won't compile, EVEN
    //   if the object has a "SubtractMonthlyFee" method.
    AssessFee(chkAcct);
    AssessFee(saveAcct);
}

다음은 유형 안전이 없지만 바인딩이 늦은 예입니다.

class DatabaseConnection {
    void ReleaseResources
}

class FileHandle {
    void ReleaseResources
}

FreeMemory(Object obj) {
    // This will work for any class that has a 
    //   "ReleaseResources" method (assuming all
    //   classes are ultimately derived from Object.
    obj.ReleaseResources
}

main() {

    DatabaseConnection dbConn;
    FileHandle fh;

    // You can pass in anything at all and it will
    //   compile just fine. But if you pass in an
    //   object that doesn't have a "ReleaseResources"
    //   method you'll get a run-time error.
    FreeMemory(dbConn);
    FreeMemory(fh);
    FreeMemory(acct); //FAIL! (but not until run-time)
}

훌륭한 예를 보려면 .NET TOSTRING () 메소드를 참조하십시오. 모든 클래스에는 모든 클래스가 객체 클래스에서 파생되기 때문에 모든 클래스가 있습니다. 그러나 각 클래스는 그 자체로 의미가있는 방식으로 tostring ()을 구현할 수 있습니다.

편집 : Simple! = Short, IMHO

다형성은 언어 기능으로, 높은 수준의 알고리즘 코드는 여러 유형의 데이터에서 변경되지 않은 작동을 허용합니다.

이는 운영이 각 데이터 유형에 대한 올바른 구현을 호출하도록함으로써 수행됩니다. OOP 컨텍스트 (이 질문의 태그에 따라) 에서도이 "올바른 구현"은 컴파일 타임 또는 런타임에 해결 될 수 있습니다 (언어가 둘 다 지원하는 경우). C ++와 같은 일부 언어에서는 런타임 다형성에 대한 컴파일러 지원 지원 (IE 가상 파견)은 OOP에만 해당되는 반면, 다른 유형의 다형성은 객체가 아닌 데이터 유형에서도 작동 할 수 있습니다 (예 : struct 또는 class 인스턴스이지만 같은 유형 일 수 있습니다 int 또는 double).

(다형성 C ++ 지지대의 유형은 내 대답에 나열되고 대조됩니다. C ++의 다형성 - 다른 언어를 프로그래밍하더라도 잠재적으로 유익합니다)

내가 시도하고 생각하는 방식은 동일하게 보이지만 인스턴스에 따라 다른 기능을 가질 수있는 것입니다. 따라서 유형을 가질 수 있습니다

interface IJobLoader

그러나 사용 방법에 따라 여전히 동일하게 보이지만 다른 기능을 가질 수 있습니다. Batchjobloader, NightlyJobloader 등에 대한 인스턴스가있을 수 있습니다

어쩌면 나는 길을 잃을 것입니다.

다형성이라는 용어는 과부하 기능에도 적용될 수 있습니다. 예를 들어,

string MyFunc(ClassA anA);
string MyFunc(ClassB aB);

다형성의 비 객체 지향 예입니다.

객체가 다른 방식으로 동일한 메시지에 응답 해야하는 능력입니다.

예를 들어, Smalltalk, Ruby, Objective-C와 같은 언어에서는 메시지를 보내면 응답합니다.

 dao  = XmlDao.createNewInstance()    #obj 1
 dao.save( data )

 dao = RdbDao.createNewnewInstance()  #obj 2
 dao.save( data )

이 예에서는 동일한 메시지에 다른 방식으로 응답했습니다 : "CreateNewinstance () 및 Save (OBJ)"

그들은 같은 메시지로 다른 방식으로 행동합니다. 위의 언어에서 클래스는 동일한 클래스 계층에 있지 않을 수도 있고 메시지에 응답하는 것으로 충분합니다.

Java, C ++, C# 등과 같은 언어에서 객체를 객체 참조에 할당하려면 인터페이스를 구현하거나 공통 클래스의 서브 클래스가되어 동일한 유형 계층을 공유해야합니다.

쉬운 .. 그리고 간단합니다.

다형성은 객체 지향 프로그래밍의 가장 중요하고 관련성이 높은 특징입니다.

그것은 그들이 어떻게하는지를 돌보지 않고 같은 방식으로 비슷한 일을 할 수있는 다른 일을 치료하는 방법입니다.

자동차, 트럭, 스케이트 보드, 비행기 등과 같이 운전하는 다양한 유형의 차량이있는 게임이 있다고 가정 해 봅시다. 모두 멈출 수 있지만 각 차량은 다른 방식으로 멈 춥니 다. 일부 차량은 기어를 아래로 이동해야 할 수도 있고 일부는 냉장 정차에 올 수 있습니다. 다형성은 당신이 이것을 할 수있게 해줍니다

foreach (Vehicle v in Game.Vehicles)
{
   v.Stop();
}

정지가 구현되는 방식은 다른 차량으로 연기되므로 프로그램이 신경 쓰지 않아도됩니다.

새 코드를 호출하기 위해 낡은 추위를 얻는 방법 일뿐입니다. 다른 사람들이 구현 해야하는 메소드 (예 - getarea)가있는 "Shape"인터페이스를 수용하는 일부 응용 프로그램을 작성합니다. 누군가가 해당 인터페이스를 구현할 수있는 새로운 whiz-bang 방법을 찾으면 이전 코드가 getarea 메소드를 통해 해당 새 코드를 호출 할 수 있습니다.

일부 유형 (예 : 자동차)의 물체가 다른 유형 (예 : 차량)과 같이 (예 : 차량) 공통 조상 (예 : 차량은 차량의 하위 유형)을 유형 계층의 한 지점에서 암시하는 능력 .

다형성은 기능을 다른 함수로 전달하는 문제에 대한 객체 지향 솔루션입니다. C에서는 할 수 있습니다

 void h() { float x=3.0; printf("%f", x); }
 void k() { int y=5; printf("%i", y); }
 void g(void (*f)()) { f(); }
 g(h);  // output 3.0
 g(k);  // output 5

C에서는 함수가 추가 매개 변수에 의존하면 상황이 복잡해집니다. 함수 h와 k가 다른 유형의 매개 변수에 의존하는 경우 곤경에 처해 있으며 캐스팅을 사용해야합니다. 해당 매개 변수를 데이터 구조에 저장하고 해당 데이터 구조에 대한 포인터를 G로 전달하여 H 또는 K로 전달합니다. H와 K는 포인터를 적절한 구조에 대한 포인터로 시전하고 데이터를 풀었다. 캐스팅 오류가 발생할 수있는 매우 지저분하고 매우 안전하지 않습니다.

 void h(void *a) { float* x=(float*)a; printf("%f",*x); }
 void k(void *a) { int* y=(int*)a; printf("%i",*y); }
 void g(void (*f)(void *a),void *a) { f(a); }
 float x=3.0;
 int y=5;
 g(h,&x); // output x
 g(k,&y); // output y

그래서 그들은 다형성을 발명했습니다. H와 K는 클래스로 홍보되고 방법에 대한 실제 함수, 매개 변수는 각 클래스 H 또는 K의 구성원 변수입니다. 기능을 전달하는 대신 원하는 기능이 포함 된 클래스 인스턴스를 전달합니다. 인스턴스에는 자체 매개 변수가 포함되어 있습니다.

class Base { virtual public void call()=0; }
class H : public Base { float x; public void call() { printf("%f",x);} } h;
class K : public Base { int y; public void call() { printf("%i",y);} } k;
void g(Base &f) { f.call(); };
h.x=3.0;
k.y=5;
g(h); // output h.x
g(k); // output k.x
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top