Squirrel 文档翻译( Class )

来源:互联网 发布:阿甘正传 知乎 编辑:程序博客网 时间:2024/06/06 03:41

Squireel实现了和C++/Java等类似的类机制,然后由于他的动态特性,在有些方面存在差异。类是第一类对象,和整型以及字符串类型一样,可以被保存在表的槽中,局部变量,数组以及传递给参数。

 

类的声明

类的对象可以通过关键字”Class“进行创建。类对象遵循表构造器同样的声明方法,只有一点不同,就是使用''作用可选的分隔符,而不是

 

例如:

class Foo {
                    //constructor
                    constructor(a)
                    {
                                         testy = ["stuff",1,2,3];
                    }
                    //member function
                    function PrintTesty()
                    {
                                         foreach(i,val in testy)
                                         {
                                                             ::print("idx = "+i+" = "+val+" /n");
                                         }
                    }
                    //property
                    testy = null;               
}
前面一个例子是下面这个例子的语法糖:
Foo <- class {
                    //constructor
                    constructor(a)
                    {
                                         testy = ["stuff",1,2,3];
                                         testy = a;
                    }
                    //member function
                    function PrintTesty()
                    {
                                         foreach(i,val in testy)
                                         {
                                                             ::print("idx = "+i+" = "+val+" /n");
                                         }
                    }
                    //property
                    testy = null;
                    
}
为了模仿命名空间,下面的例子很像:
只是两个规则嵌套的表
FakeNamespace <- {
                    Utils = {}
}
class FakeNamespace.Utils.SuperClass {
                    constructor()
                    {
                                         ::print("FakeNamespace.Utils.SuperClass")
                    }
                    function DoSomething()
                    {
                                         ::print("DoSomething()")
                    }
}
 
function FakeNamespace::Utils::SuperClass::DoSomethingElse()
{
                    ::print("FakeNamespace::Utils::SuperClass::DoSomethingElse()")
}
local testy = FakeNamespace.Utils.SuperClass();
testy.DoSomething();
testy.DoSomethingElse();
在类声明后,方法和属性可以用和表相同的方法进行添加和修改(操作符<-=)。
//添加一个新的属性
Foo.stuff <- 10;
//修改一个属性的默认值
Foo.testy = "I'm a string";
//添加一个新的方法
function Foo::DoSomething(a,b)
{
                    return a+b;
}
一个类被被实例化后,就不能再添加方法和属性了。
静态变量
Squireel的类支持静态成员变量。静态成员的变量可以被该类所有的成员共享。静态成员变量通过在变量前增加前缀”static“声明。声明体必须在类体内部。
注意: 静态变量是只读的。
class Foo {
       constructor()
                    {
                                         //..stuff
                    }
                    name = "normal variable";
                    //static variable
                    static classname = "The class name is foo";
}
类属性
类允许给他的成员关联属性。属性是元数据的一种形式,被用来存储程序的一些特定信息,比如文档字符串,IDEs的属性,代码生成器等。属性通过在类体内成员的声明前添加界定符<//>进行声明。下面是个例子:
class Foo </ test = "I'm a class level attribute" />{
                    </ test = "freakin attribute" /> //attributes of PrintTesty
                    function PrintTesty()
                    {
                                         foreach(i,val in testy)
                                         {
                                                             ::print("idx = "+i+" = "+val+" /n");
                                         }
                    }
                    </ flippy = 10 , second = [1,2,3] /> //attributes of testy
                    testy = null;
                    
}
属性实际上就是一个表,为了提高可读性,Squireel<//>语法代替花括号。
属性可以通过内置函数
classobj.getattributes(membername)读取也可以通过内置函数classobj.setattributes(membername,val)修改
下面的例子用来枚举类Foo中所有成员的属性。
foreach(member,val in Foo)
{
                    ::print(member+"/n");
                    local attr;
                    if((attr = Foo.getattributes(member)) != null) {
                                         foreach(i,v in attr)
                                         {
                                                             ::print("/t"+i+" = "+(typeof v)+"/n");
                                         }
                    }
                    else {
                                         ::print("/t<no attributes>/n")
                    }
}
类实例
类对性继承表的很多特性,但不同的是,类可以创建多个实例。类的实例是一个对象,共享类这个表的相同结构,但是拥有自己的数据。类的构造使用函数表示法。类的实例通过调用类对象进行创建。可以把类想象成一个函数,它返回一个类的实例。
//创建Foo类的一个实例
local inst = Foo(); 
当类的实例被创建时,它的成员被初始化成类中声明的值。
当类声明了一个方法
'constructor‘类的实例化槽做在创建新实例的时候会自动调用这个方法。该构造函数可以含有参数,这个会影响类实例化调用的参数个数。构造函数可以像普通函数一样可以含有可变参数(使用参数....
 
class Rect {
                    constructor(w,h)
                    {
                                         width = w;
                                         height = h;                       
                    }
                    x = 0;
                    y = 0;
                    width = null;
                    height = null;
}
 
//Rect类含有两个构造参数,所以必须调用如下
//含有两个构造参数
local rc = Rect(100,100);
在一个类的实例被创建后,他的属性可以被设置或提取,这必须遵循表的同样规则。 元方法不能被设置。
实例的成员不能被删除。
创建实例的类对象可以通过内置函数
instance.getclass()获取。
操作符instanceof用来测试一个实例是否是一个特定类对象的实例。   
local rc = Rect(100,100);
if(rc instanceof ::Rect) {
                    ::print("It's a rect");
}
else {
                    ::print("It isn't a rect");
}
继承
Squirrel通过在类声明中添加关键字
extends,跟随一个表达式支持单继承。下面是派生类语法:
class SuperFoo extends Foo {
                    function DoSomething() {
                                         ::print("I'm doing something");
                    }
}
 
当一个继承类声明了,Squireel会首先在新类中拷贝其基类的成员,然后才处理预留的声明。
继承类继承基类所有的方法和属性。如果继承类实现了基类的方法,那么基类方法的实现将会被覆盖。可以通过检索基类对象来获取一个重载函数在基类的实现。
下面是个例子:
class Foo {
                    function DoSomething() {
                                         ::print("I'm the base");
                    }
};
class SuperFoo extends Foo {
                    //overridden method
                    function DoSomething() {
                                         //calls the base method
                                         ::Foo.DoSomething();
                                         ::print("I'm doing something");
                    }
}
构造函数使用同样的规则。构造函数是个规则函数(除过在构造的时候会被自动调用)class Base {
                    constructor()
                    {
                                         ::print("Base constructor/n");
                    }
}
class Child extends Base {
                    constructor()
                    {
                                         ::Base.constructor();
                                         ::print("Child constructor/n");
                    }
}
local test = Child();
派生类的基类可以通过关键字parent获取。parent是个假槽。parent槽不能被赋值。
local thebaseclass = SuperFoo.parent;
注意:由于调用相同对象的方法时,没有特殊的保护策略,一个调用同类中方法的基类方法可能被调用派生类的方法而终止。
class Foo {
                    function DoSomething() {
                                         ::print("I'm the base");
                    }
                    function DoIt()
                    {
                                         DoSomething();
                    }
};
class SuperFoo extends Foo {
                    //overridden method
                    function DoSomething() {
                                         ::print("I'm the derived");
                                         
                    }
                    function DoIt() {
                                         ::Foo.DoIt();
                    }
}
//creates a new instance of SuperFoo
local inst = SuperFoo(); 
//prints "I'm the derived"
inst.DoIt();

 

原创粉丝点击