Eiffel Introduction(二)

来源:互联网 发布:手机音乐裁剪软件 编辑:程序博客网 时间:2024/05/14 08:25

4.1 Hello(示例)

class HELLO

creation make

feature

    make is

      -- say hello to the significant people in the world.

    do

        io.putstring( “Hello, OOPers%N” )

    end

end

 

变量 io 是一个引用,指向一个型别为 STANDARD_FILES 的对象。后面我们将看到类别 HELLO 如何访问这个变量。

 

4.2 Eiffel 系统[译注3/OOSC2e,p196]

 

l         代码文件的名称通常应该与该代码所包含之类别的名称相同,并以 .e 作为扩展名。

l         因此,类别 HELLO 的代码应该写在名为 hello.e 的文件里。

l         每个不同的系统应该处在不同的目录中。

下面给出了 hello stack 两个系统的示例。

 

4.3 STACK class

class MY_STACK[ G ]

  creation make

  feature

    capacity, depth : INTEGER

    push( x : G ) is

      -- Make x the top item.

      require

        not_full: depth < capacity

      do

        depth := depth + 1

        s.put( x, depth )

      ensure

        depth = old depth + 1

        top = x

    end -- push

    pop is

      -- Remove the top item.

      require

        not_empty: depth > 0

      do

        depth := depth - 1

      ensure

        depth = old depth - 1

        -- top = the item remaining on the stack (if any)

        -- that has been there the least amount of time.

    end -- pop

    top : G is

      -- The item that has been on the stack for the least

      -- amount of time.

      require

        not_empty: depth > 0

      do

        Result := s.item( depth )

    end -- top

  feature{NONE}

    s : ARRAY[ G ]

    make( c : INTEGER ) is

    -- Initialize an empty stack with capacity c.

      require

        c > 0

      do

        capacity := c

        !!s.make( 1, capacity )

      ensure

        capacity = c

        depth = 0

    end -- make

end -- MY_STACK

 

4.4 TEST_STACK

class TEST_STACK

creation make_test

feature{NONE}

  si : MY_STACK[ INTEGER ] ; ss : MY_STACK[ STRING ]

  make_test is

    do

      test_integer_stack

      test_string_stack

  end

  test_integer_stack is

    do

      !!si.make( 3 )

      si.push( 3 )

      si.push( 2 )

      si.push( 1 )

      io.putint( si.depth ) io.new_line

      io.putint( si.top ) io.new_line

      si.pop

      io.putint( si.top ) io.new_line

      si.pop

      io.putint( si.top ) io.new_line

      si.pop

  end

  test_string_stack is

    do

       !!ss.make( 10 )

       ss.push( " in Dixie." )

       ss.push( " I was" )

       ss.push( "Oh, I wish" )

       io.putstring( ss.top )

       ss.pop

       io.putstring( ss.top )

       ss.pop

       io.putstring( ss.top ) io.new_line

  end

end

 

4.5 STACK class(另一种实现)

class MY_STACK[ G ]

creation make

feature{ANY}

  capacity : INTEGER

  depth : INTEGER is

    do

      Result := current_depth

  end

  push( x : G ) is

    -- Make x the top item.

    require

      not_full: depth < capacity

    do

      current_depth := current_depth + 1

      s.put( x, current_depth )

      top := x

    ensure

      depth = old depth + 1 ; top = x

  end -- push

  top : G

    -- The item that has been on the stack for the least

    -- amount of time.

    -- require

    -- not_empty: depth > 0

  pop is

    -- Remove the top item.

    require

      not_empty: depth > 0

    do

      current_depth := current_depth - 1

      if current_depth > 0 then

        top := s.item( current_depth )

      end

    ensure

      depth = old depth - 1

        -- top = the item remaining on the stack (if any)

        -- that has been there the least amount of time.

  end -- pop

feature{NONE}

  s : ARRAY[ G ]

  current_depth : INTEGER

  make( c : INTEGER ) is

    -- Initialize an empty stack with capacity c.

    require

      c > 0

    do

      capacity := c

      !!s.make( 1, capacity )

      current_depth := 0

    ensure

      capacity = c

      depth = 0

  end -- make

end

5 杂项议题

5.1 Eiffel 中的简单型别

l         Eiffel 中的简单型别包括 CHARACTERBOOLEANINTEGERREAL 以及 DOUBLE

l         简单型别之对象的赋值以及等同性(equality)检查与照常想象到的一样,即 a := b 的结果是将 b 的值拷贝给 a,而 a = b 则在 a b 所代表的值相等的时候为真值。

l         检查不等性时,使用 a /= b

l         简单型别的对象不需要予以显式的创建。

l         简而言之,简单型别采用值语义(value semantics)。

 

5.2 Class Types

l         简单型别以外的其它型别之对象是通过 references(引用;也称 pointers,指针)来实现的。这样的对象需要被显式的创建。

l         如果 b = Void 为真,那么 b 不指代任何引用对象。如果 b /= Void 为真,那么 b 指代一个已经创建的对象。

l         于是,a := b 使得 a,b 两者指代同一个对象(即成为同一个对象的引用)。这种情况下, a = b 的结果为真。

l         同样,我们使用 a /= b 来检查不等性。

l         还有一些方法(copyis_equal)可以实现将一个被引用对象的域(field)拷贝到另一个对象对应的中,并可以检查两各对象是否包含相同的值。

l         简而言之,class types 采用引用语义(reference semantics)。

 

5.3 GENERAL 类别

l         每一个类别都默认的继承自类别 ANY,而类别 ANY 则是继承自类别 GENERAL

l         Void 这个 feature 正是身居 GENERAL 中,因此每一个类别都可以使用它。

l         类别 GENERAL 的另一个重要的 feature ioio 被声明为 STD_FILES 型别,提供对输入/输出程序(routines)的便捷访问。

l         例如, io.readint 从标准输入读取一个整数。读取的结果被放在 io.lastint中。(可注意到,能改变状态的feature与只询访状态(即不能改变状态)的feature是分离开来的。)

 

5.4 变量与对象

l         要让变量 b 指代一个对象,有两种方法:

1.       显式创建 b 对象:!!b.make

2.    用已经创建的对象对 b 赋值:!!a.make; b := a

l         类似的,要使 b 脱离(detach)对一个对象的引用,也有两种方法:

1.    显式脱离(Explicit detachment):b := Void

2.    Void 引用赋值给 ba := Void; b := a

 

5.5 常量

使用如下语法形式声明常量:

constant_name : CLASS_NAME is value

比如:

pi : DOUBLE is 3.14159

base : INTEGER is 10

hello : STRING is “hello”

 

5.6 不需要 make routine 的对象创建过程

l         简单的类别不需要特定的创建程序(creation routine),也是很常见的情况。

l         比如,一个只用来提供标准的数学常量及函数的类别,并不需要作特定的初始化动作。

l         当然,我们总是可以为类别提供一个空的 make routine,而这在 Eiffel 中并不是必需的。我们可以完全忽略 creation 子句。

class BASIC_MATH

-- No creation clause

feature

  pi : REAL is 3.14159

  euler : REAL is 2.71828

  sin( x : REAL ) : REAL is

  ....

end

 

该类别的使用者可能通过声明一个变量来创建 BASIC_MATH 实体,比如

bm : BASIC_MATH

然后执行命令

!!bm

这个命令让系统为一个 BASIC_MATH 型别的对象分配空间并将指向该对象的指针返回给变量 bm

在这种情况下,根本就不需要执行 make

 

5.7 自身引用

l         每一种面向对象语言都提供一种让对象引用其自身的方式。

l         Eiffel 中,用 Current 指代当前的对象。Current 最经常的用法是为另一个对象提供指向先前一个对象的引用。

class SOME_WINDOW_CLASS

sub : ANOTHER_WINDOW_CLASS

  ...

  !!sub.make( Current )

  ...

end

class ANOTHER_WINDOW_CLASS

parent : SOME_WINDOW_CLASS

  ...

  make( p : SOME_WINDOW_CLASS ) is

    do

      parent := p

end

 

 

(全文完)

原创粉丝点击