版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaojiewang1990/article/details/54380281
面向对象的Tcl语言,对象和类的概念同C++类似。
1.类和对象的定义
% Class Animal #定义类名
% Animal animal_1#产生类的对象
animal info class
=>Animal
Animal info instances
=>animal_1
2.成员变量与成员函数的定义
类的定义并不是像C++在{}中完成一个明显清楚的定义,而是写成多个分开的部分,
成员变量也并不是预先定义才在成员函数中使用,而是在成员函数中定义。
定义方法采用instproc,成员变量使用instvar关键字。$self 含义与C++中的this类似,表示对象自身。
Animal instproc run {speed}
{
$self instvar speed_ #但是这个变量也只是在Animal的这一个成员函数中使用,如果在另一个成员函数中使用还需要重新申明,即使是同一个类Animal。
set speed_ $speed
puts "Animal run with speed $speed_"
}
animal_1 run 2 ;#对象调用成员函数
=>Animal run with speed 2
在类Animal的定义中也可以使用其他成员函数中同名的变量,因为这个作用域仅仅是在该成员函数内
3.对象的初始化和销毁
使用init函数来进行初始化相当于构造函数,使用destroy函数来完成析构。
示例:Animal instproc init {args}
{
$self set speed_ 0 #初始化成员变量并赋值
eval $self next $args #显式的调用父类的init函数,next函数时父类中的同名函数,是继承概念。
#otcl不会像C++的类的构造函数会自动调用父类的构造函数,而是必须显示的调用父类的构造函数
}
Animal instproc destroy{ }
{
puts “zap!”
$self next
}
Animal animal
=>animal
animal set spee_ #查看成员变量的值
=>0
animal destroy
=>zap!
animal set speed_
=>invalid command name "animal" #因为前面对象animal已经被释放。
4、继承
otcl中的成员函数和变量的属性都是public的,没有C++中的那种的private/public/protected等属性。下面的示例学习。
Class Bagel #定义类
=>Bagel
Bagel insproc init{arg} #定义类的初始化函数
{
return raw!
$self set toasted 0
eval $self next $args
}
Bagel instproc toast {} #定义类的成员函数toast
{
$self instvar toasted
incr toasted #incr 将一个数值加到一个整形变量上,相当于自加
if {$toasted>1}then
{
error "something's burning!"
}
return{}
}
Class SpreadableBagel -superclass Bagel; #SpreadableBagel继承于类Bagel
=>SpreadableBagel
SpreadableBagel sBagel; #生成SpreadableBagel类的对象sBagel
SpreadableBagel instproc init {args} #SpreadableBagel的初始化函数
{
$self set toppings{}
eval $self next $args #调用父类的初始化函数
}
sBagel set toasted #父类的变量
=>0
sBagel toast #实际调用父类Bagel的toast函数,此时不输出,因为此时toasted=1
sBagel toast #实际调用父类Bagel的toast函数
=>something's burning! #此时toasted加上1等于2了,输出error信息
SpreadableBagel info superclass #查看父类信息
=>Bagel
SpreadableBagel info heritage #查看继承树信息
=>Bagel Object #继承树中出现了Object类,因为Bagel没有制定父类,所以默认就是Object
Bagel instproc taste {} #Bagel增加了新的taste成员函数
{
$self instvar toasted
if{$toasted==0}then
{
return raw!
}
elseif{$toasted==1}then
{
return toasty
}
else
{
return burnt!
}
}
SpreadableBagel instproc spead {args}
{
$self instvarn toppings
set toppings[concat $toppings $args]
return $toppings
}
SpreadableBagel instproc taste {}#子类SpreadableBagel增加成员函数taste
{
$self instvar toppings
set t [$self next] #$self next调用父类Bagel的taste函数
foreach i $toppings
{
lappend t $i #在变量$t后增加$i的值
}
return $t
}
Class Sesame #定义类Sesame
=>Sesame
Sesame instproc taste{}
{
concat[$self next] "sesame"
}
Class Onion #定义类Onion
=>Onion
Onion instproc taste{}
{
concat[$self next] "onion"
}
Class SesameOnionBagel -superclass {Sesame Onion SpreadableBagel}
#SesameOnionBagel 继承了3个父类
=>SesameOnionBagel
SesameOnionBagel info heritage #查看SesameOnionBagel 继承树
=>Sesame Onion SpreadableBagel Bagel Object
SesameOnionBagel abagel -spead butter #调用spead函数,来自SpreadableBagel类
=>abagel
abagel taste
=>raw! butter onion sesame
#abagel 调用taste函数之后,因为在继承树关系中它首先继承于Sesame类,从而先调用的是Sesame类的taste函数,然后Sesame类的taste函数又调用了$self next,即它的上一级父类Onion,依次类推 最后按照调用的顺序输出了结果