NS2入门学习(四)之Otcl知识点

版权声明:本文为博主原创文章,未经博主允许不得转载。 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,依次类推 最后按照调用的顺序输出了结果


猜你喜欢

转载自blog.csdn.net/xiaojiewang1990/article/details/54380281