1. 程式人生 > >NS2入門學習(四)之Otcl知識點

NS2入門學習(四)之Otcl知識點

面向物件的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,依次類推 最後按照呼叫的順序輸出了結果