2013-09-03 3 views
1

У меня есть интерфейс и соответствующий ему объект. Например ...Могу ли я использовать виртуальные абстрактные методы для наследования сопряженного объекта?

IMyInterface = interface 
    function GetSomething: WideString; 
    procedure SetSomething(const Value: WideString); 
    property Something: WideString read GetSomething write SetSomething 
    end; 

    TMyObject = class(TInterfacedObject, IMyInterface) 
    private 
    function GetSomething: WideString; 
    procedure SetSomething(const Value: WideString); 
    public 
    property Something: WideString read GetSomething write SetSomething 
    end; 

Я использую этот интерфейс, чтобы иметь возможность взаимодействовать с этим объектом через DLL.

Теперь я хотел бы, чтобы наследовать этот объект и переопределить некоторые из этих методов ...

TMyOtherObject = class(TMyObject) 
    private 
    function GetSomething: WideString; override; 
    procedure SetSomething(const Value: WideString); override; 

Только я хотел бы сделать базовые поля виртуальными и абстрактными в основном заставить ребенок наследовать их. ..

TMyObject = class(TInterfacedObject, IMyInterface) 
    private 
    function GetSomething: WideString; virtual; abstract; 
    procedure SetSomething(const Value: WideString); virtual; abstract; 

Могу ли я это сделать, и интерфейс по-прежнему работает с этими полями? И мне нужно определить его так же в интерфейсе? (Я знаю, конечно, все поля в интерфейсе уже абстрактны)

+3

Почему не пробовал компилятор самостоятельно? (учиться на практике) - Почему вы ожидаете, что это не работает? –

ответ

4

Вы действительно можете это сделать. Виртуальный метод, абстрактный или иной, может использоваться для удовлетворения контракта с интерфейсом.

Вы не можете объявить методы интерфейса virtual или abstract. Это не имеет никакого смысла, потому что virtual и abstract являются свойствами реализации, а не интерфейсом.

Наконец, вам не нужно объявлять свойство снова в объекте-реализации. Поскольку я ожидаю, что вы будете ссылаться только на эти объекты через интерфейс, он не делает повторения объявления свойства.

Вот простая программа, чтобы доказать точку:

{$APPTYPE CONSOLE} 

type 
    IMyInterface = interface 
    procedure Foo; 
    end; 

    TMyObject = class(TInterfacedObject, IMyInterface) 
    private 
    procedure Foo; virtual; abstract; 
    end; 

    TMyOtherObject = class(TMyObject) 
    private 
    procedure Foo; override; 
    end; 

procedure TMyOtherObject.Foo; 
begin 
    Writeln(ClassName); 
end; 

var 
    Intf: IMyInterface; 

begin 
    Intf := TMyOtherObject.Create; 
    Intf.Foo; 
    Readln; 
end. 
+0

Так что просто объявляйте его как обычно в интерфейсе, даже не реализуйте его в базовом сопрягаемом объекте и не отправляйте его на производные объекты для его реализации? –

+0

Вам нужно только объявить свойство в интерфейсе. Это все. Это потому, что вы будете получать доступ к объекту только через интерфейс. –

+0

Имеет смысл, любое наследование этого базового объекта в любом случае должно было бы переопределить его. Но все же хорошо знать, что я могу использовать виртуальные абстрактные методы в сопряженном объекте. –