VB编程语言入门学习.docx
《VB编程语言入门学习.docx》由会员分享,可在线阅读,更多相关《VB编程语言入门学习.docx(24页珍藏版)》请在冰豆网上搜索。
VB编程语言入门学习
VB.NET之旅(一—失踪的窗体
好久没有新作,架不住兄弟们的问询与诘问,只得拿些旧作来补上近来没空写作的缺乏。
羞愧ing!
这一
系列与Henry手记系列不一样,是一个人物办法的情形故事,开端发表于《计算机国际》,适用于VB.net初
专家,老鸟们就不必在我这一系列的文章上浪费时间了。
我期望自个有时间今后,能不断持续这一系列
的文章,参加许多的工程处理方案。
一起,我的Henry手记也会持续写下去,以报答长时间以来撑持我的
一切兄弟。
布景:
我叫Henry,刚从大学计算机专业结业,新参加索易公司的.NET开发小组;担任带我的喽罗是大李,.NET高手,是个诙谐又有耐性的家伙;老白是咱们有些的头头,常常带给咱们乖僻又难缠的需求。
榜首天上班,白司理就带着我去.NET技能小组签到。
“大李,这是新来的同事,你要多帮帮他。
”老白
指着我对一个眼镜后边透着闪闪目光的年轻人说。
“没疑问,他会做得极好的。
”大李莫非会看相不成?
仍是人家谦让呀?
不论了,我只需自个尽力就对
了。
20分钟后,我现已在分配给我的一台P4电脑,WindowsXP平台下翻开了VisualStudio.NET的集成编译环
境(IDE开端赏识了。
一个多美丽的编译环境呀,能够自选运用时的个性是VB6的还是VC6的。
我挑选的
是RAD功用好的VB6个性。
“你刚开端触摸.NET,在系统训练之前先加深点形象,看看VB.NET与VB6有啥不一样吧。
你创立两个窗体
每个窗体上各有一个按钮,点击时躲藏其地址的那个窗体,切换出另一个窗体来。
”大李的声响在耳
边响起,打断了我对IDE的赏识。
但他提的需求也太简略了吧,在VB6中只需求两句写在按钮的单击呼应
中的句子就行了:
两个窗体:
Form1与Form2。
Form1上的按钮为:
Command1,Form2上的按钮为:
Command2PrivateSubCommand1_Click(
Me.Hide
Form2.Show
EndSub
PrivateSubCommand2_Click(
Me.Hide
Form1.Show
EndSub所以,我毫不犹豫地在VS.NET中内开端我的榜首个VB.NET的项目了。
首要,新建了一个VB.NET的Windows应用程序项目,主动生成了一个WindowsForm:
Form1,在其上参加一个按钮控件:
Button1;然后,增加了一个WindowsForm:
Form2,在其上参加了一个按钮控件:
Button2。
在描绘窗口双击Button1后,编译器会切换到代码窗口的Button1的单击呼应代码中。
在代码段中故计重施,当我想写Form2.Show时,在Form2之后打个点,呈现的智能感知菜单中,却没有
Show这一办法。
真新鲜,这怎样能够?
莫非VB.NET改动有这么大。
我昂首看了看站在我身旁的大李。
大李马上面露浅笑,看来是正中他的骗局。
他手指向屏幕,点了点Form1中的代码的最初处:
Public
ClassForm1
InheritsSystem.Windows.Forms.Form不笨的我马上就知道了,如今的Form1是一个从System.Windows.Forms.Form承继下来的类了,调用的时分当然需求先实例化了,哈,也不难嘛。
马上动
手:
PrivateSub
Button1_Click(ByValsenderAsSystem.Object,_
ByValeAsSystem.EventArgsHandlesButton1.Click
Me.Hide(
Dimfrm2AsNewForm2(…实例化Form2类,得到
一个目标
frm2.Show(
EndSub在Form2的Button2的单击工作中也相似地写了一段代码,运转一下,和VB6的效果差不多了。
正
在得意中,大李走过来,在我的Form1中增加了一个文本框textbox1,清空其间的文字。
然后运转了一下
程序。
在运转中,他在文本框里写了几个字:
“Henry的著作”,然后点击Button1切换到Form2,接着
点击Button2,从头呈现的Form1的文本框中却变成了空白。
“这……”我一时语塞,慢慢地想起点啥,“大概是程序经过New布局办法,每次点击按钮都会从头实
例化一次Form类吧?
所以每次从头呈现的窗体都不是从前从前呈现过的那个。
那从前的窗体也就失踪了
调不出来了。
”
“失踪?
”大李不由笑了起来,“对呀,失踪在内存中。
你每实例化一次,系统就会拓荒一块内存给一
个目标,并会有相应的线程对其进行操控与办理。
若是作为进程中主线程的榜首个Form1被Hide起来,没有封闭它,那么即便你封闭后来新创立的一切窗体,进程也不会被间断。
那么,用啥办法去找回你
失踪的窗体,或许说怎么就只运用一个目标,不再每次实例化呢?
”
“大局目标!
”我脱口而出,感受到大李模棱两可,只好硬着头皮持续说:
“运用大局变量,使Form1
与Form2只实例化一次,这样就能够了。
”
然后,在大李的注视下,我开端施行我的方案:
再创立一个模块文件:
module1.vb,并且同时在:
处理方案办理器-〉项目名.sln-〉右点鼠标-〉特点-〉通用属性->惯例->发动目标-〉改为Module1
。
让程序发动后先运转Module1中的代码指令,然后编写代码如下:
'Module1.vb
ModuleModule1
Publicfrm1AsNewForm1(…界说Form1的共用变量实
例
Publicfrm2AsNewForm2(…界说Form1的共用变量实例
SubMain(
Application.Run(frm1…这句话标明程序发动了
modele后,会接下来运转frm1,即form1的一个实例。
主线程就变成运转期的frm1了。
EndSub
EndModule这样一来,frm1、frm2就变成大局变量了,在Button1与Button2的单击呼应代码中只需写:
frm1.show就能够了。
再运转程序,可以了,“Henry的著作”一向都会保持在Form1中的文本框里。
大李老哥没等我欢笑起来就再次出手,在frm1躲藏起来的时分,封闭了Form2窗口(frm2实例,桌面上
啥窗体都没有了,进程又一次被堕入在无法间断的状况下。
MyGod,面向目标的VB.NET,爱你莫非真的这么难……
VB.NET之旅(二—布局与析构
在Form1窗体的实例被躲藏的时分,封闭了Form2窗体的实例,使我失去了对主线程的人工操控,进程无
法正常封闭了。
只好运用Ctrl+Alt+Del调出系统进程办理器,强行间断了该进程。
为了防止昂首看见大李的笑脸,我只好垂头想办法。
有了,我只需能截获Form2实例封闭的音讯,不就能够再调出躲藏的主线程窗体了吗?
在Form2的基类事
件(BaseClassEvent中重载Closing办法进行处置:
PrivateSubForm2_Closing(ByValsenderAsObject,
ByValeAs_
System.ComponentModel.CancelEventArgsHandlesMyBase.Closing
frm1.Show(
EndSub哈,很便利,我封闭了Form2窗体的实例后,被躲藏的那个frm1又呈现了。
“嗯,”大李总算发话了,“你再点击一下Form1窗体上的Button1试试。
”
我背心一凉,隐约感受大李等待着的即是这个时分。
无法的我还只能照他说的去做。
公然,弹出一个出错窗口.
“你封闭了frm2这个Form2的实例,也就完毕了这个目标的生存期,”大李看来是蓄势已久了,“这即是犯错提示中所说的…无法拜访名为Form2的已处置目标‟。
当咱们封闭一个窗口的时分,会宣布一个终
止呼应,并将该窗口目标,就象上面界说的frm2,送入停止行列,公共言语运行库的废物收回器盯梢着这个目标的生存期,此刻就会调用此目标基类,比方Form2的Dispose办法,用于毁掉目标并收回资源。
所以……”
“所以我只需判别一下frm2是不是被毁掉就行了,若是毁掉了,我就再布局一个实例不就行了?
”我恍然大悟道。
大李首次浅笑地址了答应说:
“用frm2.IsDisposed就能够来判别了。
”
我心照不宣地写道:
PrivateSub
Button1_Click(ByValsenderAsSystem.Object,_
ByValeAsSystem.EventArgsHandlesButton1.Click
Iffrm2IsNothingOrfrm2.IsDisposedThen
…判别目标是不是被毁掉
frm2=NewForm2(
EndIf
Me.Hide(
frm2.Show(
EndSub这下完善多了,两个窗体之间的切换也不会有这么多别扭的疑问了。
我转过身,看到大李现已找了把椅子坐在我的身边。
“你来说说,对VB.NET的窗体实例的创立与毁掉的进程吧。
”
我整理了一下杂乱的思路,长吁了一口气,开端说:
“一个窗体类,比方Form1类是经过调用其基类,就是Form类的New办法来创立实例、Dispose办法来毁掉实例。
”
“没错。
”大李边说话,一边在我的程序中点击开来被代码窗口主动折叠起来的"Windows窗体描绘器
生成的代码":
PublicSubNew(
MyBase.New(
'该调用是Windows窗体描绘器所必需的。
InitializeComponent(
'在InitializeComponent(调用之后增加任何初始化
EndSub
'窗体重写处置以整理组件列表。
ProtectedOverloadsOverridesSubDispose(ByValdisposing
AsBoolean
IfdisposingThen
IfNot(componentsIsNothingThen
components.Dispose(
EndIf
EndIf
MyBase.Dispose(disposing
EndSub大李开端说明道:
“MyBase关键词的行动相似于引证类的当时实例的基类的目标变量。
MyBase常用于拜访在派生类中被重写或躲藏的基类成员。
在这段代码中,MyBase指的当然即是System.Windows.Forms.Form类了。
布局目标时用的New办法是显式调用的,没什么好说明的。
但析构的
办法值得一说。
”
他看了我一想,持续说:
“Form.Dispose办法是重写自Control.Dispose办法的,那么Control.Dispose办法的含义又是怎么的?
它的效果即是:
开释由Control占用的非保管资源,还能够另外再开释保管资
源。
当它参数中的disposing为true则开释保管资源和非保管资源;为false则仅开释非保管资源。
Form类的disposing为true。
在封闭窗体时主动调用dispose的功用是得益于.net的公共语言运转库,运
行库主动处置目标规划和办理对目标的引证,当不再运用目标时释放它们。
其生存期以这种办法来办理的目标称为保管数据。
主动内存办理消除了内存走漏以及其他一些常见的编程过错。
任何类型的Dispose办法都大概开释它具有的一切资源。
它还大概经过调用其父类型的Dispose办法开释其基类型具有的一切资源。
该父类型的Dispose办法大概开释它具有的一切资源并一样也调用其父类型的Dispose办法,从而在整个基类型层次布局中传达该办法。
要保证始终正确地整理资源,Dispose办法大概能够被屡次安全调用而不引发任何反常。
”
“可是,若是系统疑问或应用程序调用上出了疑问,不能正常调用Dispose怎样办?
”我想起了啥,问道。
“若是经过Dispose还开释不洁净或没有调用Dispose,系统的废物收回器会调用目标的Finalize办法
进行铲除。
由于履行Finalize办法会大大减损功用,所以咱们不会一开端就用它去进行铲除作业。
”
大李略微说明了一下。
我总算想起了一个重要的疑问:
“若是总是在模块中界说的大局变量来处置,由于拜访规模太大,会不会有安全性的疑问?
”
“当然,咱们能够试试其他的处理方案。
”总是有备而言。
VB.NET之旅(三—同享成员
一起对VB.NET充满了猎奇与晓得的巴望。
“除了大局变量外,还有啥好办法吗?
”我迫不急待地想知道成果。
“能够运用同享成员。
”大李依然是那么淡漠然,“VB.NET如今是撑持真实的面向目标编程,能够承继
、运用多态、同享成员和静态成员。
同享成员即是在一切类和所界说派生类的实例之间同享的办法、属性、字段和工作。
一切运用类创立的目标都能够拜访一样的数据、同享完结进程,并且收到一样的激起工作。
”
“这么好呀,那怎样完结呢?
”我好象又回到了课堂上,满脑都是无知的符号。
“很简略,在Public或Private成员润饰符后加上Shared关键词即可了。
Shared关键词指示一个或多个被声明的编程元素将被同享。
同享元素不关联于某类或布局的特定实例。
能够经过运用类名或布局称号或许类或布局的特定实例的变量称号限制同享元从来拜访它们。
你来看这段代码
PublicClassShareClass
PublicSharedSharedValueAsString
PublicSharedSubShareMethod(
MsgBox("Thisisasharedmethod."
EndSub
EndClassSub
TestShared(
DimShared1AsNewShareClass('创立了类的一个实例.
DimShared2AsNewShareClass('创立了类的第二个实例.
Shared1.SharedValue="ShareValue1"'给同享字段赋值.
Shared2.SharedValue="ShareValue2"'重写同享字段的值
ShareClass.ShareMethod('不必创立实例就能够调用类的办法.
EndSub“有两个关键,一个是同享成员若是是办法或特点,我们不必创立实例就能够直接用…类名.共
享成员‟的办法进行调用;第二个关键,同享字段是仅有的,你来说说运转后Shared1.SharesValue的值是多少?
”
我脑筋里转了两圈,已然说同享字段是仅有的,那么Shared1.SharedValue和Shared2.SharedValue其实对应的是同一个同享字段,所以么,我马上大声说:
“是ShareValue2。
由于被Shared2.SharedValue修改了。
”
“没错!
”大李又一次绽放了会意的浅笑,真是对我的最高奖励。
“那你还不着手修正一下你的程序?
”
好!
说做就做。
已然同享特点在其调用的时分是不必实例化的,那么我最佳能凭借布局一个同享特点来完结。
并且要能够判别其实例是不是存在或是不是被毁掉,若是不存在就布局一个新的窗体实例,若是存在
就对其进行调用:
Private
Sharedm_vb6FormDefInstanceAsForm1
PublicSharedPropertyDefInstance(AsForm1
Get
Ifm_vb6FormDefInstanceIsNothingOrElse_
m_vb6FormDefInstance.IsDisposedThen…判别窗体
实例是不是存在
m_vb6FormDefInstance=NewForm1(
EndIf
DefInstance=m_vb6FormDefInstance
EndGet
Set(ByValValueAsForm1
m_vb6FormDefInstance=Value
EndSet
EndProperty在Form2中也参加相似的代码,只不过把Form1改为Form2。
调用它是如此的便利:
//Form1中的代码
PrivateSubButton1_Click(ByValsenderAsSystem.Object,ByVale
AsSystem.EventArgs
HandlesButton1.Click
Me.Hide(
Form2.DefInstance.Show(
EndSub
//Form2中的代码
PrivateSubButton1_Click(ByValsenderAs_
System.Object,ByValeAsSystem.EventArgs_
HandlesButton1.Click
Me.Hide(
Form1.DefInstance.Show(
EndSub
PrivateSubForm2_Closing(ByValsenderAsObject,_
ByValeAsSystem.ComponentModel.CancelEventArgs_
HandlesMyBase.Closing
Form1.DefInstance.Show(
EndSub赶忙运转一下,不对呀,榜首个窗体里文本框改为“Henry的著作”后,再切换仍是不见了?
我疑问地昂首看了看大李。
“你再好好想想,首次发动的是啥?
”大李模糊地说了一句。
“首次发动的是作为主线程的Form1窗体呀!
”我嘟啷着说。
“那么Form1.DefInstance在哪呢?
”大李这句话真是吵醒梦中人呀!
我马上着手:
ModuleModule1
SubMain(
Application.Run(Form1.DefInstance
EndSub
EndModule并把Module1设为发动项目。
运转运转……哈哈,一切都满意!
我开端喜爱上VB.NET了。
VB.NET之旅(四—类和布局
刚上班,就被大李找去了。
“Henry,昨日对窗体的操作给你最大的领会是啥?
”
“当然有领会,最深的形象即是VB.NET中类是无所不在了,连窗体都变成了一个类。
”我深有感受地说。
“没错,类是咱们用来布局VB.NET应用程序时的最基本的编程布局了。
你也学习过最基本的面向目标编程了,那么你能告诉我,布局与类有啥相似之处与不一样之处吗?
”
“好的。
”我口中答复着,心里仍是有点不以为然,“布局和类,都是对成员的封装办法,可是类能够
撑持承继……”
大李一边点着头,一边听我说,听到我结尾支吾着没了声响才抬起头“还有呢?
”
“没了。
”我这时才开端心中发慌。
“呵呵,一样之处我想你心中仍是知道的,它们都富含成员,包括布局函数、办法、特点、字段、常量
、枚举和工作。
都可以完结接口,都有同享的布局函数。
”
“对不住,结尾那一句,都有布局函数是啥意思?
布局的布局函数我从来没有自个界说过。
”
大李马上写下了这一段代码:
StructureSHenry
Publicx,yAsInteger
PublicSubNew(ByValxAsInteger,ByValyAsInteger
Me.x=x
Me.y=y
EndSub
EndStructure
Submain(
DimH1AsSHenry=NewSHenry(
DimH2AsSHenry=NewSHenry(2,1
EndSub“真的呢,能够完结布局的布局函数!
”我还一向没有注意过这个疑问。
“可是,你只界说过
一个带参数的布局函数,H2的实例化我是知道的,可是H1怎样也能经过编译器检测呢?
”其实我心中更想问的是布局怎样也能实例化成目标,那和类真的很象呀。
“缘由么,”大李推了推眼镜,“每个布局都隐式地具有Public无参数实例构造函数,该布局函数产
生布局的默许值。
所以你平常不写布局函数,也一样能够New出一个布局来,对吧?
事实上,咱们反而在
布局类型声明中不行能声明无参数实例布局函数。
只能声明…参数化‟实例布局函数。
”
“都能够用new来实例化,布局和类在内存分配上莫非也是一样的吗?
”这个疑问我一向挺不知道,正巧借这个论题问一下。
“在这上面,不一样可就大了。
”看到大李满面笑容的姿态,我就晓得问到点子上了,马上摆开姿势,作仔细倾听状。
“简略来说,布局是值类型,而类是引证类型。
因而,布局运用仓库分配,类运用堆分配。
”
看到我苍茫的双眼,大李笑了笑,在电脑上飞快地写了个示例:
ClassCHenry
PubliczAsInteger=0
…能对非静态成员初始化也是一个差异
EndClass
Submain(
DimH1AsSHenry=NewSHenry(0,2'赋给H1.x=0
DimH2AsSHenry=H1
H2.x=26
DimR1AsNewCHenry('R1.z也是等于0
DimR2AsCHenry=R1
R2.z=26
Console.WriteLine("H1.x="&H1.x&",H2.x="&H2.x
Console.WriteLine("R1.z="&R1.z&",R2.value="&R2.z
EndSub“你看一下成果大概是啥?
”大李一边说,一边运转了程序:
H1.x=0,H2.x=26
R1.z=26,R2.value=26“这即是值类型和引证类型的不一样。
布局的实例H2.x赋值并不影响H1.x,这是由于尽管它们同归于一种SHenry布局,但它们都有各自的存储空间。
相反,给R2.z赋值26后;则会影响R1和R2都引证的目标”
“说得更知道一点,类作为引证类型,是存储在运转时的堆上,只能经过引证该存储来拜访它们,不能直接拜访。
引证类型的变量总是包括该类型的值引证,或包括空引证。
空引证不引证任何内容;除分配空引证外,对空引证进行的任何操作都是无效的。
引证类型的变量赋值只会创立引证的一个副本,而不是所引证的值的副本。
它们实践上都是会指向同一块存储区的。
”大李手指了指运转的成果。
“布局是直接存储在仓库上,要么在数组中,要么在另一个类型中。
当包括布局实例的方位被毁掉时,
布局实例也会被毁掉。
值类型总是能够直接拜访。
咱们不能创立对值类型的引证,也不能引证已毁掉的值类型实例。
值类型的变量总是包括此类型的值。
与引证类型不一样,值类型的值不能为空引证,也不能引证派生附近程度较大的类型的目标。
值类型的变量赋值会创立所赋的值的副本,当然会新拓荒一块内存区来保管值。
”
“哦,我知道了。
它们还有啥差异没有?
”我对布局和类的差异首次有了深入的感受。
“当然有许多,比方一切的布局成员都默以为Public,类变量和常量默以为Private,其他的类成员默
以为Public;布局成员不能声明为Protected,类成员能够;布局进程不能处置工作,类进程能够;结
构变量声明不能指定初始值、New关键词或数组初始巨细,类变量声明能够。
”大李喝了口水,停了一下,然后持续说。
“布局从不停止,所以公共言语运行库从不在任何布局上调用Finalize办法;类可由废物收回器停止
废物收回器会盯梢未完结的引证直到某个特定的实例,当检测到没有剩余的活动引证时,废物收回器将在类上调用Finalize。
”
“这个我能够知道,由于布局是值类型,是由系统统一办理内存,不是引证,所以不会对内存形成危害。
”我接着说了两句。
“还有,你方才也说到了它们之间一个很重要的差异:
布局是不行承继的,而类能够承继。
其实布局自
身是从ValueType类隐式承继下来的。
数据类