----------------------
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中写代码的区别