---------------------- <a href="http://net.itheima.com/" target="blank">Windows Phone 7手机开发</a>、<a href="http://net.itheima.com/" target="blank">.Net培训</a>、期待与您交流! ----------------------
C#基础
2012年2月29日
.Net Framework:提供函数库、类库。
调试→全部中断:看程序停在哪。
三条控制台指令:
Console.WriteLine:打印输出。
Console.ReadLine:从控制台读入一行。
Console.ReadKey:控制台暂停。
显示代码行号:工具→选项→文本编辑器→C#→显示→行号
2012年3月1日
变量必须在使用前声明和初始化。
2012年3月2日
string s = @"\\\\"; //@表示字符串中的\不当成转义符使用。
转义符只针对在代码中直接写出的字符串,对于程序中读取出来没有这个问题。
简单的类型转换:Convert.ToInt32()//将字符串转换为整数
命名规则:第一个字符必须是字母或者下划线(_),其后的字符可以是任意个数字、字母、下划线。不能全部使用C#的关键字(在VS中会以蓝色显示),比如class、namespace、new、void。建议变量的开头用小写 。并且可用中文作为变量名。
赋值运算符= :让左边变量的值等于右边的计算结果。
C#中赋值表达式的值为赋值后变量的值。
C#中必须写break,在switch case语句中,除了合并case的情况,如下所示。
case 10:
case 20:
Console.WriteLine("唯一一个case后不用break的情况!")
2012年3月5日
执行到return的时候就退出整个函数,而控制台程序一旦Main退出,程序就退出了。
Console.WriteLine("int最大值{0},最小值{1}",int.MaxValue,int.MinValue);
类型转换Cast:把源类型赋值给目标类型,两个类型不一致的时候会发生类型转换。a=b,b是源,a是目标。
分为显式转换,隐式转换。
只有在内存存储上存在交集的类型之间才能进行Cast,否则则不可以,比如不可以int i;string s=(string)i;反之也不可以。这种情况必须用Convert类提供的方法。
Convert不再是内存级别的转换,而是考虑数据意义的转换。Convert是一个加工、改造的过程。
Convert.ToInt32、Convert.ToString
枚举的意义就在于限定变量的取值范围。
类型后加[],就是这个类型的数组类型。
数组的长度是确定的,无法动态的增加长度。
string[] names=new string[5];//声明一个长度为5的string数组。
2012年3月6日
函数就是将一堆代码进行重用的一种机制。
确定函数参数的原则:自己能确定的数据自己内部解决,自己不能确定的数据通过函数传递。
函数以及类的名字以大写开头,变量名小写,有意义的词。
可变参数:int sum(string name,params int[] values)
可变参数数组必须是最后一个。
函数重载(函数重名):参数类型不同或者参数个数不同(不严谨),与返回值无关。
使用s.Length属性来获得字符串中的字符个数。
string可以看做是char的只读数组。char c=s[1];
C#中的字符串一个重要特性:不可变性,字符串一旦声明就不再可以改变。所以只能通过索引来读取指定位置的char,不能对指定位置的char进行修改。
如果要对char进行修改,那么必须创建一个新的字符串,用s.ToCharArray()方法得到字符串的char数组,对数组进行修改后,调用new string(char[])这个构造函数来创建char数组的字符串。
字符串的不可变性指的是内存中的字符串不可变,而不是变量不变。
string s1 = "hello";
string s10 = s1;
//s10指向s1指向的字符串,而不是s10指向s1,哪怕s1以后指向了其他内存,那么s10还是指向了“hello”。
2012年3月7日
1) String类常用函数(字符串处理)
ToLower():得到字符串的小写形式。
s=s.ToLower();
ToUpper():得到字符串的大写行式。
Trim():去掉字符串两端的空白。
s1.Equals(s2,StringComparison.OrdinalIgnoreCase),两个字符串进行比较,忽略大小写。
string[] Split(params char[] separator);//将字符串按照指定的分隔符分割为字符串数组;
string[] Split(char[] separator,StringSplitOptions options);//将字符串按照指定的char分隔符分割为字符串数组(options取RemoveEmptyEntries的时候移除结果中的空白字符串);
string[] Split(string[] separator,StringSplitOptions options);//将字符串按照指定的string分割符分割为字符串数组。
练习:从一个记录了学生成绩的文本文档,每个学生成绩是一行,每行是用|分割的数据,用|分割的域分别是姓名、年龄、成绩,写程序取出成绩最高学生的姓名和成绩。参考:使用string[] lines = System.IO.File.ReadAllLines(@"d:\1.txt", Encoding.Default);从文本文件读取数据,返回值为string数组,每个元素是一行。
字符串替换:string.Replace(string oldValue,string newValue)将字符串中出现oldValue的地方放newValue。
取字符串:string.Substring(int startIndex),取从startIndex开始一直到最后的子字符串。
string.Substring(int startIndex,int length),取从startIndex开始长度为length的子字符串,如果子字符串的长度不足length则报错。
bool Contains(string value)判断字符串中是否含有子串value
bool StartsWith(string value)判断字符串是否以子串value开始
bool EndsWith(string value)判断字符串是否以子串value结束
int IndexOf(string value) 取子串value第一次出现的位置,如果不存在则返回-1。
2012年3月8日
1) 函数参数默认是值传递的,也就是“复制一份”;
2) ref和out的区别:
ref必须先初始化,因为是引用,所以必须先“有”,才能引用,而out则是内部为外部赋值,所以不需要初始化,而且初始化也没用。
ref应用场景内部对外部的值进行改变,out则是内部为外部变量赋值,out一般用在函数有多个返回值的场所。
2012年3月9日
面向对象的三个特性:封装、继承、多态。
类是抽象的,对象是具体的。
对象也可以叫做类的实例。
字段(Field)就是类的状态,和某个对象相关的变量。类不占内存,对象才占内存。
方法(Method)就是类能够执行的动作。
类的继承,基类(BaseClass,基业,祖宗),父类(ParentClass),子类(ChildClass)。
定义类 class Person{}
对象的初始化 Person p1 = new Person();
//this. 自己的...
类的成员(Member):字段、方法、属性。它们都需要定义访问级别。
访问级别的用处在于控制成员在哪些地方可以被访问,这样达到面向对象中“封装”的目的。
访问级别:public(任何地方都可以访问),private(默认级别,只能由本类中的成员访问),internal,protected(不允许其他非子类访问)。
永远不要把字段public,用private!!!
属性:
惯用法:属性开头字母大写,字段开头字母小写。
字段和属性的区别:属性看似字段、不是字段,可以进行非法设置值的判断,可以设置只读。属性不保存数据,保存到字段中。
简化set、get(.net framwork3.5新特性):
public int Age(get;set;)/*编译器自动帮我们生成私有字段和set、get代码块*/
适合于set、get中没有特殊逻辑代码的情况。
定义:
在类中声明属性
private int age;
public int Age
{
set //赋值,在里面可以设置控制语句
{
if(value <0)//public字段和属性的区别,可以进行非法设置值的判断
{
return;
}
this.age = value;//value代表用户赋值过来的值
}
get //取值,得到Age的值
{
return this.age;
}
}
用法:
Person p1 = new Person();
p1.Age=30;
2012年3月31日星期六第一天上课笔记
1) 了解.net的基本概念以及结构和功能;
.net是一种技术,平台,适用于桌面应用程序、浏览器、手机的开发。
2) 介绍三种注释;
单行注释: / /,多行注释; /* */,文本注释; ///。
3) 变量的概念和声明以及命名规范;
先声明一个类型,再声明一个变量,最后赋值。(也可以多个变量一起声明)
必须以字母,下划线,@作为变量名称的开头。
4) 集成开发环境的功能介绍;
VS中的工具箱的拖拉以及怎样恢复,MSDN的应用,加载卸载的操作,文字的调节。
5) 创建解决方案;
如何创建新文件,文件名的命名,多个项目的创建。
6) 变量的类型及其的使用范围;
目前学习了int类型使用于整数,char类型适用于单个字符,string类型适用于字符串,decimal类型适用于金钱方面的数字后面要加m,,double类型适用于带小数点的小数。
7) 其他
占位符的使用。
“+”可以作用连接两个字符串。
变量值的多次赋值使用最终的值应用于代码中。
Console.writeline();显示输出
Console.readkey(); 使代码生成结果“暂停”。
2012年4月2日星期一第二天上课笔记
1) 快捷键
Ctrl +K +S折叠代码
Ctrl + K + D 重排代码
Ctrl + K + C 注释代码
Ctrl + K + U 取消注释
C + w + Tab + Tab Console.WriteLine();
F12 转到鼠标所在字段的定义处
2) 转义字符
\t 水平制表符它会尽可能的让行与行之间对齐 相当于键盘上的Tab键
@ 在字符串前面表示不转译,用于字符串中出现比较多的\,如果在前有@的情况下打印”,则需输入””才行。而且支持直接用回车换行。
3) 数据类型转换
隐式类型转换
参与运算(算术运算和赋值运算)的操作数和结果类型必须一致.我们在进行运算的时候如3+5 两边的操作数类型必须一样,如果不一样,必须遵守下面的两个条件:
第一 两种类型相兼容
第二 目标类型大于源类型
这样才能进行隐式转换。
如果一个操作数为double型,则整个表达式可提升为double型
double x = 10;
int y=3;
double result = x/y;
string resultStr = result.ToString("0.000");//转换成字符串的格式打印,0.000设置格式
Console.WriteLine(resultStr);
Console.WriteLine("{0:0.000}",result);//:0:0.000可以设置打印的格式
Console.ReadKey();
强制类型转换
语法:(数据类型)待转换的值
数据类型一定要相兼容
Convert不再仅是内存级别的转换,而是考虑数据意义的转换。Convert是一个加工、改造的过程
通过 Convert.ToInt32()能转换成int类型的数据)来把其他类型数据转换成int类型
4) 作业
练习,编程实现计算几天(如46天)是几周零几天.(手写、VS)
练习:编程实现107653秒是几天几小时几分钟几秒?(手写、VS)
修改上面的题目,让用户输入.(VS)
2012年4月3日星期二第三天上课笔记
1) 布尔(bool)类型:
bool值只有两个
真:True 假:False 关系运算的结果是布尔类型的
定义:bool变量名;
2) 算术运算符
++ 自加一 有前加加和后加加
-- 自减一 有前减减和后减减
一元运算符++/--比二元的+-优先级高
3) 复合赋值运算符
+= -= *= /= %=
4) 关系运算符(比较运算)
> < == != >= <=
5) 逻辑运算符
&& || !
x || y如果 x为 true,则不计算 y(因为不论 y为何值,“或”操作的结果都为 true)。这被称作为“短路”计算。
6) 运算符优先级
7) If …else if…
If(条件1)
{
语句1
}
Else if(条件2)
{
语句2
}
8) 作业
学编程不是看书,不是听老师讲,而是自己动手写。
作业1:提示用户输入密码,如果密码是“888888”则提示正确,否则要求再输入一次,如果密码是“888888”则提示正确,否则提示错误,程序结束。
作业2:提示用户输入用户名,然后再提示输入密码,如果用户名是“admin”并且密码是“888888”,则提示正确,否则,如果用户名不是admin还提示用户用户名不存在,如果用户名是admin则提示密码错误.
练习3:提示用户输入年龄,如果大于等于18,则告知用户可以查看,如果小于10岁,则告知不允许查看,如果大于等于10岁并且小于18,则提示用户是否继续查看(yes、no),如果输入的是yes则提示用户请查看,否则提示"退出,你放弃查看"。
9) 练习
练习1:提示用户输入帐号和密码 如果正确 则 提示用户输入正确 并且请用户输入你的名字 年龄 职业 性别
当用户输入完后 回车 显示 用户输入的内容 并且 提示 您是否要退出(请输入y/n) 如果用户输入的是y 则 提示程序结束 如果输入n 则显示 哈哈 我又变帅(漂亮啦)了
练习2:先提示用户输入你的名字 如果名字等于admin 则 直接显示欢迎来到我的地盘并 提示用户 测试开始
现在输入 你的语文 英语 数学 音乐 成绩 并且输入完后 计算总成绩和平均成绩
另外 要进行判断 如果总成绩大于(包含)195 则 提示 恭喜你 成绩合格 如果总成绩小于195 则 提示 悲剧了 智力不够
2012年4月5日星期四第四天上课笔记
1) switch-case
switch-case语法:
switch(表达式/变量)
{
case 值1:语句块1;
break;
case 值2:语句块2;
break;
default:语句块3;
break;
}
执行过程:当程序运行到swith(表达式/变量)这行代码的时候,判断括号里的变量,然后继续往下执行,看是否与下面case后面的值是否匹配,若匹配就运行语句块,然后break;然后继续执行后面的代码
如果与case后面的值不匹配,就运行default后面的语句块3然后运行到break;最后跳出swith,继续执行后面的代码。
相同点:
都可以实现多分支结构
不同点:
switch:一般只能用于等值比较
if-else if:可以处理范围
当case语句块是重复的,可以写到一起,例如:
case 1:
case 3:
case 5:
case 12:
day = 31;
break;
2) 使用状态变量可以灵活控制流程!!!
3) 抛异常
解决异常的办法
Try
{
//可能会报异常的代码
}
Catch
{
//异常后才执行的代码
}
4) 定义变量时,char不能为空,string可以为空
char 变量=’//必须有字符’;
string 变量=’//可以为空’;也可以这样 string 变量=null;
5) Do…while
do-while为先执行,再判断
do{循环体;}
while(条件);
6) 作业
1. Try…catch练习
2. double字符转换
3. 老师问学生,这道题你会做了吗?如果学生答"会了(y)",则可以放学.如果学生不会做(n),则老师再讲一遍,再问学生是否会做了......
直到学生会为止,才可以放学.
直到学生会或老师给他讲了10遍还不会,都要放学。
2012年4月6日星期五第五天上课笔记
1) 程序调试
设置断点
单步运行 F11逐语句执行 F10逐过程执行
观察变量 Ctrl+D+Q快速监视
2) for循环
for(表达式1;表达式2;表达式3)
{
循环体;
};
首先执行表达式1中的内容,然后判断表达式2是否为真,若为真,则执行循环体,执行完循环体后,执行表达式3,然后在判断表达式2是否为真,若为真,则执行循环体…一旦表达式2为假,退出循环,执行下面的代码
3) 定义常量
语法:
Const 类型名 常量名=值;
在程序中不可以改变常量的值,一旦改变,程序报错。变量在程序中可以改变值。
4) 三元表达式
语法:
<test> ? <resultIfTrue> : <resultIfTrue>
计算<test>可得到一个布尔值,如果为真,表达式的结果为resultIfTrue,如果为假,表达式的结果为resultIfTrue。
5) 枚举:
存储确定数量,确定的几个取值。比如男、女,东、西、南、北,
为什么要用枚举?
l 好处:
1、 规范用户的输入
2、 有智能提示,更方便。
枚举的定义语法:
[访问修饰符] enum枚举的名字
{…}
例:
[public] enum Gender //访问修饰符可以省略不写
{
值1,
值2,
…
值n
}
枚举类型定义代码放在命名空间或类中。
l 用法:
在主函数里面先声明一个枚举类型,后面跟一个变量名进行赋值
枚举类型 枚举名(变量名)= 枚举类型名.值
每一个值都对应一个数字
将int类型显式转换为枚举类型
Season number = (Season)num;
2012年4月7日星期六第六天上课笔记
1) 将字符串转换成int类型的变量,返回转换是否成功,可以实现try…catch类似的功能。
bool result = Int.Tryparse(参数1,参数2参数3)
参数1 待转换的字符串
参数2 out
参数3 转换后的那个类型的变量
前面要用一个bool类型的变量来接收返回值,如果为true则说明转换成功,如果为false则说明转换失败
注:参数2 和参数3是一体的;
Int number = Int.Parse(str); //可以将字符串格式的变量转换为int类型的变量。
2) 将字符串转换成枚举类型
格式:
(要转换成的枚举类型)(Enum.Parse(typeof(要转换成的枚举类型),”待转换字符串”))
例如:
XingBie xb = (Gender)(Enum.Parse(typeof(Gender),"male"));//用此函数可以验证输入的字符串是否包含在枚举里面,若没有,程序会报异常。
将枚举类型转换成字符串
String xb = Gender.男.ToString();
3) 结构
l 为什么要用结构?
可以一次声明多个不同类型的变量
l 语法:
[访问修饰符] struct结构的名字(自己定义的名字)
{
//结构体
}
//访问修饰符可以省略不写 最好写上 public
例如:
public struct Person
{
//结构体
}
l 结构体里如何声明变量?
[访问修饰符]数据类型变量名;
public string name;
public char sex;
l 结构的使用方法:
在主函数(目前代码都在主函数里写的)
首先声明一个结构的类型如:
Person p(变量名);
l 怎么用?
直接 p(变量名).Age就可以用了
字段初始化是不允许的
4) 数组
如何声明?
数据类型[] 变量名 = new 数据类型[]{…};
例如:
int[] nums = new int[] {…};
声明数组的四种方法:
int[] nums = new int[3]{5,3,8};//个数和声明数必须一致
int[] nums = new int[]{5,3,8};//正确,可以省略数组个数
int[] nums = new int[3];
int[] nums = {5,3,8};
Array. Sort(nums);//将数组从小到大排序
Array. Reverse(nums);//反序排序
数组要么指定长度,要么给出初始化集合,相当于隐式提供长度。
最好使用List<string>,你可以不断添加元素,最后再ToArray()
类似这样:
var list =new List<string>();
list.Add("item 1");
list.Add("item 2");
string[] result = list.ToArray();
2012年4月9日星期一第七天上课笔记
1) 冒泡排序
依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。至此,第一趟结束,将最大的数放到了最后。在第二趟:仍从第一对数开始比较,将小数放前,大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),第二趟结束,在倒数第二的位置上得到一个新的最大数(其实在整个数列中是第二大的数)。如此下去,重复以上过程,直至最终完成排序。
2) 方法(函数)
函数就是将一堆代码进行重用的一种机制。函数就是一段代码,这段代码可能有输入的值(参数),可能会返回值。一个函数就像一个专门做这件事的人,我们调用它来做一些事情,它可能需要我们提供一些数据给它,它执行完成后可能会有一些执行结果给我们。要求的数据就叫参数,返回的执行结果就是返回值。
l 方法的定义:
[访问修饰符] [static]返回值类型方法名([参数列表])
{
//方法体;
}
//访问修饰符:可以省略刚学都写public
//static :不可省略
//返回值类型:刚学 写void
//方法名:自己定义方法的名字,后面的扩后不可省略
l 方法的使用:
现在我们写的方法 在访问修饰符后面用的是static关键字,所以我们的这个方法叫静态方法,怎么用这个方法我们在静态方法中类名.方法名()就可以使用了。
l 方法的好处:
第一:方法就是代码重用的一种机制。
第二:一个方法可以说完成一个功能。
l 命名规则:方法名开头大写,参数名开头小写,参数名、变量名要有意义
l 方法的调用,对于静态方法,如果在同一个类中,直接写名字调用就行了.
l return可以立即退出方法.
如果我们定义(我们写的那个方法)方法,在同一个类中我在其他方法中调用的时候,可以省略那个类名,直接写方法名()括号不能省略,就能用了。
如果不是static的方法可以理解为非静态方法或者叫做实例方法。
3) 局部变量及变量的作用域
在方法中定义的变量成为局部变量,其作用域从定义开始,至所在的大括号结束为止。
在一个方法中想要访问另一个方法中的变量,怎么办?
第一种方法:通过参数解决
我们可以定义一个方法然后在方法的括号里定义一个变量或者自己写一个参数
然后在主函数中调用这个方法 在调用的时候我要给这个方法的括号一个参数
第二种方法:通过return返回值解决
如果你把变量定义到方法的外边,或者定义到这个类中,如果想在静态方法中,访问这个变量 要在定义的时候 加上static修饰 这个时候 我们通常叫“字段”静态字段或者叫静态变量
4) 方法重载
定义:一个类中可以有一个以上的方法拥有相同的名称。使用相同名称的每个方法必须有一个和其他方法不相同的签名。
签名:
方法的名称;
参数的数目;
参数的数据类型和顺序;
参数修饰符。
返回类型及形参的名称都不是签名的一部分。
2012年4月10日星期二第八天上课笔记
1) 方法返回值
可以用数组返回多个值,但是返回值的类型是一样的,若想要返回值的类型是不一样的呢?可以使用ref和out修饰符得到多个返回值。
l 引用参数:ref
使用引用参数时,必须在方法的声明和调用中都使用ref修饰符。
实参必须是变量,在用作实参前必须被赋值。
引用参数不在栈中为形参分配新的内存。
形参的名称相当于实参变量的别名,引用与实参相同的内存位置。
例如:
Class MyClass
{public int Val=20;}
Class program
{
Static void MyMethod(ref MyClass f1,ref int f2)
{
F1.Val = f1.Val+5;
F2=f2+5;
}
Static void Main()
{
Myclass A1 =new MyClass();
Int A2=10;
MyMethod(ref A1,ref A2);
}
}
l 输出参数:out
用于从方法内把数据传出到调用代码。
必须在声明的调用中都使用修饰符out
实参必须是变量,不能是其他表达式类型。
与引用参数不同:
在方法内部,输出参数在被读取之前必须被赋值。这意味着参数的初始值是无关的,而且没有必要在方法调用之前为实参赋值。
每个输出参数在方法返回之前必须被赋值。
代码示例:
Class MyClass
{public int Val=20;}
Class program
{
Static void MyMethod(out MyClass f1,out int f2)
{
f1 = new MyClass();
f1.Val=25;
f2 =15
}
Static void Main()
{
Myclass A1 =null;
int A2;
MyMethod(out A1,out A2);
}
}
out与ref区别:
out 把方法内的值传到外边 方法内必须要对out参数重新赋值,调用方法前不需要赋初值,但必须要声明。
ref 既可以把值传进方法内,也可以传到方法外,在调用方法之前必须先对ref参数赋初值,在方法内不需重新赋值。
2) 值类型与引用类型
值类型只需要一段单独的内存,用于存储实际的数据
引用类型需要两段内存:
第一段存储实际的数据,它总是位于堆中。
第二段是一个引用,指向数据在堆中的存放位置。
2012年4月11日星期三自习笔记
1) 什么叫静态方法和实例方法?
实例方法,就是对象的方法,静态方法,是类的方法。
例:
class Test
{
public static int add(int i,int j){}//静态方法,即不需要实例化一个对象就可以直接调用。
public void remove(){}//实例方法,需要产生一个对象才能调用。
}
调用时,Test.add();new Test().remove();
编程的时候应该有一个内存模型的概念。
静态方法不属于任何一个对象,它直属于类的方法,静态方法不能调用非静态的方法,因为这时的实例方法还没有分配地址。是NULL
实例方法必须产生一个对象才能调用,非静态方法可以调用静态方法,不过这个没有多大意义。
2012年4月12日星期四第九天上课笔记
1) 设置前景色
Console.ForegroundColor =ConsoleColor.Cyan;
重置前景色
Console.ResetColor();
2) 生成随机数
System.Random x =new Random ();
int m = x.Next(1, 7);//生成1到6之间包含1和6的数字
3) Console.ReadKey(true);//当参数为true时,在控制台上不显示输入的任意键,参数为false时,在控制台上显示输入的任意键
2012年4月13日星期五第十天上课笔记
1) 判断输入的数字是否在min和max之间的方法
static int ReadInt(string msg, int min, int max)
{
while (true)
{
try
{
Console.WriteLine(msg);
int number = Convert.ToInt32(Console.ReadLine());
if (number >= min && number <= max)
{
return number;
}
else
{
Console.WriteLine("你的输入不合法!只能输入{0}到{1}之间的数字!", min, max);
continue;
}
}
catch
{
Console.WriteLine("输入有误,请重新输入!");
}
}
//程序绝对走不到这里
}
2) String. Format方法
将指定的 String 中的每个格式项替换为相应对象的值的文本等效项。
用法:
string s=string. Format("{0}…, str);//生成一个字符串赋给s
3) 从键盘接收按键的输入,并做出反应,传说中的后门
publicstatic void BackDoor(refint i)
{
ConsoleKeyInfo myKey =Console.ReadKey(true);
if (myKey.Key==ConsoleKey.NumPad1)
{
myKey = Console.ReadKey(true);
if (myKey.Key==ConsoleKey.NumPad2)
{
myKey = Console.ReadKey(true);
if (myKey.Key==ConsoleKey.NumPad3)
{
i = 50;
}
}
}
}//判断组合键的输入
4) 类
[访问修饰符] class 类名
{
成员;
……
}
public class Person
{
成员;
}
对象有一些特征和行为,可以用属性和方法表示。
l 语法:类实例名 = new类();
类的实例化,用关键字new
l 类成员的访问
实例名.属性
实例名.方法名()
l 访问级别
访问修饰符:public、private、 internal、 protected 修饰符的访问权限
Private私有成员,在类的内部才可以访问
Public:公共成员,完全公开,没有访问限制
Internal:当前程序集内可以访问
Protected:保护成员,该类内部和继承类中可以访问。
类中字段和方法默认的访问修饰符是private
在类中如果方法加上static那么在我们的主函数中(不严谨)想调用这个方法,就用类名.方法名();就可以用这个方法了。
加上static后的方法,叫静态方法。
没加static的方法,叫实例方法。
静态方法只能访问静态字段
静态字段被类的所有实例共享,所有实例都访问同一内存位置。因此,如果该内存位置的值被一个实例改变了,这种改变对所有的实例都可见。
静态成员即使没有类的实例也存在。
5) 属性
属性是为了保护与之相对应的字段的.保证对字段的读取和赋值符合要求.
允许外部访问的变量一定要声明为属性。
属性是一个函数成员,不为数据存储分配内存,执行代码;
属性是指定的一组两个匹配的、称为访问器的方法;
Set访问器用于为属性赋值。
Get访问器用于从属性获取值。
Ctlt+R+E 快捷键根据字段自动生成属性
属性共有的任何地方都可以调用
字段私有的在本类中调用
属性可以控制只读只写读写
2012年4月14日星期六第十一天上课笔记
1) 类的实例构造函数
构造函数是用来创建对象的特殊方法,它在类的每个新实例创建的时候执行。
构造函数的名称和类名一样,不能有返回值,连void都不用
在创建对象的时候,构造函数用于初始化实例的状态。
如果希望能从类的外部创建类的实例,需要声明构造函数为public
class MyClass
{
public MyClass()
{
…
}
…
}
构造函数可以带参数。参数的语法与其他方法完全相同。
构造函数可以被重载,也就是有多个参数不同的构造函数。
如果在类的声明中没有显式地提供实例构造函数,那么编译器会提供一个隐式的默认构造函数,有以下特征:
→它不带参数。
→它的方法体为空。
如果程序员定义了一个或多个构造函数,那么编译器将不会为该类定义默认构造函数。
构造方法用来创建对象,并且可以在构造函数中对对象进行初始化。
构造函数可以有参数,new对象的时候传递函数参数即可
如果不指定构造函数,则类有一个默认的无参构造函数。如果指定了构造函数,则不再有默认的无参构造函数,如果需要无参构造函数,则需要自己来写。
2) 析构函数
程序结束后,调用析构函数。
析构函数(destructor)执行在类的实例被销毁之前需要的清理或释放非托管资源的行为。
3) param 需要学习一下
4) this关键字
this关键字在类中使用,是对当前实例的引用。
用在:
实例构造函数、实例方法、属性和索引的实例访问器
5) F12 快捷键转到定义处
6) 命名空间
用于解决类的重名问题,可以看作“类的文件夹”。
如果代码和被使用的类在一个namespace则不需要using,如果要使用的类和当前的类不在同一个namespace,则需要添加using引用。
在不同命名空间下的类调用有两种方法:
• 写全称 命名空间.类名
• 先using引用命名空间,再调用,不用再写全称了。
• using别名指令
using SC = System;//定义
SC.Console.WriteLine();//调用
如果想要调用其他项目的命名空间中的类,在此项目中添加其他项目的应用。如下图进行操作:
7) 字符串处理
• string可以看做是char的只读数组。char c = s[1];例子:遍历输出string中的每个元素。
• C#中字符串有一个重要的特性:不可变性,字符串一旦声明就不再可以改变。所以只能通过索引来读取指定位置的char,不能对指定位置的char进行修改。
• 如果要对char进行修改,那么就必须创建一个新的字符串,用s. ToCharArray()方法得到字符串的char数组,对数组进行修改后,调用new string(char[])这个构造函数(暂时不用细研究)来创建char数组的字符串。一旦字符串被创建,那么char数组的修改也不会造成字符串的变化。例子:将字符串中的A替换为a。
字符串的连接+,两边只要有一个是字符串类型,另一个也会被自动转换成字符串类型
一切类型都可用.ToString()方法转换成字符串。
• ToLower():得到字符串的小写形式。
• 注意字符串是不可变的,所以这些函数都不会直接改变字符串的内容,而是把修改后的字符串的值通过函数返回值的形式返回。s.ToLower()与s=s.ToLower()
• ToUpper():得到字符串的大写形式;
• Trim()去掉字符串两端的空白。
• s1.Equals(s2, StringComparison.OrdinalIgnoreCase),两个字符串进行比较不区分大小写的比较。
• string[] s= str.Split(params char[] separator):将str字符串按照指定的分割符separator分割为字符串数组,separator可以为char数组;
• string[] s= str.Split(char[] separator, StringSplitOptions.options)将str.字符串按照指定的分割符separator分割为字符串数组( options取RemoveEmptyEntries的时候移除结果中的空白字符串);`
8) 对象的引用
Int datetime bool char等类型都属于值类型(valueType),赋值的时候是传递拷贝。
普通的对象则是引用类型,赋值的时候是传递引用。
方法间传递引用。
9) 继承
语法实例:
class A
{
public void Sum(int i,int j)
{
int sum = i + j;
Console.WriteLine("I am A ,my sum ={0}",sum);
}
}
class B : A //B类继承A类
{
public void Minus(int i,int j)
{
int minus = i - j;
Console.WriteLine("I am B ,my minus ={0}", minus);
this.Sum(3, 4);
}
}
class InheritanceTest1
{
static void Main(string[] args)
{
B b = new B();
b.Minus(3, 4);
Console.Read();
}
}
在继承时需要注意的问题:
可以把基类引用指向子类的空间,但声明的基类不具有子类的属性和方法。
不可以把子类的引用指向基类的空间。
更不可以把子类的引用指向其他子类的空间。
具体细节问题参见.NET C#继承与派生类细解
定义类的时候不指定父类,则父类是Object类。Object类是任何类的直接或者间接父类。
10) 异常与异常处理
举例如下:
static void Main(string[] args)
{
#region 抛异常练习
try
{
string str =JuAge(30);
Console.WriteLine(str);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message+ex.StackTrace);
//ex.Message显示错误的信息(可以自定义),ex.StackTrace报告错误的位置
}
#endregion
Console.ReadKey();
}
static string JuAge(int i)
{
if (i > 100)
{
throw new Exception("你升仙了吧");//可以自定义抛出的错误信息
}
else if (i > 0)
{
return "人类";
}
else
{
throw new Exception("你穿越了!");
}
}
Exception ex异常也是对象
发生异常后程序默认就退出了,try代码块中的后续代码不会被执行。Catch以后的代码则会继续执行。
不要吃掉异常,一般情况下不需要处理异常。
2012年4月15日星期日自习
1) 常量
const常量。常量名要大写。一定不会变化的值才能声明为常量。不可变的凉。
语法:
public const double pi=3.14;
public const 不用new一个类就可以直接调用。
2) 静态成员
不用new一个对象就能使用。
全局变量。Static类变量。
可以声明方法,字段
关键词:static
在static方法中可以调用其他static成员,但不能调用非static成员。
在非static方法中可以调用static成员。
静态类:不能被new的类就是静态类。一般用来实现一些函数库。
3) 索引器
索引器是一种特殊的类成员,它能够让对象以类似数组的方式来存取,使程序看起来更为直观,更容易编写。
1、索引器的定义
C#中的类成员可以是任意类型,包括数组和集合。当一个类包含了数组和集合成员时,索引器将大大简化对数组或集合成员的存取操作。
定义索引器的方式与定义属性有些类似,其一般形式如下:
[修饰符]数据类型 this[索引类型 index]
{
get{//获得属性的代码}
set{ //设置属性的代码}
}
修饰符包括 public,protected,private,internal,new,virtual,sealed,override, abstract,extern.
数据类型是表示将要存取的数组或集合元素的类型。
get 访问器返回值。 set访问器分配值。
索引器类型表示该索引器使用哪一类型的索引来存取数组或集合元素,可以是整数,可以是字符串;this表示操作本对象的数组或集合成员,可以简单把它理解成索引器的名字,因此索引器不能具有用户定义的名称。例如:
class Z
{
//可容纳100个整数的整数集
private long[] arr = new long[100];
//声明索引器
public long this[int index]
{
get
{ //检查索引范围
if (index < 0 || index >= 100)
{
return 0;
}
else
{
return arr[index];
}
}
set
{
if (!(index < 0 || index <= 0))
{
arr[index] = value;
}
}
}
2、索引器的使用
通过索引器可以存取类的实例的数组成员,操作方法和数组相似,一般形式如下:
对象名[索引]
其中索引的数据类型必须与索引器的索引类型相同。例如:
Z z=new z();
z[0]=100;
z[1]=101;
Console.WriteLine(z[0]);
表示先创建一个对象z,再通过索引来引用该对象中的数组元素。
3、接口中的索引器
在接口中也可以声明索引器,接口索引器与类索引器的区别有两个:一是接口索引器不使用修饰符;二是接口索引器只包含访问器get或set,没有实现语句。访问器的用途是指示索引器是可读写、只读还是只写的,如果是可读写的,访问器get或set均不能省略;如果只读的,省略set访问器;如果是只写的,省略get访问器。
例如:
public interface IAddress
{
string this[int index]{get;set;}
string Address{get;set;}
string Answer();
}
表示所声明的接口IAddress包含3个成员:一个索引器、一个属性和一个方法,其中,索引器是可读写的。
4、索引器与属性的比较
索引器与属性都是类的成员,语法上非常相似。索引器一般用在自定义的集合类中,通过使用索引器来操作集合对象就如同使用数组一样简单;而属性可用于任何自定义类,它增强了类的字段成员的灵活性。
属 性 索 引 器
允许调用方法,如同公共数据成员 | 允许调用对象上的方法,如同对象是一个数组 |
可通过简单的名称进行访问 | 可通过索引器进行访问 |
可以为静态成员或实例成员 | 必须为实例成员 |
其get访问器没有参数 | 其get访问器具有与索引器相同的形参表 |
其set访问器包含隐式value参数 | 除了value参数外,其set访问器还具有与索引器相同的形参表 |
2012年4月16日星期一第十二天上课笔记
1) 字符串函数
字符串替换:string Replace(string oldValue, string newValue)将字符串中的出现oldValue的地方替换为newValue。例子:名字替换。
取子字符串:string Substring(int startIndex),取从位置startIndex开始一直到最后的子字符串;
string Substring(int startIndex, int length),取从位置startIndex开始长度为length的子字符串,如果子字符串的长度不足length则报错。
bool Contains(string value)判断字符串中是否含有子串value
bool StartsWith(string value)判断字符串是否以子串value开始;
bool EndsWith (string value)判断字符串是否以子串value结束;
int IndexOf(string value)取子串value第一次出现的位置。如果没找到返回-1,如果找到返回索引。
Int IndexOf(string value,int startIndex)从startIndex下标开始,取子串value第一次出现的位置。如果没找到返回-1,如果找到返回索引。如果startIndex超出索引范围,则会报错。
String string.Remove(int startindex,int count);
从指定的索引开始一只删除到最后,这是一个参数的时候
还有一种从指定的索引开始,删除几个
Array.Reverse(s);//反转字符串顺序
string[]str=System.IO.File.ReadAllLines("book.txt",Encoding.Default);//按行读取txt文件中的内容到string数组中
char[] ch=str.ToCharArray();
Array.Reverse(ch);
string s = new String(ch);//将字符数组转换成字符串,用String类的构造函数。
2) Winform
控件:窗口上很多元素都是相似的,因此将这些元素抽象为一些类,这些类就叫做控件。按钮(button)、文本框(textbox)、标签(label)、单选按钮(radiobutton)、复选框(checkbox)
当用户点击按钮的时候Buttton1_click方法被调用,这个方法不是程序员调用的,而是程序员把方法写好,并且说明“当用户点击按钮的时候执行Button1_click方法中的代码”,这一点和控制台程序不同。
bool r = name.Equals("admin", StringComparer.OrdinalIgnoreCase);//比较字符串,不区分大小写
2012年4月17日星期二第十三天上课笔记
1) 继承和构造函数
在student后面加上一个冒号:person,表示student是Person的子类,继承person。
在Person中可以有构造函数,子类中也可以有构造函数
继承父类的构造函数,用关键字base,举例如下:
public Student(string name,char sex, int age)
: base(name, sex, age)
{
this.Name = name;
this.Sex = sex;
this.Age = age;
}
把name,sex,age传给父类中的构造函数
第一如果子类继承父类,可以用到父类的字段或者属性,通过一个有参的构造函数再用一个关键字base()把参数传过去,子类就能用到父类的构造函数,然后间接的给父类的字段赋值。
当基类中编写构造函数时,派生类没有指定调用构造哪个构造函数时,会寻找无参的构造函数,如果没有则报错,另外无论调用派生类中的哪个构造函数都是寻找无参的那个基类构造函数,而非参数匹配。
2) Shift+alt+f10 Ctrl + . 自动生成using,引用相应的命名空间。
3) 对象类型转换
子类可以隐式的转换成父类,
Person p=new teacher();
父类可以显示转换成子类
里氏转换原则:
→Is语法:
布尔类型变量=对象或实例 is类型名
检查对象是否与给定类型兼容。
Person zsp= new person();
Student stu = new student();
Bool b= stu is person;//常常用来判断父类是否能转换成子类,若可以转换,返回true,不可以转换,返回false。
if (cls1 is Class2)
{
Class2 cls2 = (Class2)cls1;
}
else
System.Console.WriteLine("Error 2!");
→as语法:
类型名变量名 =某个对象或实例as 类型名;
Class2 cls2 = cls1 as Class2;
if (cls2!=null)
System.Console.WriteLine("Ok");
else
System.Console.WriteLine("Error!");
as稍微不同,它检查引用对象是否兼容,如果不兼容则返回null,因此需要做null的判断。如果兼容,则cls1转换成Class2类型。
对比两种方式,is需要做两次对象的类型检查,而as需要做一次对象类型检查,再加一次null的检查,而null检查开销比对象类型检查少。相对as的方法效率高些。
父类转子类要通过强转.为了不出错,可以先通过is判断或用as转换.
as 运算符类似于强制转换操作。但是,如果无法进行转换,则 as返回 null 而非引发异常。
4) 集合
ArrayList元素的增加、插入、删除、清空、
增加 . arry.Add(23);
插入 arry.Insert(3, true);
删除 arry.Remove('$');
清空 arry.Clear();
排序 arry.Sort();
反转 arry.Reverse();
数组与集合的区别:
一:数组声明了它容纳的元素的类型,而集合不声明。这是由于集合以object形式来存储它们的元素。
二:一个数组实例具有固定的大小,不能伸缩。集合(包括泛型)则可根据需要动态改变大小。
三:数组是一种可读/可写数据结构没有办法创建一个只读数组。然而可以使用集合提供的ReadOnly方 只读方式来使用集合。该方法将返回一个集合的只读版本。
5) Hashtable
哈希表,名-值对。类似于字典(比数组更强大)。哈希表是经过优化的,访问下标的对象先散列过。如果以任意类型键值访问其中元素会快于其他集合。
在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似key/value的键值对,其中key通常可用来快速查找,同时key是区分大小写;value用于存储对应于key的值。Hashtable中keyvalue键值对均为object类型,所以Hashtable可以支持任何类型的keyvalue键值对.
在哈希表中添加一个key/键值对:HashtableObject.Add(key,);
在哈希表中去除某个key/键值对:HashtableObject.Remove(key);
从哈希表中移除所有元素: HashtableObject.Clear();
判断哈希表是否包含特定键key: HashtableObject.Contains(key);
遍历哈希表需要用到DictionaryEntry Object,代码如下:
foreach(DictionaryEntry de in ht) //ht为一个Hashtable实例
{
Console.WriteLine(de.Key);//de.Key对应于key/键值对key
Console.WriteLine(de.Value);//de.Key对应于key/键值对
}
foreach(string de in ht.keys)
{
Console.WriteLine(de);//de.Key对应于key/键值对key
Console.WriteLine(ht[de]);//de.Key对应于key/键值对
}
对哈希表进行排序在这里的定义是对key/键值对中的key按一定规则重新排列,但是实际上这个定义是不能实现的,因为我们无法直接在Hashtable进行对key进行重新排列,如果需要Hashtable提供某种规则的输出,可以采用一种变通的做法:
ArrayList akeys=new ArrayList(ht.Keys); //别忘了导入System.Collections
akeys.Sort(); //按字母顺序进行排序
foreach(string skey in akeys)
{
Console.Write(skey+ ":");
Console.WriteLine(ht[skey]);//排序后输出
}
其实hastable就像是一个特殊的数组,它有一个类似主键的唯一编号(类似数组[]中的数字,这个键值是你随便写的),和这个唯一编号又对应一个值value(值的数据类型是不受限制的)
2012年4月18日星期三
1) Winform
文本框的几种模式:Multiline(多行),PassworChar(密码)
退出程序this.Close()或Application.Exit()
在多行的文本框中换行,加”\r\n”。
可以批量修改控件的属性
string[] str1 = textBox1.Lines;//获取文本框控件中的文本行
2012年4月19日星期四第十四天上课笔记
1) foreach
只要实现IEumerable接口,就能用foreach实现循环。
2) Join
String.Join(“|”,str); 把|插入到str数组中,然后返回插入后的字符串
3) 泛型
List<string> mylist=new List<string>();
集合可放任意类型的元素,会自动增大,取出时要做类型转换
泛型集合只能放定义类型的元素,会自动增大,取出时不用做类型转换
数组只能放定义类型的元素,不会自动增大,取出时不用做类型转换
泛型与集合的区别
泛型听起来很高深的一个词,但实际上它的作用很简单,就是提高c#程序的性能。
比如在计算机中经常用到一些数据结构,如队列,链表等,而其中的元素以前一般这么定义:object a=new object();
这样就带来一个严重的问题,用object来表示元素没有逻辑问题,但每次拆箱、封箱就占用了大量的计算机资源,导致程序性能低下,而这部分内容恰恰一般都是程序的核心部分,如果使用object,那么程序的表现就比较糟糕。
而使用泛型则很好的解决这个问题,本质就是在编译阶段就告诉编译器,数据结构中元素的种类,既然编译器知道了元素的种类,自然就避免了拆箱、封箱的操作,从而显著提高c#程序的性能。
比如List<string>就直接使用string对象作为List的元素,而避免使用object对象带来的封箱、拆箱操作,从而提高程序性能。
普通集合相对是弱类型从中取数据需要转换类型,
泛型是强类型,定义的时候就已经声明类型了,取数据不需要转换类型,比较安全,不用拆箱,装箱,效率比较高。
4) 字典
Dictionary<string,string> mydic= new Dictionary<string,string>();
表示键和值的集合。Dictionary遍历输出的顺序,就是加入的顺序,这点与Hashtable不同
Bool result=mydic.ContainsKey(ch[i].ToString());//判断字典里是否包含这个键,若有返回true,没有则返回false,集合和字典里要活用contains能获的事半功倍的效果
5) 文件的读写
读取文本文件的内容,字符串数组:
string[] str = System.IO.File.ReadAllLines(@"d:/1.txt", Encoding.Default);
读取文本文件的内容,字符串数组:
string[] str = System.IO.File.ReadAllText(@"d:/1.txt", Encoding.Default);
复制文件:
System.IO.File.Copy(@"d:/1.txt", @"E:/1.txt",true);//true覆盖同名文件,若为false不覆盖同名文件
创建文件
File.Create(@"d:/1.txt");
删除文件
File.Delete(@"d:/1.txt");
确定指定文件是否存在?
File.Exists(@"d:/1.txt");
移动文件
File.Move(@"d:/1.txt", @"E:/1.txt");
打开文件
File.Open(@"d:/1.txt", @"E:/1.txt");
写文件,字符串数组
File.WriteAllLines(@"d:/1.txt", Encoding.Default);//可指定文件的编码格式
写文件,字符串数组
File.WriteAllText(@"d:/1.txt", Encoding.Default);
追加文件
File.AppendAllText(@"d:/1.txt",str);
6) 文件流
StreamReader;
StreamWriter;
7) 文件夹操作
创建文件夹
Directory.CreateDirectory(@"f:\练习");
查找某个文件夹里所有的文件名,并返回文件名字符串数组
String[] str=Directory.GetFiles(@"f:\练习1");//可以查看隐藏的文件
获取程序的当前工作目录
string s=Directory.GetCurrentDirectory();
8) 局部变量每次运行完毕变量的值都会被销毁,下次再运行,会重新初始化。而类字段,只要是一个对象,那么只要对象不销毁,就会一直保持对象的字段值。
2012年4月20日星期五第十五天上课笔记
1) 多态(以后学习)
虚方法
Public virtual void Say() //父类虚方法,虚方法关键词virtual
{}
Public override void Say() //重写父类方法,重写方法关键词override
{}
如果父类中有虚方法,同名的子类的方法要有override,重写此方法。
抽象方法
Abstract class Dog
{
Abstract public void Jiao();
}
抽象方法必须出现在抽象类中。
抽象类不能实例化
抽象类就像是中央的指导方针啊,地方各级政府根据指导方针制定的实施细则就是抽象类的派生类啊。
政策在执行时,具体根据的实施办法可能是由不同级别政府颁布的,相当于同一件事情在不同环境下处理结果是不同的,这就是多态啊。
2) 装箱拆箱
装箱是一种接受值类型的值,根据这个值在堆上创建一个完整的引用类型对象并返回对象引用的隐式转换
装箱创建一份副本,在装箱产生之后,有两份值—原始值类型和副本的引用类型,每一个都可以独立操作。
拆箱转换
拆箱(unboxing)是把装箱后的对象转换回值类型的过程。
拆箱是显式转换
系统在把值拆箱成值类型(ValueTypeT)时执行了如下的步骤:
它检测到要拆箱的对象实际是ValueTypeT的装箱值。
它把对象的值复制到变量。
3) 序列化 二进制流(以后学习)
2012年4月22日星期日自习笔记
1) 隐藏基类的成员
要隐藏一个继承的数据成员,需要声明一个新的相同类型的成员,并使用相同的名称。
通过在派生类中声明新的带有相同签名的函数成员,可以隐藏或掩盖继承的函数成员。
要让编译器知道你在故意隐藏继承的成员,使用new修饰符。没有它,程序可以成功编译,但编译器会警告你隐藏了一个继承的成员。
派生类需要访问被隐藏的继承成员。可以使用基类访问表达式访问隐藏的基类成员。基类访问表达式由关键字base后面跟着一个点和成员的名称组成。
举例如下:
class Person
{
public string name="Person";
public void Say()
{
Console.WriteLine("你?好?,ê?我¨°是º?{0},ê?是º?父?类¤¨¤",name);
}
}
class Student : Person
{
new public string name="Student";
new public void Say()
{
Console.WriteLine("你?好?,ê?我¨°是º?{0},ê?是º?子Á¨®类¤¨¤", name);
Console.WriteLine("你?好?,ê?我¨°是º?{0},ê?是º?父?类¤¨¤", base.name);
}
}
class Program
{
static void Main(string[] args)
{
Student stu = new Student();
stu.Say();
Console.ReadKey();
}
}
使用对象的基类部分的引用访问对象,当使用基类引用访问派生对象时,得到的是基类的成员。
class Program
{
static void Main(string[] args)
{
Student stu = new Student();
Person per = (Person)stu;
per.Say();
Console.ReadKey();
}
}
2) 虚方法、覆写方法
虚方法可以使基类的引用访问“升至”派生类内
可以使用基类引用调用派生类(derived class)的方法,只需满足下面的条件
派生类的方法和基类的方法有相同的签名和返回类型
基类的的方法使用virtu标注、
派生类的方法使用override标注
class Person
{
public string name = "Person";
virtual public void Say()
{
Console.WriteLine("你?好?,ê?我¨°是º?{0},ê?是º?父?类¤¨¤", name);
}
}
class Student : Person
{
new public string name = "Student";
override public void Say()
{
Console.WriteLine("你?好?,ê?我¨°是º?{0},ê?是º?子Á¨®类¤¨¤", name);
}
}
class Program
{
static void Main(string[] args)
{
Student stu = new Student();
Person per = (Person)stu;
stu.Say();
per.Say();
Console.ReadKey();
}
}
注意:
覆写和被覆写的方法必须具有相同的可访问性。换一种说法,被覆写的方法不能使private等,而覆写方法是publi
不能覆写static方法或非虚方法
方法、属性、索引和事件,它们都可以被声明为virtual何override。
覆写标记为override的方法
覆写方法可以再继承的任何层次出现
当使用对象基类部分的引用调用一个覆写方法时,方法的调用被沿派生层次上溯执行,一直到标记为override的方法的最派生(most-derived)版本
如果在更高的派生级别有该方法的其他声明,但没有被标记为override,那么它们不会被调用。
3) 抽象成员
抽象成员是被设计来被覆写的函数成员。有以下特征:
它被用abstract修饰符标记
它没有实现代码块。抽象成员的代码块被分号代替。
语法:
abstract public void PrintStuff(string s);
abstract public int MyProperty
{
get;
set;
}
注意:
尽管抽象方法必须在派生类中用相应的方法覆写,但不能把virtual修饰符附加到abstract修饰符。
就像虚方法,派生类中抽象方法的实现必须指定override修饰符
抽象成员只能被声明在抽象类中。
4) 抽象类
抽象类只能被用作其他类的基类。抽象类就是被设计来继承的。
不能创建抽象类的实例
抽象类使用abstract修饰符声明
语法:
abstract class MyClass
{…}
抽象类可以包含抽象成员,但不是必须的。抽象类的成员可以是抽象成员和普通带实现的成员的任意组合。
抽象类自己可以派生自另一个抽象类。
任何派生自抽象类的类必须使用override关键字实现该类所有的抽象成员,除非派生类自己也是抽象类。
abstract class Person
{
public void Print()
{
Console.WriteLine("我¨°是º?普?通ª¡§方¤?法¤¡§");
}
abstract public void AbPrint();
}
class Student:Person
{
public override void AbPrint()
{
Console.WriteLine("我¨°是º?抽¨¦象¨®方¤?法¤¡§");
}
}
class Program
{
static void Main(string[] args)
{
Student stu = new Student();
stu.Print();
stu.AbPrint();
Console.ReadKey();
}
}
5) 接口
接口是表示一组函数成员而不实现成员的引用类型。其他类型-类和结构可以实现接口。
要实现接口,类或结构,必须做两件事情:
必须在基类列表后面列出接口名称。
必须为接口提供每一个成员的实现。
namespace 接¨®口¨²
{
class MyClass : IComparable//继¨¬承D接¨®口¨²
{
public int value;
public int CompareTo(object obj)//实º¦Ì现?接¨®口¨²中D的Ì?方¤?法¤¡§
{
MyClass objClass = (MyClass)obj;
if (this.value > objClass.value)
{
return 1;
}
if (this.value < objClass.value)
{
return -1;
}
return 0;
}
}
class Program
{
static void Main(string[] args)
{
int[] intArray = new int[5] { 1, 34, 23, 2, 45 };
MyClass[] classArray = new MyClass[5];//数ºy组Á¨¦对?象¨®的Ì?实º¦Ì例¤y化¡¥
for (int i = 0; i < intArray.Length; i++)
{
classArray[i] = new MyClass();//数ºy组Á¨¦中D具?体¬?某3个?对?象¨®的Ì?实º¦Ì例¤y化¡¥
classArray[i].value = intArray[i];
}
Array.Sort(classArray);
foreach (var item in classArray)
{
Console.WriteLine(item.value);
}
Console.ReadKey();
}
}
}
1. 接口声明
接口声明不包含数据成员。
接口声明只能包含如下类型的静态成员函数的声明:
方法
属性
事件
索引
这些函数成员的声明不能包含任何实现代码,而在每一个成员声明的主体后必须使用分号。
按照惯例,接口名称必须从大写的I开始(比如ISaveable)
2. 语法:
interface IMyInterface1
{
int DoStuff(int nVar1,long lVar2);
double DoOtherStuff(string s,long x);
}
接口声明可以有任何的访问修饰符public,protected,internal,private
然而,接口的成员是隐式public的,不允许有任何访问修饰符,包括public
public interface IMyInterface2
{
private int Method1(int nVar1,long lVar2);//错误
}
3. 实现接口
如果类实现了接口,它必须实现接口的所有成员。
如果类从基类继承并实现接口,基类列表中的基类名称必须放在任何接口之前,如下所示:
class Derived : MyBaseClass,IIfc1,IEnumerable,IEnumerator
{
…
}
→接口的简单示例
interface IMyInterface//声¦¨´明¡Â接¨®口¨²
{
void Print(string value);
}
class MyClass1 : IMyInterface
{
public void Print(string vl)
{
Console.WriteLine("我¨°是º?{0}",vl);
}
}
class Program
{
static void Main(string[] args)
{
MyClass1 mc1 = new MyClass1();
mc1.Print("霍?达ä?");
Console.ReadKey();
}
}
4. 接口是引用类型
我们不能直接通过类对象的成员访问接口。然而,我们可以通过把类对象引用强制转换为接口类型来获取指向接口的引用。一旦有了接口的引用,我们就可以使用点号来调用接口的方法。
IMyInterface mi1 = (IMyInterface)mc1;
mi1.Print("接¨®口¨²");
5. 实现多个接口
类或结构可以实现任意数量的接口
所有实现的接口必须列在基类列表中并以逗号分割(如果有基类名称,则在其后)
=========================================================================
WinForm基础
2012年4月21日星期六上课笔记
1) 下拉列表
ComboBox
在属性Items设置下拉列表的值
在属性DropDownStyle设置下拉列表的功能
→DropDownList//只能选择不能输入,禁止用户编辑
→DropDown既可以输入也可以选择
.SelectedItem//返回的值为下拉列表的选择的值
.SelectedIndex//返回下拉列表选择项的索引
SelectedIndexChanged事件:下拉列表响应选择改变事件
.Items.Clear()//清理下拉列表中的内容
.Items.Add(i)//向下拉列表添加内容
2) 实现按钮(Button)透明
设置按钮的属性,首先就BACKCOLOR,将其设置为WEB的Transparent,另外就是FLATSTYLE这个属性,要设置为POPUP,加起来就可以实现透明效果。
3) 了解常见控件的属性与事件
-> 什么事属性
就是控件的特征
-> 什么事事件
现在可以认为是控件的行为,有点儿像方法
4) 常见属性
默认按钮
AcceptButton 设置默认焦点
CancelButton
背景的属性
backgroundColor
BackgroundImage
BackgroundLayout
修改光标
Cursor
修改显示文本
Text
控制最大化最小化与关闭的按钮
ControlBox
窗体上所有控件的字体
Font
窗体上所有控件的颜色
ForeColor
窗体边框
FormBorderStyle
-> FixedSingle
-> None
标题栏的Icon图标
Icon
设定窗体位置
Location
最大化与最小化
MaximumBox
MinmumBox
关闭按钮灰色
protected override CreateParams CreateParams
{
get
{
int CS_NOCLOSE = 0x200;
CreateParams parameters = base.CreateParams;
parameters.ClassStyle |= CS_NOCLOSE;
return parameters;
}
}
是否显示Icon图标
ShowIcon
是否在Windows下边的任务栏显示
ShowInTaskBar
开始的位置
StartPosition
-> CenterScreen
-> Manual
是否总是前端显示
TopMost
窗体的状态
WindowState
-> 最大化、最小化、一般
5) Button的属性
(Name)
表示在程序中引用控件的名字
是否可用
Enable
是否显示出来
Visible
使用Tab键切换序号
TabIndex
禁用Tab切换获得焦点
TabStop
6) Button的事件
将按钮的事件看做成他做的一件事儿
-> 一点
-> 做
如何添加事件?
-> 选中控件 -> 右键 -> 属性 -> “闪电”的标志
-> 根据所要的事件,找到相应的选项(使用button默认以Click为例)
-> 在Click后面的文本框中双击
-> 自动的生成一个方法
-> 当Click事件触发的时候(就是点击按钮)就会去执行这个方法
7) MessageBox
MessageBox实际上是一个类,提供Show这样的静态方法,用来显示信息
有几个重载
MessageBox.Show(要显示的字符串);
MessageBox.Show(要显示的字符串, 标题栏显示的字符串);
MessageBox.Show(要显示的字符串, 标题栏显示的字符串, 默认使用的按钮);
MessageBox.Show(要显示的字符串, 标题栏显示的字符串, 默认使用的按钮, 使用的图标);
MessageBox.Show(要显示的字符串, 标题栏显示的字符串, 默认使用的按钮, 使用的图标, 默认按钮的枚举);
8) 控件的默认事件
每一个控件都有自己的默认事件,添加默认事件只用双击控件即可
双击会添加默认事件,常见的就是Click与Load
9) 如果要删除事件的方法,不能直接删除代码,需要重置事件。
10) 用代码调用一个按钮的单击事件
button1_Click(null, null);
==================================
2、弄清楚"(Name)属性"与Text属性
(Name) 就是使用该控件时,表示这个控件,好像变量一个(实际是一个字段)
Text 是控件上面显示的文本信息
3、常用事件
Load事件
窗体一加载之前执行的方法
...Changed事件
当某一个属性发生变化的时候,执行的方法
鼠标事件
MouseClick
MouseDoubleClick
MouseEnter
MouseLeave
MouseMove
MouseDown
MouseUp
4、窗体的创建
窗体实际上是一个Form的子类对象
-> 创建窗体,首先要new
-> 显示使用Show或ShowDialog方法
-> Show表示显示窗体
-> ShowDialog表示模态窗体,当窗体出现的时候,该主窗体不再可获得焦点
,除非这个模态窗体结束。
ShowDialog有返回值, 该值指定活动被接受还是被取消。 返回值是 DialogResult 属性在窗口关闭前具有的值,DialogResult是一个枚举,包含None,OK,Cancel,Abort,Retry,Ignore,Yes,No。
当 Window 类实例化时,默认情况下是不可见的。 ShowDialog 显示窗口,禁用应用程序中的所有其他窗口,并且仅在窗口关闭后才返回。 这种类型的窗口称为“模式”窗口。
模式窗口主要用作对话框。对话框是一种特殊类型的窗口,应用程序使用它们与用户交互以完成任务,例如打开文件或打印文档。对话框通常允许用户在关闭对话框之前接受或取消向其显示的任务。
焦点:是当前光标被激活的位置,也就是当前的操作对象,是哪个控件被选中,可以被操作;比如一个文本框获得焦点,你在键盘上敲进的字符就直接进入了文本框;还比如一个下拉式列表框获得焦点,你按下键盘上的向下箭头,它就会把列表列出来。程序中还有获得焦点发生的事件(gotfocus())和失去焦点发生的事件(lostfocus())以及为控件设置焦点方法(setfocus())。利用好焦点,能使你的程序显得非常人性化。
5、练习
-> 窗体上有三个按钮
-> 开始只有一个按钮可以按下,表示创建窗体
-> 创建窗体以后,该按钮不能再被按下
-> 另外两个按钮可以按下,分别表示显示窗体域隐藏窗体
=================
窗体就是一个窗体类
6、销毁窗体使用(成对使用)
<windowName>.Close();
<windowName>.Dispose();
7、对话框的返回值
Dialog有关的窗体都可以有返回值
DialogResult result = MessageBox.Show("确定关闭吗?", "警告", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
根据现实的MessageBox的结果来判断是否做什么动作
-> 如何获得用户的按下按钮是哪一个?
-> MessageBox.Show()方法会将用户的选择返回
result== System.Windows.Forms.DialogResult.Cancel
MessageBox.Show中可选的按钮有:
重试、OK、放弃、忽略、取消、是、否、终止、...
返回值:DialogResult
9、自定义窗体的位置
-> 创建一个主窗体,和一个按钮与子窗体
-> 设定子窗体的StartPosition为Manul,表示自定义位置
-> 为子窗体添加构造函数,传入两个坐标X,Y
-> 在构造函数中为子窗体的Location赋值
10、Label和LinkLabel
System.Diagnostics.Process.Start(//在这里可以执行系统带的程序);
2012年4月23日星期一
1) textbox
属性:
ScrollBars属性:滚动条
→Horizontal横条
→Vertical竖条
→Both横竖都有
WordWrap属性:自动换行
PasswordChar属性:密码输入显示的字符
MultiLine属性:多行显示
MaxLength属性:文本最大的长度
事件:
TextChanged
KeyPress
→e.Handle如果为true表示,按键无效,如果为false,表明按键有效
→e.KeyChar 按下的字符对应的ASCII码(Unicode码)
Enter 控件获得焦点
Leave 失去焦点
2) Char.IsDigit(字符);//判断字符是否是十进制数字
1、属性、事件
既然WinForm有面向对象的特征,可以知道每一个子类都具有相似的特征,所以使得父类,具有大量的属性与事件
2、WinForm与面向对象的一个关系
由于每一个窗体外观都是一致的,所以可以考虑每一个Windows应用程序,肯定有一个模板
但是每一个窗体都有一些特有的功能
每一个窗体都有一个父类,提供工作区、蓝色的标题栏,以及控制的按钮
所有的窗体都是他的子类,提供自己独有的功能和相关控件
3、 每一个窗体
class MyWinForm:Form
{
// 子类窗体独有的东西
}
4、写Windows程序的一般步骤
-> 拖控件,设属性
-> 为相应的控件添加所需事件(加事件)
-> 写方法
5、如何创建和控制窗体
-> 右键添加窗体
-> 设定窗体的属性与事件
-> new窗体,Show窗体
7、添加事件
-> 直接双击控件
-> 选择事件,双击事件上的空
-> 直接在事件边上的空中,添加事件方法的名字
=======================================================
2、PictureBox
Image属性处理添加图片
SizeMode属性,对图片进行布局
如何通过代码来显示图片,或切换图片
picImage.Image = Image.FromFile(“//图片路径”);//设置图片
3、DateTime
Now 获得当前时间
Year
Month
Day
Hour
Minitue
Second
4、Timer控件
-> 拖控件
-> 谁定Enable属性 Timer.Close()停止计时,Timer.Start()开始计时
-> 设定时间间隔,单位为毫秒,1000毫秒等于1秒
-> 设定事件
-> 每当到达计时器所表示的时间间隔就执行一次方法
5、SoundPlayer类//播放音乐
Program.cs文件中的application.Run()
Main方法调用Application.Run时,创建了MainForm类的一个实例作为参数。这样就指定了当前应用程序的主窗体为MainForm窗体对象,即用MainForm窗体对象来管理当前应用程序消息循环。Application.Run方法同时指定窗体对象可见,并显示它。
比较经典的为C# Winform程序设置登录窗体先启动,成功后再启动主窗口。修改项目的Program.cs文件 static class Program { Application.EnableVisualStyles(); //Login成功后添加此代码: this.DialogResult = DialogResult.OK; |
图片查看器
仿QQ登陆界面
优化图片飘飘的算法
C#基础结束!!!
---------------------- <a href="http://net.itheima.com/" target="blank">Windows Phone 7手机开发</a>、<a href="http://net.itheima.com/" target="blank">.Net培训</a>、期待与您交流! ----------------------