面向对象和类
类:类是一组具有相同数据结构和相同操作的对象的集合。类是对一系列具有相同性质的对象的抽象,是对对象共同特征的描述。
对象:对象可以是现实生活中的一个物理对象,还可以是某一类概念实体的实例。例如:一辆汽车、一个人、一本书,乃至一种语言、一个图形、一种管理方式,都可以作为一个对象。
面向对象的三个特征:继承,多态,封装(oop编程的主要特性,将类进行封装,对外提供可访问的属性和方法,外部对象必须通过这些属性和方法来访问此对象的信息)
封装性主要通过访问修饰符来访问。(面试)
方法:(面试)包涵一系列语句的代码块,是完成一定的功能的
方法通过修饰符(并不一定是访问修饰符 如static),返回值类型,方法名称和方法参数列表(这些共同构成方法的签名) static void Main(string[] args)(方法的签名) { } 形参:在定义方法是的参数形参 实参:在调用方法是的参数觉实参 string[] args:形参,定义了参数的类型和个数 用来定义方法 形参必须有类型 实参的类型必须和形参相匹配 object类型的可以和任何类型向匹配方法的实现(方法体):{}
方法可以向调用方返回值。如果返回类型(方法名称前列出的类型)不是 void,则方法可以使用 return 关键字来返回值。(也可以不使用return因为return是跳转语句可以用别的跳转语句来替代如throw
)如果语句中 return 关键字的后面是与返回类型匹配的值,则该语句将该值返回给方法调用方。
return 关键字还会停止方法的执行。如果返回类型为 void,则可使用没有值的 return 语句来停止方法的执行。如果没有 return 关键字,方法执行到代码块末尾时即会停止。
具有非 void 返回类型的方法才能使用 return 关键字返回值。普通方法(按参数划分):
值类型参数方法 参数是int类型,一个赋值不会影响另一个 引用类型参数方法 ref关键字参数方法:ref是双向的可以用作静态变量,与out的区别是ref是双向的,外部的值可以传进来,内部的值也可以传出去 out关键字参数方法: 1.在有out,ref关键字的时候其实是吧值类型当做为引用类型来使用但是又不会发生装箱和拆箱。 2.在参数前面加out无论参数在外部是否赋值,传到方法内部它是不会认的,out是单向的从方法内部向外传参数,out做关键字的参数必须是一个变量。 3.但凡方法返回两个参数时用out比较好。 params关键字参数方法参数进出一个含义用out,进出含义不同用ref,如果不是一个类型可以用return。
关于out和ref的例题: class Program { static void Main(string[] args) { int i = 10; int j = 0; Add(ref i, out j); Console.WriteLine(j); Console.WriteLine(i); Console.WriteLine(j); /* 运行结果 100 300 300 100 300程序运行的过程:在main方法中调用Add(ref i,out j)方法,;
因为有参数ref,通过ref把int i=10传递到Add()方法内部运行Add()里因为 Add()方法里面对i赋值为100,更改了i=10,所以调用Console.WriteLine(i)输出100; 接着调用 Console.WriteLine(j); 因为有out 把add()方法中j=300取了过来 Console.WriteLine(j)运行结果为300输出300 ,然后运行main方法的下一行代码:Console.WriteLine(i); 此时又通过ref把Add()方法中的i=100取出来 运行 Console.WriteLine(i); 输出100 而out也把add()中的j的值取了过来 运行 Console.WriteLine(j);输出300 * */}
static void Add(ref int i, out int j) { i = 100; j = 300; Console.WriteLine(i); Console.WriteLine(j); }}
params关键字参数方法 params实现了参数的动态变化,可以是实现加任意和参数匹配类型的参数 ,当同名方法其中一个参数是动态的还有一个是唯一性参数即不是params声明的就会优先调用唯一性的那一个。 在main方法中调用: Test(10);//会优先调用具有唯一性参数的方法而不去调用带有params关键字的参数 static void Test(int k, params int[] arr)//params int[] arr有其他参数的时候必须放到参数的最后面 { foreach (int i in arr) { Console.WriteLine(i); } } static void Test(int k) { Console.WriteLine("111111111"); }int i; 在方法内部叫变量 在方法外的叫字段,构造函数给他一个默认值,不赋初始值。
分部方法:
分部方法(方法的书写分):
说到分部方法,引出分部类: 可以将类或结构、接口或方法的定义拆分到两个或多个源文件中。每个源文件包含类型或方法定义的一部分,编译应用程序时将把所有部分组合起来。在以下几种情况下需要拆分类定义:
处理大型项目时,使一个类分布于多个独立文件中可以让多位程序员同时对该类进行处理。 使用自动生成的源时,无需重新创建源文件便可将代码添加到类中。Visual Studio 在创建 Windows 窗体、Web 服务包装代码等时都使用此方法。无需修改 Visual Studio 创建的文件,就可创建使用这些类的代码。 若要拆分类定义partial 关键字指示可在命名空间中定义该类、结构或接口的其他部分。所有部分都必须使用 partial 关键字。
在编译时,各个部分都必须可用来形成最终的类型。 各个部分必须具有相同的可访问性,如 public、private 等。 如果将任意部分声明为抽象的,则整个类型都被视为抽象的。 如果将任意部分声明为密封的,则整个类型都被视为密封的。(不可以去继承) 如果任意部分声明基类型,则整个类型都将继承该类。指定基类的所有部分必须一致,但忽略基类的部分仍继承该基类型。 各个部分可以指定不同的基接口,最终类型将实现所有分部声明所列出的全部接口。 在某一分部定义中声明的任何类、结构或接口成员可供所有其他部分使用。 最终类型是所有部分在编译时的组合。分部方法:
分两部分、:一部分只定义签名不定义实现,在别的地方定义实现。注意事项:
分部方法声明必须以上下文关键字 partial 开头,并且方法必须返回 void。 分部方法可以有 ref 参数,但不能有 out 参数。 分部方法为隐式 private 方法,因此不能为 virtual 方法。 分部方法不能为 extern(外面来的) 方法,因为主体的存在确定了方法是在定义还是在实现。 分部方法可以有 static 和 unsafe(不安全的如可以有指针) 修饰符。 分部方法可以为泛型的。约束将放在定义分部方法声明上,但也可以选择重复放在实现声明上。参数和类型参数名称在实现声明和定义声明中不必相同。 不能将委托转换为分部方法。扩展方法:可以给类定义一个扩展方法 但是扩展的方法必须定义为static。但是调用的时候需要实例出一个对象来调用
using ExtStrNS; namespace ClassDemo { class Program { static void Main(string[] args) { string str = "I'm Guisw,I like .net"; Console.WriteLine(str.WordCount()); } } } namespace ExtStrNS { static class ExtString { public static int WordCount(this string str) { return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length; } } } 通常,您更多时候是调用扩展方法而不是实现您自己的扩展方法。 由于扩展方法是使用实例方法语法调用的,因此不需要任何特殊知识即可从客户端代码中使用它们。 若要为特定类型启用扩展方法,只需为在其中定义这些方法的命名空间添加 using 指令。如果您确实为给定类型实现了扩展方法,请记住以下两点:
如果扩展方法与该类型中定义的方法具有相同的签名,则扩展方法永远不会被调用。 扩展方法被在命名空间级别放入范围中。例如,如果您在同一个名为 Extensions 的命名空间中具有多个包含扩展方法的静态类,则这些扩展方法将全部由 using Extensions; 指令放入范围中。