[Pas2js] Interface implementation idea
warleyalex
warleyalex at yahoo.com.br
Wed Jan 17 18:56:51 CET 2018
Since Pas2JS does not have support for Interface yet. At the moment, I'm
having a look for alternatives, the DWScript supports interface directly,
the compiler emittes AsInterface and InterfaceAsClass functions.
unit uAnimais;interfacetype ISerVivo = interface procedure Respira;
procedure AlimentaSe; end; IAnimal = interface(ISerVivo) procedure
LocomoverSe; end; ICachorro = interface(IAnimal) procedure Latir; end;
IBoi = interface(IAnimal) procedure Mugir; end; TSerVivo = class
abstract(ISerVivo) public procedure Respira; virtual; abstract;
procedure AlimentaSe; virtual; abstract; end; TAnimal = class
abstract(TSerVivo, IAnimal) public procedure LocomoverSe; virtual;
abstract; end; TCachorro = class(TAnimal, ICachorro) public
//implementação de ISerVivo procedure Respira;
override; procedure AlimentaSe; override;
//implementação de IAnimal procedure LocomoverSe; override;
//implementação de Icachorro procedure Latir; virtual;
end; TBoi = class(TAnimal, IBoi) public //implementação
de ISerVivo procedure Respira; override; procedure AlimentaSe;
override; //implementação de IAnimal procedure
LocomoverSe; override; //implementação de Iboi
procedure Mugir; virtual; end;implementation{ TBoi }procedure
TBoi.AlimentaSe;begin console.log('Comendo Capim');end;procedure
TBoi.LocomoverSe;begin console.log('Boi Andando pesadamente');end;procedure
TBoi.Mugir;begin console.log('Muuuuuuuuuuuuuuuuuu');end;procedure
TBoi.Respira;begin console.log('Boi Respirando');end;{ TCachorro }procedure
TCachorro.AlimentaSe;begin console.log('Comendo
Ração');end;procedure TCachorro.Latir;begin console.log('Au
Au');end;procedure TCachorro.LocomoverSe;begin console.log('Cachorro
Andando');end;procedure TCachorro.Respira;begin console.log('Cachorro
Respirando');end;end.{=====================================}/* main entry
point */var boi: IBoi; UmAnimal: IAnimal; UmSerVivo: ISerVivo;begin boi
:= TBoi.Create; //boi is Ianimal and IServivo can be converted with "as"
(boi as IServivo).AlimentaSe; // Comendo Capim (boi as
IAnimal).LocomoverSe; // Boi Andando pesadamente //boi also can be
converted directly UmAnimal := boi; UmSerVivo := boi;
UmSerVivo.AlimentaSe; // Comendo Capim UmAnimal.LocomoverSe; // Boi
Andando pesadamente
JavaScript emitted (output):
var TObject={ $ClassName: "TObject", $Parent: null, ClassName: function (s)
{ return s.$ClassName }, ClassType: function (s) { return s }, ClassParent:
function (s) { return s.$Parent }, $Init: function () {}, Create: function
(s) { return s }, Destroy: function (s) { for (var prop in s) if
(s.hasOwnProperty(prop)) delete s.prop }, Destroy$: function(s) { return
s.ClassType.Destroy(s) }, Free: function (s) { if (s!==null)
s.ClassType.Destroy(s) }}function $New(c) { var i={ClassType:c}; c.$Init(i);
return i }function $Is(o,c) { if (o===null) return false; return
$Inh(o.ClassType,c);};function InterfaceAsClass(i,c) { if (i===null) return
null; if ($Is(i.O,c)) return i.O; else throw
Exception.Create($New(Exception),"Cannot cast interface of
\""+i.O.ClassType.$ClassName+"\" to class \""+c.$ClassName+"\"");};function
$Inh(s,c) { if (s===null) return false; while ((s)&&(s!==c))
s=s.$Parent; return (s)?true:false;};function AsInterface(o,i) { if
(o===null) return null; var r = o.ClassType.Interface[i].map(function (e) {
return function () { var arg=Array.prototype.slice.call(arguments);
arg.splice(0,0,o); return e.apply(o, arg); } }); r.O = o; return r;};///
TSerVivo = class (TObject) file: uAnimaisvar TSerVivo = {
$ClassName:"TSerVivo",$Parent:TObject ,$Init:function ($) {
TObject.$Init($); } ,Destroy:TObject.Destroy
,Respira$:function($){return $.ClassType.Respira($)}
,AlimentaSe$:function($){return
$.ClassType.AlimentaSe($)}};TSerVivo.Interface={
ISerVivo:[TSerVivo.Respira,TSerVivo.AlimentaSe]}/// TAnimal = class
(TSerVivo) file: uAnimaisvar TAnimal = {
$ClassName:"TAnimal",$Parent:TSerVivo ,$Init:function ($) {
TSerVivo.$Init($); } ,Destroy:TObject.Destroy ,Respira:TSerVivo.Respira
,AlimentaSe:TSerVivo.AlimentaSe ,LocomoverSe$:function($){return
$.ClassType.LocomoverSe($)}};TAnimal.Interface={ IAnimal:
[TSerVivo.Respira,TSerVivo.AlimentaSe,TAnimal.LocomoverSe], ISerVivo:
[TSerVivo.Respira,TSerVivo.AlimentaSe]}/// TBoi = class (TAnimal) file:
uAnimaisvar TBoi = { $ClassName:"TBoi",$Parent:TAnimal ,$Init:function
($) { TAnimal.$Init($); } ,Respira:function(Self) { console.log("Boi
Respirando"); } ,AlimentaSe:function(Self) { console.log("Comendo Capim");
} ,LocomoverSe:function(Self) { console.log("Boi Andando pesadamente"); }
,Mugir:function(Self) { console.log("Muuuuuuuuuuuuuuuuuu"); }
,Destroy:TObject.Destroy ,Respira$:function($){return
$.ClassType.Respira($)} ,AlimentaSe$:function($){return
$.ClassType.AlimentaSe($)} ,LocomoverSe$:function($){return
$.ClassType.LocomoverSe($)}};TBoi.Interface={ ISerVivo:
[TBoi.Respira,TBoi.AlimentaSe], IBoi:
[TBoi.Respira,TBoi.AlimentaSe,TBoi.LocomoverSe,TBoi.Mugir], IAnimal:
[TBoi.Respira,TBoi.AlimentaSe,TBoi.LocomoverSe]}/* main entry point */var
boi = null;var UmAnimal = null;var UmSerVivo = null;boi =
AsInterface(TObject.Create($New(TBoi)),"IBoi");AsInterface(InterfaceAsClass(boi,TObject),"ISerVivo")[1]();AsInterface(InterfaceAsClass(boi,TObject),"IAnimal")[2]();UmAnimal
= boi;UmSerVivo = boi;UmSerVivo[1]();UmAnimal[2]();
--
Sent from: http://pas2js.38893.n8.nabble.com/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/pas2js/attachments/20180117/1011ad00/attachment-0001.html>
More information about the Pas2js
mailing list