PLC結構化文字(ST)——介面(Interface)

J_Sheng發表於2024-09-04

PLC Structured Text Object Oriented Programming

PLC結構化文字(ST)——介面(Interface)

介面定義

介面定義了所有類繼承介面時應遵循的語法合同。介面定義了語法合同 "是什麼" 部分,派生類定義了語法合同 "怎麼做" 部分。
介面定義了屬性、方法和事件,這些都是介面的成員。介面只包含了成員的宣告。成員的定義是派生類的責任。介面提供了派生類應遵循的標準結構。---C# 介面(Interface)|菜鳥教程

介面特點

  • 介面使得實現介面的類或結構在形式上保持一致。---C# 介面(Interface)|菜鳥教程
  • 介面本身並不實現任何功能,它只是和宣告實現該介面的物件訂立一個必須實現哪些行為的契約。---C# 介面(Interface)|菜鳥教程
  • 介面可以繼承介面,一個介面可以繼承多個不同的介面。
  • 介面成員預設是Public,也必須是Public。
  • 介面變數可以接收實現該介面型別的類的物件。

介面與抽象類區別

  • 抽象類在某種程度上與介面類似,但是,它們大多隻是用在當只有少數方法由基類宣告由派生類實現時。---C# 介面(Interface)|菜鳥教程
  • 抽象類不能直接例項化,但允許派生出具體的,具有實際功能的類。---C# 介面(Interface)|菜鳥教程
  • 抽象類的成員不一定都是抽象的,但如果有一個類的成員是抽象的,那麼這個類一定是抽象類。

Tips : 以上關於介面抽象定義、特點和區別,在IEC61131-3 PLC程式設計標準中同樣適用。

介面的實現

// 定義一個介面
INTERFACE I_StringBuilder EXTENDS __SYSTEM.IQueryInterface
// 介面的方法 Append
METHOD Append : I_StringBuilder
VAR_INPUT
	sText : STRING;
END_VAR
// 介面的方法 Clear
METHOD Clear : I_StringBuilder
VAR_INPUT
END_VAR
// 介面的方法 ToString
METHOD ToString : STRING
VAR_INPUT
END_VAR
// 功能塊 FB_StringBuilder 實現 介面 I_StringBuilder
FUNCTION_BLOCK FB_StringBuilder IMPLEMENTS I_StringBuilder
VAR
	sContent : STRING; // Store temporary strings;
END_VAR
// 新增介面方法的實現 Append
METHOD Append : I_StringBuilder
VAR_INPUT
	sText : STRING;
END_VAR
--------
sContent := CONCAT(STR1 := sContent, STR2 := sText);
Append := THIS^;
// 新增介面方法的實現 Clear
METHOD Clear : I_StringBuilder
VAR_INPUT
END_VAR
--------
sContent := '';
Clear := THIS^;
// 新增介面方法的實現 ToString
METHOD ToString : STRING
VAR_INPUT
END_VAR
--------
ToString := sContent; // return internal content

定義一個介面I_StringBuilder包含三個方法:Append(作用:在字串後面新增新字元)、Clear(作用:清空當前字串)、ToString(作用:輸出字串)。
定義一個功能塊FB_StringBuilder實現介面I_StringBuilder並給方法新增具體實現細節。

Tips : 示例介面 I_StringBuilder繼承了 __SYSTEM.IQueryInterface,其中 __SYSTEM.IQueryInterface 為系統內建介面,無其它成員,主要作用是為了可以做介面與介面的轉換或者介面與指標的轉換,所以在PLC ST OOP中一般以它作為介面的基類(最小粒度)以此派生。關於 __SYSTEM.IQueryInterface 介面詳細用法可查閱官方資料。
1.Codesys運算子__QUERYPOINTER
2.倍福線上幫助系統

使用介面實現Fluent

Main(PRG)程式中宣告FB_StringBuilderI_StringBuilder兩個物件,然後宣告sResult1sResult2用來接收結果。

PROGRAM MAIN
VAR
	// 字元拼接,輸出'Hello world'
	fbStringBuilder : FB_StringBuilder;
	iStringBuilder	: I_StringBuilder := fbStringBuilder;
	sResult1 : STRING;
	sResult2 : STRING;
	bTest : BOOL;
END_VAR

介面物件iStringBuilder在初始化時傳入的是fbStringBuilder物件。

  • 1.使用物件實現Fluent
IF bTest THEN
	// Function Block Instance
	sResult1 := fbStringBuilder.Clear()
							.Append('H')
							.Append('e')
							.Append('l')
							.Append('l')
							.Append('o')
							.Append(' ')
							.Append('W')
							.Append('o')
							.Append('r')
							.Append('l')
							.Append('d')
							.ToString();
	bTest := FALSE;
END_IF
  • 2.使用介面實現Fluent
IF bTest THEN
	// Interface 
	sResult2 := iStringBuilder.Clear()
							.Append('H')
							.Append('e')
							.Append('l')
							.Append('l')
							.Append('o')
							.Append(' ')
							.Append('W')
							.Append('o')
							.Append('r')
							.Append('l')
							.Append('d')
							.ToString();
	bTest := FALSE;
END_IF

方法Clear()Append()返回值是I_StringBuilder介面,因此可以使用“.”訪問介面內部定義的成員。
這種程式設計方式實現的方法不只這一種,還有其它方式也能實現這種效果,後續文章會有詳細介紹。

Tips : 作者喜歡稱這種程式設計方式為流式程式設計鏈式程式設計,老外習慣的叫法為" Fluent "或者" Work Flow ",具體怎麼形容看個人喜好吧。

總結

介面(Interface)是引用型別,與IEC61131-3定義的另一種型別(REFERENCE)相似,目前筆者想到的" 引用型別 "在IEC61131-3中只有兩個" 介面(INTERFACE "和" 引用(REFERENCE ",若還有其它的引用型別,歡迎大神留言討論。

相關文章