发新话题
打印

[转载D语言文档] D语言基础之class

D语言基础之class

知识若不分享 实在没有意义 http://www.d-programming-language-china.org 20070427

点击下面网址查看原文:
http://www.d-programming-language-china.org

by: 燕良
from: http://blog.csdn.net/yanonsoftware/archive/2007/01/13/1481911.aspx

D语言的class不支持多继承 ,对象的实例只能使用引用类型,但是它不只是简单的一个C++的简化。D语言的class书写起来更方便,例如使用this作为构造函数的名称,对于虚函数不需要指定virtual属性,编译器会自动判断哪些函数需要列入vtabl。D语言的class在契约式编程方面提供两个方便的工具:invariant和unittest。下面是一些主要特性的演示代码。

import std.stdio;
import std.math;

void main()
{
    tryClass();
}

class MyBaseClass
{
    static float c;
    static this()    // static constructor用来初始化静态成员, 会在main()之前被调用
    {
        c = 1;
    }

    static ~this()    // 静态析构函数在程序结束时被调用
    {
        writefln("program exit");
    }

    float x;
    float y = 9;    // 可以指定默认的初始值

    this(float _x, float _y)    // 构造函数
    {
        writefln("MyBaseClass.ctor");
        x = _x;
        y = _y;
    }
    ~this()    // Destructors
    {
        writefln("MyBaseClass.dtor");
    }
}

class MySubClass : MyBaseClass    // 只能使用单继承
{
    float z;

    this(float _x, float _y, float _z)    // 构造函数
    {
        writefln("MySubClass.ctor");

        super(_x, _y);    //调用父类的构造函数
        z = _z;
    }
    ~this()    // Destructors
    {
        writefln("MySubClass.dtor");
    }

    float getLength()
    {
        return sqrt(x*x + y*y + z*z);
    }

    /**//* invariant是D语言契约(contract)式编程的一个工具,
        用来描述class固定不变的特性(characteristics);
        invariant代码在类的实例构造之后、析构之前,public函数的调用时和调用完成后被调用
        */
    invariant
    {
        assert(z*z >= 0);
        writefln("-- MySubClass.invariant");
    }

    /**//*    unittest
        使用dmd的"-unittest"命令行参数将unittest代码编译进最终的可执行文件;
        unittest代码在静态构造之后在main之前被自动调用
    */
    unittest
    {
        writefln("%% MyClassSubClass.unittest");
    }
}

// Scope
//----------------------------------
/**//*    scope类的实例必须以scope属性来声明;
    当scope类的实例离开作用域时会自动析构函数, 包括抛出异常的时候
*/
scope class MyScopeClass
{
    int a;
    int b;

    ~this()
    {
        writefln("go out of scope");
    }
}

//----------------------------------------------
void Foo()
{
    scope MyScopeClass s = new MyScopeClass;
}

void tryClass()
{
    // 类的实例都是引用类型,使用new操作符创建
    MyBaseClass m = new MyBaseClass(1,2);

    // Field Properties
    //----------------------------
     m.x = 100; // field都使用“.”来引用,不再需要::和->
     writefln("offset of y = ", m.y.offsetof);

     // tupleof
     m.tupleof[0] = 99;    // m.x
     m.tupleof[1] = 98;    // m.y

     foreach(float e;m.tupleof)
         writef(e,", ");
     writefln();

     //  如果一个类没有指明基类,则是从Object派生的
     writefln(m.toString());    // 调用Object方法

     MySubClass s = new MySubClass(1,2,3);
     writefln("call MySubClass.getLength()");
     float length =    s.getLength();
     writefln("length = ", length);

     assert(s); // 手动调用invariant

     // Scope class
     Foo();

}

D语言论坛 http://www.d-programming-language-china.org 补充:

上面代码输出信息如下:

QUOTE:
MyBaseClass.ctor
offset of y = 12
99, 98,
test.MyBaseClass
MySubClass.ctor
MyBaseClass.ctor
-- MySubClass.invariant
call MySubClass.getLength()
-- MySubClass.invariant
-- MySubClass.invariant
length = 3.74166
-- MySubClass.invariant
go out of scope
program exit
MyBaseClass.dtor
-- MySubClass.invariant
MySubClass.dtor
MyBaseClass.dtor
( lastupdate:20070427 最新文章请访问http://www.d-programming-language-china.org )

关于一大步成功社区:
yidabu提倡在交流中学习,在分享中提高
收集感兴趣的知识,写下心得,通过网络与别人一起分享
理解一点就实践一步,收获什么就分享什么,成功就是这样一点点一步步累积起来的
网络只是一个工具,只有自己身心提高才是实实在在的。d-programming-language-china.org为大家提供一个学习交流各种知识的平台

TOP

发新话题