<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en" xmlns="http://www.w3.org/2005/Atom"><title>Recent posts to [OOP] Use extended interface instead of base interface as a method return object</title><link href="https://forge.codesys.com/forge/talk/Engineering/thread/ad907cfcdc/" rel="alternate"/><link href="https://forge.codesys.com/forge/talk/Engineering/thread/ad907cfcdc/feed.atom" rel="self"/><id>https://forge.codesys.com/forge/talk/Engineering/thread/ad907cfcdc/</id><updated>2020-02-27T13:49:42.350000Z</updated><subtitle>Recent posts to [OOP] Use extended interface instead of base interface as a method return object</subtitle><entry><title>[OOP] Use extended interface instead of base interface as a method return object</title><link href="https://forge.codesys.com/forge/talk/Engineering/thread/ad907cfcdc/?limit=25#a4f9" rel="alternate"/><published>2020-02-27T13:49:42.350000Z</published><updated>2020-02-27T13:49:42.350000Z</updated><author><name>Anonymous</name><uri>https://forge.codesys.com/u/*anonymous/</uri></author><id>https://forge.codesys.comf1621b88ed9914abd8a4e5102a838e4fef3d926d</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;&lt;em&gt;Originally created by:&lt;/em&gt; scott_cunningham&lt;/p&gt;
&lt;p&gt;QueryInterface can be used for two purposes: verify an object implements an interface, and cast the object.  For it to work, the object must extend __System.IQueryInterface.  Instead of remembering that all FBs must extend, I create a basic "ALL" interface that all FBs implement.&lt;/p&gt;
&lt;p&gt;For example, I had a project where I wanted collections (arrays) of objects (because QueryInterface took too much time on my embedded controller for live-time determination)...&lt;/p&gt;
&lt;p&gt;Created a base interface all object implement:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;INTERFACE&lt;/span&gt; &lt;span class="n"&gt;IAll&lt;/span&gt; &lt;span class="n"&gt;EXTENDS&lt;/span&gt; &lt;span class="n"&gt;__System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IQueryInterface&lt;/span&gt;
&lt;span class="n"&gt;PROPERTY&lt;/span&gt; &lt;span class="n"&gt;Instance&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;STRING&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Created a interface for all OD objects:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;INTERFACE&lt;/span&gt; &lt;span class="n"&gt;IOdAll&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Example object with automatic instance name!&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;attribute&lt;/span&gt; &lt;span class="s1"&gt;'reflection'&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;FUNCTION_BLOCK&lt;/span&gt; &lt;span class="n"&gt;ClassOdWord&lt;/span&gt; &lt;span class="n"&gt;IMPLEMENTS&lt;/span&gt; &lt;span class="n"&gt;IOdAll&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IAll&lt;/span&gt;
&lt;span class="n"&gt;VAR_OUTPUT&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; {&lt;/span&gt;&lt;span class="n"&gt;attribute&lt;/span&gt; &lt;span class="s1"&gt;'instance-path'&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; {&lt;/span&gt;&lt;span class="n"&gt;attribute&lt;/span&gt; &lt;span class="s1"&gt;'noinit'&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;InstanceName&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;STRING&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="k"&gt;object&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="k"&gt;full&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;automatically&lt;/span&gt;
&lt;span class="n"&gt;END_VAR&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And the collection object:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;FUNCTION_BLOCK&lt;/span&gt; &lt;span class="nv"&gt;ClassOdCollection&lt;/span&gt;
&lt;span class="nv"&gt;VAR&lt;/span&gt;
   &lt;span class="nv"&gt;Collection&lt;/span&gt;   : &lt;span class="nv"&gt;ARRAY&lt;/span&gt;[&lt;span class="mi"&gt;1&lt;/span&gt;..&lt;span class="nv"&gt;GVL_COLLECT&lt;/span&gt;.&lt;span class="nv"&gt;MAX_OBJECTS&lt;/span&gt;] &lt;span class="nv"&gt;OF&lt;/span&gt; &lt;span class="nv"&gt;IOdAll&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
   &lt;span class="nv"&gt;ObjNames&lt;/span&gt;   : &lt;span class="nv"&gt;ARRAY&lt;/span&gt;[&lt;span class="mi"&gt;1&lt;/span&gt;..&lt;span class="nv"&gt;GVL_COLLECT&lt;/span&gt;.&lt;span class="nv"&gt;MAX_OBJECTS&lt;/span&gt;] &lt;span class="nv"&gt;OF&lt;/span&gt; &lt;span class="nv"&gt;STRING&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
   &lt;span class="nv"&gt;J&lt;/span&gt;      : &lt;span class="nv"&gt;INT&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
   &lt;span class="nv"&gt;_ArrayOver&lt;/span&gt;   : &lt;span class="nv"&gt;BOOL&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
   &lt;span class="nv"&gt;_BadObj&lt;/span&gt;   : &lt;span class="nv"&gt;INT&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
   &lt;span class="nv"&gt;_DupeObj&lt;/span&gt;   : &lt;span class="nv"&gt;INT&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
   &lt;span class="nv"&gt;_OverObj&lt;/span&gt;   : &lt;span class="nv"&gt;INT&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
   &lt;span class="nv"&gt;_TotalObj&lt;/span&gt;   : &lt;span class="nv"&gt;INT&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;END_VAR&lt;/span&gt;
&lt;span class="nv"&gt;METHOD&lt;/span&gt; &lt;span class="nv"&gt;AddObject&lt;/span&gt;
&lt;span class="nv"&gt;VAR_INPUT&lt;/span&gt;
   &lt;span class="nv"&gt;Obj&lt;/span&gt;   : &lt;span class="nv"&gt;IAll&lt;/span&gt;&lt;span class="c1"&gt;; //general object&lt;/span&gt;
&lt;span class="nv"&gt;END_VAR&lt;/span&gt;
&lt;span class="nv"&gt;VAR&lt;/span&gt;
   &lt;span class="nv"&gt;Cast&lt;/span&gt;: &lt;span class="nv"&gt;IOdAll&lt;/span&gt;&lt;span class="c1"&gt;; //object for the collection&lt;/span&gt;
&lt;span class="nv"&gt;END_VAR&lt;/span&gt;
&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="nv"&gt;try&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;cast&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;object&lt;/span&gt;
&lt;span class="k"&gt;IF&lt;/span&gt; &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;__QUERYINTERFACE&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Obj&lt;/span&gt;, &lt;span class="nv"&gt;Cast&lt;/span&gt;&lt;span class="ss"&gt;))&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt;
   &lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="nv"&gt;it&lt;/span&gt; &lt;span class="nv"&gt;is&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="nv"&gt;member&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
   &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="nv"&gt;make&lt;/span&gt; &lt;span class="nv"&gt;sure&lt;/span&gt; &lt;span class="nv"&gt;haven&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t already added this object&lt;/span&gt;
   &lt;span class="k"&gt;FOR&lt;/span&gt; &lt;span class="nv"&gt;J&lt;/span&gt;:&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nv"&gt;TO&lt;/span&gt; &lt;span class="nv"&gt;_TotalObj&lt;/span&gt; &lt;span class="k"&gt;DO&lt;/span&gt;
      &lt;span class="k"&gt;IF&lt;/span&gt; &lt;span class="nv"&gt;Collection&lt;/span&gt;[&lt;span class="nv"&gt;J&lt;/span&gt;] &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;Cast&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt;
         &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="nv"&gt;object&lt;/span&gt; &lt;span class="nv"&gt;pointer&lt;/span&gt; &lt;span class="nv"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;dupe&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="nv"&gt;not&lt;/span&gt; &lt;span class="nv"&gt;add&lt;/span&gt; &lt;span class="nv"&gt;it&lt;/span&gt;
         &lt;span class="nv"&gt;_DupeObj&lt;/span&gt;:&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;_DupeObj&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
         &lt;span class="k"&gt;RETURN&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;END_IF&lt;/span&gt;
   &lt;span class="nv"&gt;END_FOR&lt;/span&gt;
   
   &lt;span class="k"&gt;IF&lt;/span&gt; &lt;span class="nv"&gt;_TotalObj&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nv"&gt;GVL_COLLECT&lt;/span&gt;.&lt;span class="nv"&gt;MAX_OBJECTS&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt;
      &lt;span class="nv"&gt;_TotalObj&lt;/span&gt;:&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;_TotalObj&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;Collection&lt;/span&gt;[&lt;span class="nv"&gt;_TotalObj&lt;/span&gt;]:&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;Cast&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;ObjNames&lt;/span&gt;[&lt;span class="nv"&gt;_TotalObj&lt;/span&gt;]:&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;Obj&lt;/span&gt;.&lt;span class="nv"&gt;Instance&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;ELSE&lt;/span&gt;
      &lt;span class="nv"&gt;_ArrayOver&lt;/span&gt;:&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;TRUE&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;_OverObj&lt;/span&gt;:&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;_OverObj&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
   &lt;span class="nv"&gt;END_IF&lt;/span&gt;
   
&lt;span class="k"&gt;ELSE&lt;/span&gt;
   &lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="nv"&gt;object&lt;/span&gt; &lt;span class="nv"&gt;was&lt;/span&gt; &lt;span class="nv"&gt;not&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="nv"&gt;member&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
   &lt;span class="nv"&gt;_BadObj&lt;/span&gt;:&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;_BadObj&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;END_IF&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Some additional discussion can be found here:  l &lt;a class="" href="http://forum.codesys.com/viewtopic.php?f=11&amp;amp;t=5908" rel="nofollow"&gt;viewtopic.php?f=11&amp;amp;t=5908&lt;/a&gt; l .&lt;/p&gt;&lt;/div&gt;</summary></entry><entry><title>[OOP] Use extended interface instead of base interface as a method return object</title><link href="https://forge.codesys.com/forge/talk/Engineering/thread/ad907cfcdc/?limit=25#1e49" rel="alternate"/><published>2020-02-27T13:49:42.216000Z</published><updated>2020-02-27T13:49:42.216000Z</updated><author><name>rickj</name><uri>https://forge.codesys.com/u/rickj/</uri></author><id>https://forge.codesys.com6ab82619ac336ecc4131b5d62a71d40d53433880</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;I am new to codesys interfaces and have only done a bit of reading.  A couple points come to mind that you may find helpful.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;IProduct is a subset of ProductTypeOne.  If I understand correctly the _QUERRYINTERFACE macro can be used to cast ProductTypeOne to IProduct.  Check help for usage.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;An object (FB) may implement multiple interfaces&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;FUNCTION_BLOCK&lt;/span&gt; &lt;span class="nv"&gt;FactoryOne&lt;/span&gt; &lt;span class="nv"&gt;IMPLEMENTS&lt;/span&gt; &lt;span class="nv"&gt;IFactory&lt;/span&gt;, &lt;span class="nv"&gt;IProduct&lt;/span&gt;
&lt;span class="nv"&gt;VAR_INPUT&lt;/span&gt;
&lt;span class="nv"&gt;END_VAR&lt;/span&gt;
&lt;span class="nv"&gt;VAR_OUTPUT&lt;/span&gt;
&lt;span class="nv"&gt;END_VAR&lt;/span&gt;
&lt;span class="nv"&gt;VAR&lt;/span&gt;
   
&lt;span class="nv"&gt;END_VAR&lt;/span&gt;
&lt;span class="nv"&gt;METHOD&lt;/span&gt; &lt;span class="nv"&gt;getProduct&lt;/span&gt; : &lt;span class="nv"&gt;IProduct&lt;/span&gt;
   &lt;span class="k"&gt;IF&lt;/span&gt; &lt;span class="nv"&gt;_QUERRYINTERFACE&lt;/span&gt; &lt;span class="ss"&gt;(&lt;/span&gt;...&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt;
      &lt;span class="nv"&gt;getProduct&lt;/span&gt; :&lt;span class="o"&gt;=&lt;/span&gt; ...&lt;span class="c1"&gt;;&lt;/span&gt;
   &lt;span class="nv"&gt;END_IF&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/div&gt;</summary></entry><entry><title>[OOP] Use extended interface instead of base interface as a method return object</title><link href="https://forge.codesys.com/forge/talk/Engineering/thread/ad907cfcdc/?limit=25#6394" rel="alternate"/><published>2020-02-27T13:49:41.998000Z</published><updated>2020-02-27T13:49:41.998000Z</updated><author><name>Anonymous</name><uri>https://forge.codesys.com/u/*anonymous/</uri></author><id>https://forge.codesys.com0f1211c26fb6a06416ff69eae85940b3788ce541</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;&lt;em&gt;Originally created by:&lt;/em&gt; scott_cunningham&lt;/p&gt;
&lt;p&gt;This code will not work:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ProductTypeOne&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;FactoryOne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getProduct&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I think for what you are trying to do, you need to look at the REFERENCE keyword.  You want to define product to be of type ProductTypeOne but have it actually be whatever the product is out of FactoryOne.&lt;/p&gt;
&lt;p&gt;Try this:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;REFERENCE&lt;/span&gt; &lt;span class="n"&gt;TO&lt;/span&gt; &lt;span class="n"&gt;ProductTypeOne&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;FactoryOne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getProduct&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;But I guess I am not understanding your use of interfaces... for me I understand it this way:&lt;/p&gt;
&lt;p&gt;ProductTypeOne implements IProduct, but that doesn't mean ProductTypeOne is an IProduct.  FBs can implement multiple interfaces, so whenever you write in code that you want to return an object IProduct, this does not mean the same as a ProductTypeOne.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;INTERFACE&lt;/span&gt; &lt;span class="n"&gt;IProduct&lt;/span&gt;
&lt;span class="k"&gt;METHOD&lt;/span&gt; &lt;span class="n"&gt;ProduceNoise&lt;/span&gt;
&lt;span class="k"&gt;METHOD&lt;/span&gt; &lt;span class="n"&gt;FlashLights&lt;/span&gt;
&lt;span class="n"&gt;INTERFACE&lt;/span&gt; &lt;span class="n"&gt;IWiFi&lt;/span&gt;
&lt;span class="k"&gt;METHOD&lt;/span&gt; &lt;span class="n"&gt;ConnectToWiFi&lt;/span&gt;
&lt;span class="n"&gt;PROPERTY&lt;/span&gt; &lt;span class="n"&gt;NeedsUpdate&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And now you make the product FB:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;FUNCTION&lt;/span&gt; &lt;span class="n"&gt;BLOCK&lt;/span&gt; &lt;span class="n"&gt;ProductTypeOne&lt;/span&gt; &lt;span class="n"&gt;IMPLEMENTS&lt;/span&gt; &lt;span class="n"&gt;IProduct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IWiFi&lt;/span&gt;
&lt;span class="k"&gt;METHOD&lt;/span&gt; &lt;span class="n"&gt;ProduceNoise&lt;/span&gt;
&lt;span class="k"&gt;METHOD&lt;/span&gt; &lt;span class="n"&gt;FlashLights&lt;/span&gt;
&lt;span class="k"&gt;METHOD&lt;/span&gt; &lt;span class="n"&gt;ConnectToWiFi&lt;/span&gt;
&lt;span class="n"&gt;PROPERTY&lt;/span&gt; &lt;span class="n"&gt;NeedsUpdate&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;So, the FB is required to have methods ProduceNoise and FlashLights, but also has other required features like a property NeedsUpdate and method ConnectToWiFi.&lt;/p&gt;
&lt;p&gt;Now you do this:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;PROGRAM&lt;/span&gt; &lt;span class="n"&gt;PLC_PRG&lt;/span&gt;
&lt;span class="n"&gt;VAR&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;Toy1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ProductTypeOne&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;Obj&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IProduct&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Toy1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;END_VAR&lt;/span&gt;
&lt;span class="n"&gt;Toy1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProduceNoise&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="k"&gt;valid&lt;/span&gt;
&lt;span class="n"&gt;Toy1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectToWiFi&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="k"&gt;valid&lt;/span&gt;
&lt;span class="n"&gt;Obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProduceNoise&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="k"&gt;valid&lt;/span&gt;
&lt;span class="n"&gt;Obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectToWiFi&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;valid&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;does&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="n"&gt;exist&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;With REFERENCE TO, you would get:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;PROGRAM&lt;/span&gt; &lt;span class="n"&gt;PLC_PRG&lt;/span&gt;
&lt;span class="n"&gt;VAR&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;Toy1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ProductTypeOne&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;Obj&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;REFERENCE&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="n"&gt;ProductTypeOne&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;END_VAR&lt;/span&gt;
&lt;span class="n"&gt;Toy1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProduceNoise&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="k"&gt;valid&lt;/span&gt;
&lt;span class="n"&gt;Toy1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectToWiFi&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="k"&gt;valid&lt;/span&gt;
&lt;span class="n"&gt;Obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProduceNoise&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="k"&gt;valid&lt;/span&gt;
&lt;span class="n"&gt;Obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectToWiFi&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="k"&gt;valid&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/div&gt;</summary></entry><entry><title>[OOP] Use extended interface instead of base interface as a method return object</title><link href="https://forge.codesys.com/forge/talk/Engineering/thread/ad907cfcdc/?limit=25#9cf8" rel="alternate"/><published>2020-02-27T13:49:41.868000Z</published><updated>2020-02-27T13:49:41.868000Z</updated><author><name>FPawlak</name><uri>https://forge.codesys.com/u/fpawlak/</uri></author><id>https://forge.codesys.com53fb582d541cd43b48b5fc68875dde773e1feb70</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;Yes, I want to return instance of object type ProductTypeOne.&lt;/p&gt;
&lt;p&gt;As long as ProductTypeOne implements IProduct, everywhere IProduct is correct also ProductTypeOne is also correct because it can be cast to IProduct.&lt;br/&gt;
So if FactoryOne implements IFactory then method getProduct should return anything what implements IProduct.&lt;br/&gt;
But in Java I can also specify that method getProduct in FactoryOne can only return object which extends ProductTypeOne (they also implements IProduct). I hope that this is also possible in Codesys.&lt;/p&gt;
&lt;p&gt;The benefit of "narrowing return type" is that later I can write without any casting&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ProductTypeOne&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;FactoryOne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getProduct&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;//instead of&lt;/span&gt;
&lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IProduct&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;FactoryOne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getProduct&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;and call on that object methods specific to ProductTypeOne&lt;/p&gt;
&lt;p&gt;My english is not so very well so maybe I haven't express correctly what I am trying to achieve.&lt;/p&gt;&lt;/div&gt;</summary></entry><entry><title>[OOP] Use extended interface instead of base interface as a method return object</title><link href="https://forge.codesys.com/forge/talk/Engineering/thread/ad907cfcdc/?limit=25#125f" rel="alternate"/><published>2020-02-27T13:49:41.735000Z</published><updated>2020-02-27T13:49:41.735000Z</updated><author><name>Anonymous</name><uri>https://forge.codesys.com/u/*anonymous/</uri></author><id>https://forge.codesys.comd3ec171abea46585e8849aeeed73bc019f98013b</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;&lt;em&gt;Originally created by:&lt;/em&gt; scott_cunningham&lt;/p&gt;
&lt;p&gt;IProduct is not the same as ProductTypeOne. Therefor the error is correct. You can return an instance of ProductTypeOne with your method (because it implements the interface and it will be cast automatically), but you cannot return the type ProductTypeOne as this is a different object. Maybe you meant to actually return the type ProductTypeOne (FBs are objects!) - but then you don't need the interface IProduct.&lt;/p&gt;
&lt;p&gt;You can do this:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;FB&lt;/span&gt; &lt;span class="n"&gt;Factory&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;VAR&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;MyProduct&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ProductTypeOne&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;END_VAR&lt;/span&gt;
&lt;span class="k"&gt;METHOD&lt;/span&gt; &lt;span class="n"&gt;getProduct&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IProduct&lt;/span&gt;
&lt;span class="n"&gt;getProduct&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyProduct&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/div&gt;</summary></entry><entry><title>[OOP] Use extended interface instead of base interface as a method return object</title><link href="https://forge.codesys.com/forge/talk/Engineering/thread/ad907cfcdc/?limit=25#f758" rel="alternate"/><published>2020-02-27T13:49:41.577000Z</published><updated>2020-02-27T13:49:41.577000Z</updated><author><name>FPawlak</name><uri>https://forge.codesys.com/u/fpawlak/</uri></author><id>https://forge.codesys.com76f5097e05dd76fc76f551cd53615c53cf9f7306</id><summary type="html">&lt;div class="markdown_content"&gt;&lt;p&gt;Hi guys,&lt;br/&gt;
I come from "Java world" so OOP is good know to me. But in codesys 3 I have some problems. I think codesys OOP is not so rich as Java and other high-level object oriented languages.&lt;/p&gt;
&lt;p&gt;I have created two base interfaces - IProduct and IFactory (with method returning instance of IProduct)&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;INTERFACE&lt;/span&gt; &lt;span class="n"&gt;IProduct&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;INTERFACE&lt;/span&gt; &lt;span class="n"&gt;IFactory&lt;/span&gt;
&lt;span class="k"&gt;METHOD&lt;/span&gt; &lt;span class="n"&gt;getProduct&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IProduct&lt;/span&gt;
&lt;span class="n"&gt;VAR_INPUT&lt;/span&gt;
&lt;span class="n"&gt;END_VAR&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And two Functions Blocks - ProductTypeOne, and FactoryOne which should return instances to ProductTypeOne&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;FUNCTION_BLOCK&lt;/span&gt; &lt;span class="n"&gt;ProductTypeOne&lt;/span&gt; &lt;span class="n"&gt;IMPLEMENTS&lt;/span&gt; &lt;span class="n"&gt;IProduct&lt;/span&gt;
&lt;span class="n"&gt;VAR_INPUT&lt;/span&gt;
&lt;span class="n"&gt;END_VAR&lt;/span&gt;
&lt;span class="n"&gt;VAR_OUTPUT&lt;/span&gt;
&lt;span class="n"&gt;END_VAR&lt;/span&gt;
&lt;span class="n"&gt;VAR&lt;/span&gt;
&lt;span class="n"&gt;END_VAR&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;FUNCTION_BLOCK&lt;/span&gt; &lt;span class="n"&gt;FactoryOne&lt;/span&gt; &lt;span class="n"&gt;IMPLEMENTS&lt;/span&gt; &lt;span class="n"&gt;IFactory&lt;/span&gt;
&lt;span class="n"&gt;VAR_INPUT&lt;/span&gt;
&lt;span class="n"&gt;END_VAR&lt;/span&gt;
&lt;span class="n"&gt;VAR_OUTPUT&lt;/span&gt;
&lt;span class="n"&gt;END_VAR&lt;/span&gt;
&lt;span class="n"&gt;VAR&lt;/span&gt;
&lt;span class="n"&gt;END_VAR&lt;/span&gt;
&lt;span class="k"&gt;METHOD&lt;/span&gt; &lt;span class="n"&gt;getProduct&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ProductTypeOne&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Unfortunately, when I try to compile this I get an error: "Interface of overridden method 'GETPRODUCT' of interface 'IFACTORY' doesn't match declaration getProduct"&lt;br/&gt;
When I change the return type to the basic one - IProduct it works. I have checked that this work in Java (method declaration with return ProductTypeOne), so maybe it is also possible to do this in Codesys.&lt;/p&gt;
&lt;p&gt;I want to mark that FactoryOne return only ProductTypeOne because I plan to use FactoryOne as a base FunctionBlock for FBs which should extends it and they should only return ProductTypeOne - eg. FB FactoryOneA, FactoryOneB,......&lt;br/&gt;
Also FactoryTwoA, FactoryTwoB,...... should return only ProcutTypeTwo and so on.&lt;/p&gt;
&lt;p&gt;I hope you can point me out how to achieve this in codesys.&lt;/p&gt;&lt;/div&gt;</summary></entry></feed>