Інженерні нотатки TwinCAT
← Всі записи

Абстрактний клас чи інтерфейс у Structured Text

Порівняння абстрактних класів та інтерфейсів у CoDeSys/TwinCAT, детальний аналіз успадкування, перевірки типів та безпеки поліморфізму.

Це обговорення стосується саме CoDeSys, оскільки в інших реалізаціях та мовах поведінка може суттєво відрізнятися.

Інтерфейс не підтримує поля (змінні) або реалізацію логіки. Проте, якщо ви створите абстрактний клас без полів, де всі методи та властивості також є абстрактними, він стає структурно дуже схожим на інтерфейс. Проте є кілька важливих відмінностей:

1️⃣ Множинне успадкування

Клас може реалізовувати кілька інтерфейсів, але успадковувати може лише один клас.

2️⃣ Перевірка типів під час виконання (Runtime type checking)

Інтерфейси надають певні можливості перевірки типів під час виконання (наприклад, __QUERYINTERFACE для інтерфейсів, які реалізують __SYSTEM.IQueryInterface). Класи такої функціональності не мають.

3️⃣ Варіанти поліморфізму в Structured Text

Щоб повноцінно використовувати поліморфізм, вам знадобиться один із цих варіантів:

  • Інтерфейси
  • REFERENCE TO
  • POINTER TO

Серед них інтерфейси є найбезпечнішими та найзручнішими. Розглянемо їх детальніше:

3️⃣•1️⃣ Змінна типу інтерфейсу

  • Працює як звичайний об’єкт; проста у використанні.
  • Присвоювання виконується звичайним оператором :=.
  • Перевірка на NULL (порожнє значення) виконується простим порівнянням з 0.
  • Компiлятор контролює сумісність типів: присвоїти можна лише об’єкти, які реалізують цей інтерфейс (або їх нащадків).

3️⃣•2️⃣ Змінна типу REFERENCE TO клас

  • Працює як об’єкт, але має нюанси (особливо з властивостями).
  • Присвоювання здійснюється спеціальним оператором REF= (помилкове використання := може призвести до важковиявних багів).
  • Перевірка на NULL здійснюється спеціальним оператором __ISVALIDREF.
  • Компiлятор перевіряє типи: присвоїти можна лише об’єкти того ж типу або нащадків.

3️⃣•3️⃣ Змінна типу POINTER TO клас

  • Доступ до членів вимагає явного розіменування за допомогою оператора ^.
  • Присвоювання виконується через :=, але для отримання адреси об’єкта використовується оператор ADR.
  • Перевірка на NULL виконується простим порівнянням з 0.
  • Компiлятор не перевіряє типи — вказівники можна вільно перепризначати, що збільшує ризик помилок.

✅ Висновок

Якщо у вас є абстрактний клас без полів, де всі члени є абстрактними, це ідеальний кандидат для заміни на інтерфейс.

#TwinCAT #CoDeSys #StructuredText #IndustrialAutomation #OOP