Jump to content
Sign in to follow this  
lynkfs

inheritance

Recommended Posts

There are various object-types implemented in Smart and javascript. According to aSmartbook (4.1.6) Smart has a super-parent class 'Object' which is parent to TObject and to JObject. TObject is the ancestor for all rtl descendants and JObject is the parent for external classes.
Javascript of course has its own object structure.

I was wondering if it would be possible to derive usable components from any or all of these various object types.

Deriving a new class therefore depends on who (which object type) is going to be chosen as ancestor.

By way of demo, a TSet class is created with methods to maintain a list of values and to make it usable in Venn-diagrammatic operations (intersect, union, difference, subset etc).

TSet is implemented 3 times: as a component derived from TObject, as a component derived from a jsArray and as a component derived directly from the javascript object (jsObject).
These implementations differ internally quite a bit, but usage in a Smart app is exactly the same.

A) TSet derived from TObject

type
  TSet = class
  public
    Constructor Create; virtual;
    Procedure add(Item: Variant);
    Procedure remove(Item: Variant);
    Function  contains(Item: Variant) : boolean;
    Function  union(&Set: TSet2) : TSet2;
    Function  intersect(&Set: TSet2) : TSet2;
    Function  difference(&Set: TSet2) : TSet2;
    Function  isSubset(&Set: TSet2) : boolean;
    Function  length : integer;
    Procedure Print;
    values :  array of variant;
  end;

implementation

Constructor TSet.Create;
begin
  inherited Create;
end;

Procedure TSet.add(Item: Variant);
begin
  If values.IndexOf(Item) < 0 then
    values.add(Item);
end;

and usage 

  var set1 : TSet := TSet.Create;
  set1.add(1);
  set1.add(2);
  set1.add(3);
  set1.print(); // => 1 2 3

nothing special about this

B ) TSet derived from a javascript array (see)
Javascript has a different inheritance mechanism using prototypes.

type
  TSet = class
  public
    Constructor Create; virtual;
    Procedure add(Item: Variant);
    ...
    FHandle:  variant;
  end;

implementation

Constructor TSet.Create;
begin
  inherited Create;

asm
function Set() {
  this.values = [];
}

Set.prototype.add = function(value) {
  if(!~this.values.indexOf(value)) {
    this.values.push(value);
  }
};

  @FHandle = new Set();
end;

end;

Procedure TSet.add(Item: Variant);
begin
  FHandle.add(Item);
end; 

usage is the same.

C) TSet derived from the ultimate ancestor : jsObject

type

  TSet = class
  public
    Constructor Create; virtual;
    Procedure add(Item: Variant);
    ...
    FHandle:  variant;
  end;

implementation

Constructor TSet.Create;
begin
  inherited Create;

asm
function Set() {
  this.lastIndex = 0;
}

Set.prototype.add = function(value) {
  for (var property1 in this) {
   if (typeof this[property1] === 'number') {
     if (this[property1] == value) {
         break;
       } else {
         Object.defineProperty(this, this.lastIndex.toString() , {
           value: value,
           configurable: true,
           writable: true,
           enumerable: true
         });
         //console.log(this.lastIndex);
         this.lastIndex++;
         break;
     };
   };
  };
  //console.log(Object.getOwnPropertyNames(this));
};

  @FHandle = new Set();
end;

end;

Procedure TSet.add(Item: Variant);
begin
  FHandle.add(Item);
end;

again usage is the same

I don't think these last 2 approaches have much of a practical application, and while it works, there is no obvious advantage to stray away from TObject (and there may be hidden disadvantages as well). Curiosity kills the cat.

Project code with full implementations and demo (not much to see, uses console)


 

Share this post


Link to post
Share on other sites

Good write!

Also make sure the IE patch is included when using this code, since "array.indexOf()" doesnt exist in pre Edge browsers.
"inherited" also has no meaning when using JObject etc. because they are compiled without a VMT and are thus without inheritance in the object pascal/C++ way of thinking

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×