View Issue Details

IDProjectCategoryView StatusLast Update
0000514Ecere SDKcompilerpublic2013-09-18 08:23
Reporterjerome Assigned To 
PriorityhighSeverityfeatureReproducibilityhave not tried
Status newResolutionopen 
Target Version0.46 eC II 
Summary0000514: Support for Interface Constructs
DescriptionWe 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
Additional InformationTopic about MI and interfaces on the forums:
http://www.ecere.com/forums/viewtopic.php?f=1&t=209
TagsNo tags attached.

Activities

jerome

2013-09-18 08:19

administrator   ~0001068

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();
   }
}

jerome

2013-09-18 08:21

administrator   ~0001069

Last edited: 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();
   }
}

Issue History

Date Modified Username Field Change
2010-07-28 15:16 jerome New Issue
2012-03-08 16:51 redj Target Version => 0.45 Ginkakuji
2012-03-29 07:50 redj Category => eC Compiling Tools
2012-03-29 07:50 redj Project @2@ => Ecere SDK
2013-09-18 06:26 jerome Description Updated
2013-09-18 08:19 jerome Note Added: 0001068
2013-09-18 08:19 jerome Target Version 0.45 Ginkakuji => 0.46 eC II
2013-09-18 08:21 jerome Note Added: 0001069
2013-09-18 08:23 jerome Description Updated
2013-09-18 08:23 jerome Additional Information Updated
2013-09-18 08:26 jerome Note Edited: 0001069