powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Generics, Interfaces и реализация
15 сообщений из 15, страница 1 из 1
Generics, Interfaces и реализация
    #39491475
SolidSnake
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!

Строится структура приложения от интерфейсов.
Есть сложность при работе с дженериками, не понятно как инстанцировать реализацию и запихнуть её в поле.
Сделал пример:

Интерфейс:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
unit Int;

interface

uses
  System.SysUtils,
  System.Contnrs,
  System.Generics.Collections,
  System.Classes;

type

  // Интерфейсы для реализации дополнительных классов
  IFunctionalInterface = interface
    ['{72DE63BB-DA79-4FAC-8FEC-F12671B4DC52}']
    {
      Тут методы, поля.
    }
  end;

  IAnotherInterface = interface
    ['{DF9A0110-D588-45B6-8F8C-BE4F3CBE3555}']
    {
      Тут методы, поля.
    }
  end;

  // Интерфейс для главного класса
  IMainInterface = interface
    ['{D29A0190-F894-493F-BA97-564C81D49499}']
    function GetFunctional(): IFunctionalInterface;
    function GetCompGeneric(): TList<IAnotherInterface>;
    property Funtional: IFunctionalInterface read GetFunctional;
    // Здесь описывается типовой класс TList c элементами, мы не имеем представления какая будет реализация у элементов,
    // но она должна реализовывать всё, что описано в IAnotherInterface
    property CompGeneric: TList<IAnotherInterface> read GetCompGeneric;
  end;

implementation

end.


Реализация:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
unit Cls;

interface

uses
  {RTL}
  System.SysUtils,
  System.Contnrs,
  System.Generics.Collections,
  System.Classes,
  int;

type

  // Класс реализующий главный интерфейс IMainInterface
  // Этот класс - единственное, что видно снаружи модуля
  TMainClass = class(TInterfacedPersistent, IMainInterface)
  private
    FFunctional: IFunctionalInterface;
    // Поскольку реализуется интерфейс, TList идет с IAnotherInterface
    FAnotherInterface: TList<IAnotherInterface>;
    function GetFunctional(): IFunctionalInterface;
    function GetCompGeneric(): TList<IAnotherInterface>;
  public
    constructor Create();
    destructor Destroy(); override;
  end;

implementation

type

  // Реализации других интерфейсов
  TFunctionalInterface = class(TInterfacedPersistent, IFunctionalInterface)
    {
      Тут методы, поля.
    }
  end;

  TIAnotherInterface = class(TInterfacedPersistent, IAnotherInterface)
    {
      Тут методы, поля.
    }
  end;

  { MainClass }

constructor TMainClass.Create();
begin
  // Помещаем в интерфейсное поле FFunctional реализацию TFunctionalInterface
  FFunctional := TFunctionalInterface.Create();
  // Теперь надо как-то поместить реализацию в FAnotherInterface
  FAnotherInterface := TList<TIAnotherInterface>.Create();
  {
    [dcc32 Error] Cls.pas(53): E2010 Incompatible types:
    'System.Generics.Collections.TList<Int.IAnotherInterface>' and
    'System.Generics.Collections.TList<Cls.TIAnotherInterface>'
  }
end;

destructor TMainClass.Destroy();
var
  i: Integer;
begin
  (FFunctional as TFunctionalInterface).Free();
  for i := 0 to FAnotherInterface.Count - 1 do
    (FAnotherInterface.Items[i] as TObject).Free;
  (FAnotherInterface as TObject).Free();
  inherited;
end;

function TMainClass.GetFunctional(): IFunctionalInterface;
begin
  Result := FFunctional;
end;

function TMainClass.GetCompGeneric(): TList<IAnotherInterface>;
begin
  Result := FAnotherInterface;
end;

end.


Как правильно это реализовать?
Можно конечно TList объявлять в интерфейсе без указания типа элементов, чего делать не хочется.
Или писать функцию конвертирующую TList<IAnotherInterface> в TList<TIAnotherInterface>, но кажется, должен быть другой более правильный способ.
...
Рейтинг: 0 / 0
Generics, Interfaces и реализация
    #39491479
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
19.07.2017 12:18, SolidSnake пишет:
>
> Строится структура приложения от интерфейсов.

зачем?
какова цель?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Generics, Interfaces и реализация
    #39491535
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolidSnake,

Дженерики - это точно такие же типы как потомки TObject. Потомки TObject ты как будешь передавать?
...
Рейтинг: 0 / 0
Generics, Interfaces и реализация
    #39491592
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
FAnotherInterface := TList<IAnotherInterface>.Create();
FAnotherInterface.Add(TIAnotherInterface.Create());
...
Рейтинг: 0 / 0
Generics, Interfaces и реализация
    #39491593
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Использование интерфейсов без необходимости - раскладывание себе (или не дай бог тем, кто после вас будет) грабель на будущее.
...
Рейтинг: 0 / 0
Generics, Interfaces и реализация
    #39491594
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
rgreatИспользование интерфейсов без необходимости - раскладывание себе (или не дай бог тем, кто после вас будет) грабель на будущее.
о дааааа ! При воспоминании об исходниках SAS Планета меня охватывает ужас.
Там вся программа состоит из интерфейсов.
Где надо и где не надо.
Жуть
...
Рейтинг: 0 / 0
Generics, Interfaces и реализация
    #39491609
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolidSnakeКак правильно это реализовать?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
unit Int;

interface

type

  .............
  TMyList = TList<>
  // Интерфейс для главного класса
  IMainInterface = interface
    ['{D29A0190-F894-493F-BA97-564C81D49499}']
    function GetFunctional(): IFunctionalInterface;
    function GetCompGeneric(): TMyList;
    property Funtional: IFunctionalInterface read GetFunctional;
    property CompGeneric: TMyList read GetCompGeneric;
  end;
................

unit Cls;

interface

uses
  int;

type

  TMainClass = class(TInterfacedPersistent, IMainInterface)
  private
    FFunctional: IFunctionalInterface;
    FAnotherInterface: TMyList;
    function GetFunctional(): IFunctionalInterface;
    function GetCompGeneric(): TMyList;
  .............
...
Рейтинг: 0 / 0
Generics, Interfaces и реализация
    #39491626
SolidSnake
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
автор Мимопроходящийзачем?
какова цель?
Описание прототипов для классов, методы поля, которые должны быть обязательно реализованы.
Интерфейс декларирует требования к классам.
Приложение будет состоять из блоков, для некоторых интерфейсов будет доступно несколько реализаций.
Причем независимо от реализации, другие части приложения должны свободно работать с ожидаемыми полями и методами любой реализации конкретного интерфейса.

В эти самые другие части программы объект передается через интерфейс, без явного указания класса реализации и обращение к полям и методам происходит через интерфейсный слой, без приведения объекта к конкретному типу реализации (в этом месте логига не должна подстраиваться под класс реализации (такого быть не должно: если класс1 то делай одно, если класс2 то другое), наоборот, класс реализации должен предоставить всё что нужно этой части программы).

Была какая-то проблема с полноценной заменой интерфейсов на абстрактные классы, не могу вспомнить, видимо надо снова пробовать.
Но даже если заменить, то TList<T> все равно потребует точного совпадения типов, основная проблема никуда не уйдет.
X-CiteFAnotherInterface := TList<IAnotherInterface>.Create();
FAnotherInterface.Add(TIAnotherInterface.Create());Очень похоже что это оно :) Искал какое-то сложное решение, но так вполне пойдет, спасибо! (затупил, что называется).

авторПотомки TObject ты как будешь передавать?
Не понял вопрос, это не то? :
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
  TChildClass = class(TFunctionalInterface)
  
  end;

constructor TMainClass.Create();
begin
  // Помещаем в интерфейсное поле FFunctional реализацию TFunctionalInterface
  //FFunctional := TFunctionalInterface.Create();
  FFunctional := TChildClass.Create(); // Сюда подходит и любой потомок
end;



rgreatИспользование интерфейсов без необходимости - раскладывание себе (или не дай бог тем, кто после вас будет) грабель на будущее.Ну пока выглядит всё логично, я задаю минимальные ограничения для реализаций, без которых не могут работать другие блоки.
Т.е. условно блок1 внутри себя видит весь класс1, который реализует интерфейс1.
Но есть блок2, где класс1 даже не виден, туда передается интерфейс и блок2 свободно работает с тем функционалом, который обязательно должен быть реализован.
Проходит время, появляются новые реализации в виде нового класса в блоке1. Но блок2 никак не менялся и должен по прежнему работать. Если схема не сработает, вариант переписать всё в с нуля тоже доступен.
...
Рейтинг: 0 / 0
Generics, Interfaces и реализация
    #39491636
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
имхо, очередная попытка построить "обобщённый решатель абстрактных задач".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Generics, Interfaces и реализация
    #39491639
SolidSnake
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_ , так не подходит, решение уже есть - выше.
Не подходит потому как в модуле интерфейсов необходимо определить что должно быть внутри TList.
При этом, здесь не должно быть реализаций. И если мы укажем конкретный класс здесь, то снова попадаем на туже самую ситуацию из шапки.
...
Рейтинг: 0 / 0
Generics, Interfaces и реализация
    #39491654
SolidSnake
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мимопроходящийимхо, очередная попытка построить "обобщённый решатель абстрактных задач".

Обобщённый абстрактный решатель, но конкретных задач (в блоках решаются конкретные задачи).

Рабочий модуль реализации интерфейса из шапки:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
unit Cls;

interface

uses
  {RTL}
  System.SysUtils,
  System.Contnrs,
  System.Generics.Collections,
  System.Classes,
  int;

type

  // Класс реализующий главный интерфейс IMainInterface
  // Этот класс - единственное, что видно снаружи модуля
  TMainClass = class(TInterfacedPersistent, IMainInterface)
  private
    FFunctional: IFunctionalInterface;
    // Поскольку реализуется интерфейс, TList идет с IAnotherInterface
    FAnotherInterface: TList<IAnotherInterface>;
    function GetFunctional(): IFunctionalInterface;
    function GetCompGeneric(): TList<IAnotherInterface>;
  public
    constructor Create();
    destructor Destroy(); override;
  end;

implementation

type

  // Реализации других интерфейсов
  TFunctionalInterface = class(TInterfacedPersistent, IFunctionalInterface)
    {
      Тут методы, поля.
    }
  end;

  TIAnotherInterface = class(TInterfacedPersistent, IAnotherInterface)
    {
      Тут методы, поля.
    }
  end;

  { MainClass }

constructor TMainClass.Create();
begin
  // Помещаем в интерфейсное поле FFunctional реализацию TFunctionalInterface
  FFunctional := TFunctionalInterface.Create();
  // Теперь надо поместить реализацию в FAnotherInterface, создаем сперва TList
  FAnotherInterface := TList<IAnotherInterface>.Create();
  // Добавляем элемент с конкретной реализацией
  FAnotherInterface.Add(TIAnotherInterface.Create());
end;

destructor TMainClass.Destroy();
var
  i: Integer;
begin
  (FFunctional as TFunctionalInterface).Free();
  for i := 0 to FAnotherInterface.Count - 1 do
    (FAnotherInterface.Items[i] as TObject).Free;
  (FAnotherInterface as TObject).Free();
  inherited;
end;

function TMainClass.GetFunctional(): IFunctionalInterface;
begin
  Result := FFunctional;
end;

function TMainClass.GetCompGeneric(): TList<IAnotherInterface>;
begin
  Result := FAnotherInterface;
end;

end.

...
Рейтинг: 0 / 0
Generics, Interfaces и реализация
    #39491667
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
дерзайте.
до написания "всеобщей теории всего сущего" осталось рукой подать.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Generics, Interfaces и реализация
    #39491705
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне кажется можно было и классами ограничится.

авторОписание прототипов для классов, методы поля, которые должны быть обязательно реализованы.

Если сильно хочется - можно абстрактный предок создать. Либо частично либо полностью.
...
Рейтинг: 0 / 0
Generics, Interfaces и реализация
    #39491731
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТС-у пожалуй было бы невредно почитать Шлеера с Меллором - "моделирование мира в состояниях", 1993 года издания
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Generics, Interfaces и реализация
    #39491759
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolidSnakeНе подходит потому как в модуле интерфейсов необходимо определить что должно быть внутри TList.Так и не понял, почему не подходит? Я говорю, что Вам всего лишь, нужно ЯВНО определить тип TList<IAnotherInterface>
SolidSnakeПри этом, здесь не должно быть реализацийНикакой реализации и нет
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Generics, Interfaces и реализация
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]