2014-01-20 4 views
0

에서 I 캔버스에 다른 물건을 그리 인터페이스
일반 TLIST <IMyInterface> 델파이

IImage = interface 
// another methods... 
    procedure Draw; 
end; 

의 TList를이.


TCustomImage = class(TInterfacedObject, IImage) 
    procedure Draw; virtual; abstract; 
end; 

와 자식 클래스의 몇

TSomeShape = class(TCustomImage, IImage) 
    procedure Draw(aCanvas:TCanvas); reintroduce; overload; 
end; 

TSomeAnotherShape = class(TCustomImage, IImage) 
    procedure Draw(aCanvas:TCanvas); reintroduce; overload; 
end; 

나는 다음과 같이 코드를하고자하는 부모 클래스 :

var 
    list : TList<IImage>; 
    shape : IImage; 
begin 
    try 
    list := TList<IImage>.Create; 

    list.Add(TSomeShape.Create(atSomePosition)); 
    list.Add(TSomeAnotherShape.Create(atSomePosition)); 

    // or better :) 
    for shape in list do 
     shape.Draw(Canvas); // TSomeShape and TSomeAnotherShape respectively. 

    finally 
    FreeAndNil(list); 
    end; 
end; 

UPD
올바른 클래스 (TSomeShape 또는 TSomeAnotherShape)로 list.Items[I].draw()을 사용하고 싶습니다. 그러나 지금, 나는 이것이 IImage 인터페이스로는 불가능하다는 것을 안다. 나는 IImage에 Draw(Canvas:TCanvas) 메소드를 가지고 있었지만 클래스에서 메소드를 재 도입하는 것이 합리적이라고 생각했습니다.

감사합니다. 코드를 작성해 드리겠습니다. :)

+0

실제 문제는 무엇입니까? 코드 샘플을 제공하는 것 외에는 설명 할 필요가 없습니다. –

+0

아래 해결 방법으로 해결할 수있는 경우 해당 진드기를 맞추어 허용 된 답변으로 표시하십시오. –

답변

3

문제는 인터페이스가 잘못 정의되어 있다는 것입니다. 귀하의 구체적인 클래스는이 서명 방법을 구현 :

procedure Draw(Canvas: TCanvas); 

을하지만 당신의 인터페이스는이 서명하는 방법을 정의합니다

procedure Draw; 

당신은 당신의 인터페이스와 일치하도록 구체적인 구현을 필요합니까. 다음과 같은 코드를 원할 것입니다 :

type 
    IImage = interface 
    procedure Draw(Canvas: TCanvas); 
    end; 

    TCustomImage = class(TInterfacedObject, IImage) 
    procedure Draw(Canvas: TCanvas); virtual; abstract; 
    end; 

    TSomeShape = class(TCustomImage) 
    procedure Draw(Canvas: TCanvas); override; 
    end; 

    TSomeOtherShape = class(TCustomImage) 
    procedure Draw(Canvas: TCanvas); override; 
    end; 

모든 것이 일치하고 코드가 잘 컴파일되어야하며, 원하는대로 할 수도 있습니다.


제쳐두고, try의 위치가 잘못되었습니다. 뒤에 을 배치해야 개체를 인스턴스화해야합니다. 당신이 당신의 코드를 가지고

obj := TSomeClass.Create; 
try 
    // use obj 
finally 
    obj.Free; 
end; 

쓰기, 생성자에서 예외가 finally 블록 실행으로 이어질 및 초기화되지 않은 참조에 무료로 전화를 시도합니다.