MantisBT - Ecere SDK
View Issue Details
0000514Ecere SDKcompilerpublic2010-07-28 15:162013-09-18 08:23
jerome 
 
highfeaturehave not tried
newopen 
 
0.46 eC II 
0000514: Support for Interface Constructs
We need support for Java-like interface constructs to compensate for eC's lack of multiple inheritance.

Some common use cases:

- Inheriting from another class + a Window
- Controllers
Topic about MI and interfaces on the forums:
http://www.ecere.com/forums/viewtopic.php?f=1&t=209 [^]
No tags attached.
Issue History
2010-07-28 15:16jeromeNew Issue
2010-07-29 15:29jeromeRelationship addedchild of 0000431
2012-03-08 16:51redjTarget Version => 0.45 Ginkakuji
2012-03-08 21:21redjRelationship deletedchild of 0000431
2012-03-29 07:50redjCategory => eC Compiling Tools
2012-03-29 07:50redjProject@2@ => Ecere SDK
2013-09-18 06:26jeromeDescription Updated
2013-09-18 08:19jeromeNote Added: 0001068
2013-09-18 08:19jeromeTarget Version0.45 Ginkakuji => 0.46 eC II
2013-09-18 08:21jeromeNote Added: 0001069
2013-09-18 08:23jeromeDescription Updated
2013-09-18 08:23jeromeAdditional Information Updated
2013-09-18 08:26jeromeNote Edited: 0001069

Notes
(0001068)
jerome   
2013-09-18 08:19   
What the syntax could look like:

public interface FinancialAccount
{
   void deposit(int amount);
   int checkout();
}

public class AtmAccount implements FinancialAccount
{
   void deposit(int amount)
   {

   }

   int checkout()
   {

   }
}

public class BankAccount implements FinancialAccount
{
   void deposit(int amount)
   {

   }

   int checkout()
   {

   }
}

void test()
{
   BankAccount ba { };
   AtmAccount aa { };
   List<FinancialAccount> services { [ aa, ba ] };

   for(s : services)
   {
      s.deposit(10);
      s.checkout();
   }
}
(0001069)
jerome   
2013-09-18 08:21   
(edited on: 2013-09-18 08:26)
When converting a class instance into an 'interface instance', the interface object must be bundled with the instance object ( something like: struct InterfaceObject { Class interface; Instance object; } )

Here's how this can be sort-of manually implemented at the moment with some extra code, giving a glimpse on what the Class system improvements and the code generation could do:

// A base class for classes implementing interfaces
public class ExtensibleClass
{
public:
   virtual Class QueryInterface(Class c);
}

// Definition of the FinancialAccountInterface
public class FinancialAccountInterface
{
   virtual void Instance::deposit(int amount);
   virtual int Instance::checkout();
}

public class AtmAccount : ExtensibleClass
{
   Class QueryInterface(Class c)
   {
      // Return the interfaces this class supports
      if(c == class(FinancialAccountInterface)) return class(AtmAccountFinancialAccountInterface);
      return null;
   }

   void deposit(int amount)
   {

   }

   int checkout()
   {

   }
}

// Present the AtmAccount methods as a FinancialAccountInterface
class AtmAccountFinancialAccountInterface : FinancialAccountInterface
{
   void deposit(int amount)
   {
      ((AtmAccount)this).deposit(amount);
   }
   int checkout()
   {
      return ((AtmAccount)this).checkout();
   }
}

public class BankAccount : ExtensibleClass
{
   Class QueryInterface(Class c)
   {
      // Return the interfaces this class supports
      if(c == class(FinancialAccountInterface)) return class(BankAccountFinancialAccountInterface);
      return null;
   }

   void deposit(int amount)
   {

   }

   int checkout()
   {

   }
}

// Present the BankAccount methods as a FinancialAccountInterface
class BankAccountFinancialAccountInterface : FinancialAccountInterface
{
   void deposit(int amount)
   {
      ((BankAccount)this).deposit(amount);
   }

   int checkout()
   {
      return ((BankAccount)this).checkout();
   }
}

public class FinancialService : ExtensibleClass
{
public:
   void deposit(int amount)
   {
      subclass(FinancialAccountInterface) faInterface = (subclass(FinancialAccountInterface))QueryInterface(class(FinancialAccountInterface));
      if(faInterface) faInterface.deposit(this, amount);
   }

   int checkout()
   {
      subclass(FinancialAccountInterface) faInterface = (subclass(FinancialAccountInterface))QueryInterface(class(FinancialAccountInterface));
      return faInterface ? faInterface.checkout(this) : 0;
   }

   // Accept any ExtensibleClass object (They may implement the interface)
   property ExtensibleClass { }
}

void test()
{
   BankAccount ba { };
   AtmAccount aa { };
   List<FinancialService> services { [ aa, ba ] };

   for(s : services)
   {
      s.deposit(10);
      s.checkout();
   }
}