Я следующий беглом описания интерфейса и класса, который реализует этот интерфейс:свободный интерфейс с наследованием в Delphi
type
IDocWriter = interface
['{8CB5799A-14B1-4287-92FD-41561B237560}']
function Open: IDocWriter;
function Close: IDocWriter;
function Add(const s: string): IDocWriter;
function SaveToStream(Stream: TStream): IDocWriter;
end;
TDocWriter = class(TInterfacedObject, IDocWriter)
public
function Open: IDocWriter;
function Close: IDocWriter;
function Add(const s: string): IDocWriter;
function SaveToStream(Stream: TStream): IDocWriter;
end;
{ TDocWriter }
function TDocWriter.Open: IDocWriter;
begin
Result := Self;
// DoOpen
end;
function TDocWriter.Close: IDocWriter;
begin
Result := Self;
// DoClose
end;
function TDocWriter.Add(const s: string): IDocWriter;
begin
Result := Self;
// DoAdd
end;
function TDocWriter.SaveToStream(Stream: TStream): IDocWriter;
begin
Result := Self;
// DoSaveToStream
end;
И я могу использовать выше код следующим образом:
var
Stream: TStream;
...
TDocWriter.Create
.Open
.Add('abc')
.Close
.SaveToStream(Stream);
Я должен простираться выше интерфейс, добавив функцию SaveToString
.
Я не хочу добавлять этот метод к исходному интерфейсу IDocWriter
, потому что это недопустимый метод для всех реализаций интерфейса. Так что я сделал следующий
type
IStrDocWriter = interface(IDocWriter)
['{177A0D1A-156A-4606-B594-E6D20818CE51}']
function SaveToString: string;
end;
TStrDocWriter = class(TDocWriter, IStrDocWriter)
public
function SaveToString: string;
end;
{ TStrDocWriter }
function TStrDocWriter.SaveToString: string;
begin
Result := 'DoSaveToString';
end;
Для того, чтобы использовать IStrDocWriter
интерфейс я должен написать код
var
Writer: IDocWriter;
s: string;
Writer := TStrDocWriter.Create
.Open
.Add('abc')
.Close;
s := (Writer as IStrDocWriter).SaveToString;
Но я хотел бы, чтобы иметь возможность использовать его без необходимости объявить Writer
переменными, что-то вроде следующий код (который, разумеется, не может быть скомпилирован)
s := TStrDocWriter.Create
.Open
.Add('abc')
.Close
.SaveToString; // Undeclared identifier SaveToString
Есть ли способ достичь этого?
Любые изменения в интерфейсах и классах приемлемы (за исключением, очевидно, объединения этих двух интерфейсов в один).
Вся конструкция выглядит неправильно для меня. Свободно это просто так плохо! –
Простите мое любопытство, но есть ли этот интерфейс v. Безоговорочное требование самостоятельно или оно вытекает из фактического бизнес-требования и, если да, то как? – MartynA
@MartynA это причиняет себе причину. Интерфейсы, потому что он подсчитан и устраняет необходимость в блоках try..finally. Свободно, потому что он устраняет необходимость объявления переменных и делает код более читаемым, когда у вас длинная цепочка. Его можно использовать inline в противном случае грязный код, который вы обычно можете использовать при создании документа или отчета. Представьте себе TTextDocWriter, TRichTextDocWriter, TPdfDocWriter, TMetafileDocWriter ... –