黑马程序员—C#系列 (三)
来源:互联网 发布:stata面板数据ols回归 编辑:程序博客网 时间:2024/05/16 02:20
---------------------- ASP.Net+Android+IO开发S、.Net培训、期待与您交流! ----------------------
属性:
惯用法:属性开头字母大写,字段开头字母小写
构造函数:
1) 构造函数用来创建对象,并且可以在构造函数中对对象进行初始化。
2) 构造函数是用来创建对象的特殊函数,函数名和类名一样,没有返回值,连void都不用。
3) 构造函数可以有参数,new对象的时候传递函数参数即可
4) 构造函数可以重载,也就是有多个参数不同的构造函数。
5) 如果不指定构造函数,则类有一个默认的无参构造函数。如果指定了构造函数,则不再有默认的无参构造函数,如果需要无参构造函数,则需要自己来写。
6) 构造函数的调用顺序(父子)
is运算
---------------------- ASP.Net+Android+IO开发S、.Net培训、期待与您交流! ----------------------
1.变量作用域
1) 变量的作用域是变量声明的最近一层的包着他的大括号
2) 两个函数之间无法访问各自内部定义的变量
3) 如果需要则需要通过参数传递
2.面向对象(OOP,Object-Oriented programming)
面向对象概念:
1) 面向对象的三个特性:封装、继承、多态
2) 类、对象:“人”是类,“张三”是“人”这个类的对象。类是抽象的,对象是具体的。按钮就是类,某个按钮就是对象。对象可以叫做类的实例(Instance)。类就像int,对象就像10
3) 字段Field(和某个对象相关的变量),字段就是类的状态(不同的对象可能不一样的状态就是字段)。人这个类有姓名、年龄、身高等字段。类不占内存,对象才占内存。字段描述对象特点的数据。眼睛的个数不能做为字段,因为所有人的眼睛个数都一样,没有差异性。
4) 方法Method(函数),方法就是类能够执行的动作,比如问好、吃饭等
5) 类的继承,类之间可以有继承关系,比如“电脑”类可以从“电器”类继承,这样的好处是“电脑”类只需要定义自己特有的字段、方法就可以,也就是只要定义内存大小、CPU型号这些字段或者弹出光驱等方法就可以。父类(Parent)、基类(Base,基业,祖宗十八代传下来的)。电脑类是电器类的子类(ChildClass)。重用。父类有的子类都有
1) 面向对象的三个特性:封装、继承、多态
2) 类、对象:“人”是类,“张三”是“人”这个类的对象。类是抽象的,对象是具体的。按钮就是类,某个按钮就是对象。对象可以叫做类的实例(Instance)。类就像int,对象就像10
3) 字段Field(和某个对象相关的变量),字段就是类的状态(不同的对象可能不一样的状态就是字段)。人这个类有姓名、年龄、身高等字段。类不占内存,对象才占内存。字段描述对象特点的数据。眼睛的个数不能做为字段,因为所有人的眼睛个数都一样,没有差异性。
4) 方法Method(函数),方法就是类能够执行的动作,比如问好、吃饭等
5) 类的继承,类之间可以有继承关系,比如“电脑”类可以从“电器”类继承,这样的好处是“电脑”类只需要定义自己特有的字段、方法就可以,也就是只要定义内存大小、CPU型号这些字段或者弹出光驱等方法就可以。父类(Parent)、基类(Base,基业,祖宗十八代传下来的)。电脑类是电器类的子类(ChildClass)。重用。父类有的子类都有
类:
class Person{ }
易错:类的定义中只能定义字段、方法等,不能直接写其他代码
一个类可有有多个实例,类就是把一系列相关的变量(状态)、行为定义为一个整体。字段记录的就是这个对象相关的数据。
访问级别:
public(任何地方都可以访问);private(默认级别。只能由本类中的成员访问)。还有internal、protected两个级别
永远不要把字段public,字段一般都是private,字段开头小写
调用者只能通过方法来请求对象改变它的状态,是否改变,改变多少是类自己决定的。这是为什么字段不能public的原因
对象的引用(非常重要):
int、decimal、bool、byte、enum等基础类型(值类型)是传递拷贝;对象(引用类型)则是传递引用。因为基础类型不怎么占内存,而对象则比较占内存
i1=3;i2=i1;i1++;//i2是3
为对象变量重新赋值。p2=p1是让p2指向p1指向的对象,函数间传递普通的类的对象也是引用传递
p1=new Person();p1.i=3;p2=p1;p1.i++;//p2.i是4
p1.height = 180;//修改p1指向的对象的height字段的值为180
Person p1 = new Person();//new的操作相当于根据类的定义在内存中创建一块独立的区域//所以两个对象修改各自的字段不受影响
Person p1 = null; //p1不指向任何的对象,//如果p1之前指向过对象,则切断p1和对象间的关系//以后如果碰到NullReferenceException,先看变量是不是指向了对象
值类型中,只有string可赋值为null,是个特例
惯用法:属性开头字母大写,字段开头字母小写
class Person { private int age; public int Age { get{return age;} set{age=value;} } public void SayHello() { Console.WriteLine("我的年龄是{0}",Age); } }例子:限制非法值的设置
private string job; public string Job //属性不会存储值,而是由相应的字段保存值 { get { //当读取Job属性的时候执行的代码 return job; } set { //和使用字段相比,用属性可以拒绝非法值 if (value == "waitor") { this.job = "大爷";//属性返回的值不一定非要存到私有字段中,怎么处理无所谓 return; } this.job = value;//value是设置的值,名字是固定的 //当设置Job属性的时候执行的代码 } }1)只用set或者只用get就可以定义只读或者只写属性
2) 字段和属性的区别是什么?
属性看似字段、不是字段,可以进行非法值控制,可以设置只读。
3) Net3.x简化set、get:
public int Age{get;set;}
适合于set、get中没有特殊逻辑代码的情况。允许外部访问的值一定要声明为属性。
4) set、get块内部其实就是get_***、set_***方法。
5) 用简写方式不能只有get或者只有set。不合理 逻辑不对,报错
常见错误: 不要在类定义中写多行代码,多行代码必须定义在方法中,只能在声明字段等地方调用一个有返回值的一行代码。
4) set、get块内部其实就是get_***、set_***方法。
5) 用简写方式不能只有get或者只有set。不合理 逻辑不对,报错
常见错误: 不要在类定义中写多行代码,多行代码必须定义在方法中,只能在声明字段等地方调用一个有返回值的一行代码。
1) 构造函数用来创建对象,并且可以在构造函数中对对象进行初始化。
2) 构造函数是用来创建对象的特殊函数,函数名和类名一样,没有返回值,连void都不用。
3) 构造函数可以有参数,new对象的时候传递函数参数即可
4) 构造函数可以重载,也就是有多个参数不同的构造函数。
5) 如果不指定构造函数,则类有一个默认的无参构造函数。如果指定了构造函数,则不再有默认的无参构造函数,如果需要无参构造函数,则需要自己来写。
6) 构造函数的调用顺序(父子)
7) 当对象被创建的时候(new)构造函数被执行
继承:
定义类的时候不指定父类,则父类是Object类。Object类是任何类的直接或者间接父类。所有类都是Object的子类
class Chinese : Person//: 后为父类的名字,一个类只能有一个父类
构造函数不能继承,它是用来初始化自己的,子类调用父类的构造函数初始化,不能继承,能继承的话就成为子类自己的了
对象的隐式转换和显式转换:
父类的变量可以指向子类的变量 把子类的变量指向父类的变量就不成功,必须显式转Chinese c2 = (Chinese)p1; //如果转换失败则抛异常
Chinese ch= new Chinese();//隐式转换,把子类变量赋值给父类变量Person p = ch;//显式转换,把父类变量赋值给子类变量Person p = new Chinese();Chinese ch = (Chinese)p;//如果对象不在同一个继承树路径上//则不能强制类型转换Dog g = new Dog();Chinese ch = (Chinese)g;//错误
is用来判断变量指向的对象是否是指定的类型或者指定类型子类类型
if(p is Chinese)//is运算符结果就是bool,表示是否是指定的类型。{ Console.WriteLine("中国人");}else if(p is Korean){ Console.WriteLine("韩国人");}
as 运算符
as可以起到判断类型和转换的双重作用
()转换和as 转换的区别:如果转换失败()会报异常,而as则会返回null
Chinese ch = p as Chinese ;if(ch!=null){ Console.WriteLine("中国人");}Korean ch = p as Korean ;if(ch!=null){ Console.WriteLine("韩国人");}
string s = new string("aaa") //创建了两个字符串对象,只要new就会创建一个新的字符串对象 先ToCharArry(),然后再创建一个"aaa"父类没有无参的构造函数,子类必须显示显示调用父类的构造函数
子类不能调用父类私有方法。private成员只能自己调用,子类也不行。protect成员 只有自己和子类可以调用
new一个子类对象,首先会调用用父类的构造函数
继承方式实现复用,只有父类的大部分行为、状态都需要的时候才继承
组合方式实现复用,组合方式没有继承的包袱,用的更多。一个类调用另外一个类实现动作就叫组合
组合例子:
命名空间:
1) namespace(命名空间),用于解决类重名问题,可以看做“类的文件夹”
2) 程序员说要有属性,所以就有了属性。索引器同理
class A { public A(int i) { Console.WriteLine("A构造"); } private void M1() { } public void M2() { this.M3(); } protected void M3() { } } class B : A { public B():base(1)//先调用父类的构造函数 { base.M3();//调用父类的M3() 。 Console.WriteLine("B构造"); this.M2(); this.M3();//protected的,儿子可以调用 //this.M1(); //private成员只有自己能调用,儿子也不能调 } }类与类之间有 继承 和 组合 两种关系:
继承方式实现复用,只有父类的大部分行为、状态都需要的时候才继承
组合方式实现复用,组合方式没有继承的包袱,用的更多。一个类调用另外一个类实现动作就叫组合
组合例子:
class Program { static void Main(string[] args) { YZK y = new YZK(); y.打人(); TuFei t = new TuFei(); t.LG = new LiGang(); t.打人(); //y.嫌摊子(); Console.ReadKey(); } } class LiGang { public void 打人() { Console.WriteLine("前勾拳"); Console.WriteLine("扫堂腿"); Console.WriteLine("九阴白骨爪"); } public void 嫌摊子() { } } class YZK : LiGang { } class TuFei { public LiGang LG { get; set; }//类的属性、字段可以是另外一个对象 public void 打人() { LG.打人();//调用LG属性指向的对象的“打人”方法 } }
常量与静态成员:
const常量:常量名要大写。一定不会变化的值才能声明为常量
static方法:不用new就能用的方法,static方法其实就是普通函数
在static成员中可以调用其他static成员,但是不能调用非static成员。
在非static成员中可以调用static成员。string的static成员和非static成员。不需要记,分析是否有状态就行
在非static成员中可以调用static成员。string的static成员和非static成员。不需要记,分析是否有状态就行
全局变量:static类变量,不用new一个对象就能调用,直接 类名.全局变量名 //A.F1 = 30;
引用静态成员的时候直接"类名.成员名即可"
静态类:不能被new的类就是静态类。静态类一般用来实现一些函数库。***Helper,SqlHelper,PageHelper
static class A{ //静态类中不能声明非静态成员,木有意义! //private int Age;} //A a = new A();//静态类不能new
sealed(密闭类):不能被继承
sealed class B//sealed密闭类不能"被"继承,主要基于安全考虑{ }面试题:不能创建一个从String类继承的类,因为String是sealed密闭类
例子:
class A { public static int F1=30; private int F2; //调用非static成员必须通过对象 public void Hello() { F1 = 10;//在对象中为一个不要求对象的成员 赋值 M1(); A.M1(); //this.M1();//不可以,因为this.调用的都是非static成员 } static public void M1() { //A.Hello(); //A a = new A(); //a.Hello(); // Hello();//在static成员中不能直接调用非static成员 //F2 = 5;//因为static成员不要求对象,没有对象,所以不能直接调用要求对象的非static成员 } }
1) namespace(命名空间),用于解决类重名问题,可以看做“类的文件夹”
2) 在代码中使用其他类的时候需要using类所在的namespace,但是只有没有类名冲突才这么用,否则还要用全名(类的全名:Namespace.类名)
System.Collections.ArrayList,快速引入的方法,右键→解析(Ctrl+.)。“System.Collections”是命名空间(c:/temp/动作片/)," ArrayList"是类名(1.txt)
3) 也可以直接引用类的全名
4) 如果代码和被使用的类在一个namespace则不需要using
5) 可以修改默认的namespace,因此不要认为在相同文件夹下就不用using,不在相同文件夹下就需要using
6) 命名空间不一定和文件夹结构、名称一致易错:把cs移动到其他文件夹下不会自动更新namespace
7) 说明:类的名字尽量不要和命名空间的名字重复,否则会有很多麻烦
8) 为什么使用Convert、Console等类不需要自己写using?using System;已经using过了
索引器:
之前用到索引器的地方:
string类char c = s1[2]
定义索引器的方式:
string this[int index]{ get { return ""; } set { }}//string为索引器的类型,[]中是参数列表。进行索引器写操作就是调用set代码块,在set内部使用value得到用户设置的值;进行读操作就执行get代码块1) 索引器参数可以不止一个,类型也不限于int,几乎可以是任意类型
2) 程序员说要有属性,所以就有了属性。索引器同理
3) 索引器也可以只读,只要没有set段就可以了
public string this[string s, bool b] { get { return ""; } }
4) 索引器的本质,反编译看,也是和属性一样生成set_***,get_***,两个方法
5) 索引也是可以重载的
例子:
static void Main(string[] args) { string s = "aaa"; char ch = s[0]; Family f = new Family(); f[1] = "耳鸣"; Console.WriteLine(f["a", true]); //Console.WriteLine(f[2]); //Console.ReadKey(); } class Family { private string child1="大毛"; private string child2 = "二毛"; private string child3 = "五毛"; public string this[int index]//索引器参数可以不止一个,类型也不限于int,几乎可以是任意类型。程序员说要有属性,所以就有了属性。索引器同理。 { get { if (index == 0) { return child1; } if (index == 1) { return child2; } if (index == 2) { return child3; } //自己也可以抛出异常,这里抛出的异常对象 //可以被catch抓住 throw new Exception("序号错误"); } set { if (index == 0) { child1 = value; } else if (index == 1) { child2 = value; } else if (index == 2) { child3 = value; } else { throw new Exception("序号错误"); } } }一旦抛出异常,就不存在“并非所有路径都返回值的问题”,异常抛出后续代码终止,返回值也就没有意义了
3.异常与异常处理 try catch
1) Exception ex 异常也是对象2) Exception 是所有异常的父类,Exception 类主要属性:Message、StackTrace
3) 发生异常后程序默认就退出了,try代码块中的后续代码不会被执行。catch以后的代码则会继续执行
4) 不要吃掉异常,一般情况下不需要处理异常//VS中调试出现异常的时候如果想终止程序不要关界面,而是点击终止按钮。
5) 尽量不要靠异常来判断执行逻辑,异常是一种“程序员代码错误导致的情况”
try { //抛出异常:throw exception System.IO.File.Delete("c:\\sln20110305.exe"); if (System.IO.File.Exists("c:\\haha.txt")) { System.IO.File.ReadAllLines("c:\\haha.txt"); } //不要随意的try、catch,异常是“未考虑的情况”,尽量不要靠 //try catch来实现正常的逻辑,而是应该“读文件之前判断是否存在” //用int.TryParse而不是Convert.ToInt32() Console.WriteLine("删除exe成功"); } //catch(Exception ex)//抓住所有的异常 catch (UnauthorizedAccessException ex)//只抓UnauthorizedAccessException异常 { //UnauthorizedAccessException //所有的异常信息对象的类都是直接或者间接从Exception类继承 Console.WriteLine("删除失败,错误{0},堆栈{1}",ex.Message, ex.StackTrace); } catch (FileNotFoundException ex)/可以写多个catch,/判断磁盘上文件是否存在 { Console.WriteLine("要删除的文件不存在"); }
文件操作常用方法:
System.IO.File.Delete(); System.IO.File.ReadAllLines(); System.IO.File.Exists();可以try...catch...finally,也可以try...finally
//无论try中的代码是否执行成功 //finally都会在try结束后执行finally中的代码 finally { Console.WriteLine("执行完成"); Console.ReadKey(); } //如果没有catch异常,那么如果发生异常 //try后的代码不会执行,但是finally会执行 //这就是在try后写代码和finally中写代码的区别
- 黑马程序员—C#系列 (三)
- 黑马程序员—SQL系列 (三)
- 黑马程序员—C#系列 (一)
- 黑马程序员—C#系列 (二)
- 黑马程序员—C#系列 (四)
- 黑马程序员--C#基础知识小结(三)
- 黑马程序员—C#多线程
- 黑马程序员—C#继承
- 黑马程序员—C#委托
- 黑马程序员—c#基础知识。。
- 黑马程序员————————C#基础知识(三)
- 黑马程序员——C#你不能不知道的事(三)
- 黑马程序员之C#学习笔记: 解决三大问题
- 黑马程序员-----踏踏实实基础C#基础(三)
- 黑马程序员:C#基础篇(三)委托与事件
- 黑马程序员—SQL系列 (一)
- 黑马程序员—SQL系列 (二)
- 黑马程序员—SQL系列 (四)
- Android Chronometer控件使用,计时器
- thrift之默认传输类TTransportDefaults和虚拟传输类TVirtualTransport
- hadoop2官方文档中文翻译(3)---集群配置【还未翻译完】
- StringBuilder类
- 链表的创建,删除,插入小型程序。
- 黑马程序员—C#系列 (三)
- poj 3026 Borg Maze (bfs+最小生成树)
- Smack文档(翻译)
- java读取文件方法大全
- CF 332A Down the Hatch! 超级水题。。不过题目太长了
- HTML5 Canvas中实现绘制一个像素宽的细线
- thrift之TTransport层的堵塞的套接字I/O传输类TSocket
- 《C和指针》读书笔记(9)
- 9个tcpdump使用实例