Presentation is loading. Please wait.

Presentation is loading. Please wait.

第四章 类 4.1 基础知识 4.2 构造函数 4.3 方法 4.4 属性与索引 4.5 String类

Similar presentations


Presentation on theme: "第四章 类 4.1 基础知识 4.2 构造函数 4.3 方法 4.4 属性与索引 4.5 String类"— Presentation transcript:

1 第四章 类 4.1 基础知识 4.2 构造函数 4.3 方法 4.4 属性与索引 4.5 String类
第四章 类 4.1 基础知识 4.2 构造函数 4.3 方法 4.4 属性与索引 4.5 String类 4.6 StringBuilder类 4.7 Convert类 4.8 DateTime类 4.9 Math类

2 4.1 基础知识 4.1.1 类与对象  类:大楼结构蓝图  对象(实例):理工楼、十号楼、科技馆
 对象(实例):理工楼、十号楼、科技馆  要使用对象,必须先定义类,然后再创建类的对象。

3 1.类的组织 在C#中使用class定义类,一般格式为: <访问修饰符> class <类名称> { //成员声明 //构造函数 //方法 //…… } 下面举例说明如何声明类、构造函数和方法。

4 声明类、构造函数和方法的例子 using System; public class Child { private int age;
private string name;   //下面是不带参数的构造函数 public Child() name = "none"; } // 下面是带参数的构造函数 public Child(string name, int age) this.name = name; this.age = age;

5 // 输出方法 public void PrintChild() {
Console.WriteLine("{0}, {1} years old.", name, age); } public class MainClass public static void Main() // 创建对象要用new操作符 Child child1 = new Child("Zhang San", 11); Child child2 = new Child("Li Si", 10);

6 Child child3 = new Child();
Console.Write("Child #1: "); child1.PrintChild(); Console.Write("Child #2: "); child2.PrintChild(); Console.Write("Child #3: "); child3.PrintChild(); } 输出结果: Child #1: Zhang San, 11 years old. Child #2: Li Si, 10 years old. Child #3: none, 0 years old.

7 2.对象的生存周期 对象在建立时分配了内存,创建对象实际上作了两个方面的工作: (1)使用new保留字要求系统分配内存; (2)使用构造函数初始化数据。 在C#中不允许通过编制程序做销毁对象的工作,这是因为如果把这个权力交给编程者,一旦编程者忘记销毁对象,就会引起内存泄漏问题。  C#采用垃圾回收机制自动销毁对象,在适当的时候自动启动回收机制,然后检测没有被引用的对象并销毁之。 销毁对象也是做了两个方面的工作: (1)释放占用的内存; (2)将分配给对象的内存归还给堆(Heap)。

8 4.1.2 静态成员与实例成员 类的成员 在类中定义的数据称为类的成员。对象中的成员和方法都是对象私有的,即只有对象本身才能够操作这些成员和调用这些方法,其他对象不能直接对其进行操作。 所有对象共用的内容也可以定义为静态(static)的,当该类被装入内存时,系统就会在内存中专门开辟一部分区域保存这些静态成员和方法,这样一来,其它类不必建立该类的实例就可以直接使用该类的静态成员和方法。 静态成员和静态方法在内存中只有一份 静态的成员或者方法要等到应用程序结束时才会消失。 只有创建了类的实例才能够使用的成员叫实例成员。

9 4.1.3 访问修饰符 C#中有以下几种成员访问修饰符: Public 任何外部的类都可以不受限制的存取这个类的方法和数据成员。
private 类中的所有方法和数据成员只能在此类中使用,外部无法存取。 Protected 除了让本身的类可以使用之外,任何继承自此类的子类都可以存取。 Internal 在当前项目中都可以存取。该访问权限一般用于基于组件的开发,因为它可以使组件以私有方式工作,而该项目外的其它代码无法访问。 protected internal 只限于当前项目,或者从该项目的类继承的类才可以存取。

10 4.2 构造函数 构造函数用于在建立对象时进行初始化的动作 每当创建一个对象的实例时,都会先调用类中定义的构造函数。
每个类至少有一个构造函数。如果不写构造函数,系统会提供一个缺省的构造函数。 一个构造函数总是和它的类名相同,但是,不能声明返回类型。 构造函数总是 public的。

11 4.2.1 缺省构造函数 如果在类中不定义构造函数,系统会提供一个缺省的构造函数,缺省构造函数没有参数,之所以这样做是为了保证能够在使用实例前先进行非静态类成员的初始化工作,即将非静态成员初始化为: 数值型:如int、double等,初始化为0。 bool类型:初始化为false. 引用类型:初始化为null。

12 4.2.2 重载(Overloading)构造函数 有时候可能会遇到这样的情况:在一个类中的多个方法中都要用到某一个数据成员,而该成员值必须从其它类中传递过来,这时,无参数的构造函数就不能胜任了,解决这个问题最好的办法就是:重载构造函数。 下面是重载构造函数的一个例子。

13 using System; class Test { public Test() Console.WriteLine(“hi"); } public Test(string str) Console.WriteLine(str); static void Main() Test aa=new Test(); Test bb=new Test("How are you!"); Console.Read(); 输出结果: hi How are you!

14 4.3 方法 方法(Method)是一组程序代码的集合,每个方法都有 4.3.1 方法的定义与使用 C#程序中定义的方法都必须放在某个类中。
一个方法名,便于识别和让其它方法调用。 4.3.1 方法的定义与使用 C#程序中定义的方法都必须放在某个类中。 定义方法的语法形式为: 访问修饰符 返回值类型 方法名称(参数序列) { //方法的内容 }

15 在定义方法时,需要注意以下几点: 方法名称不能和变量、常数或者任何声明在类中其它的成员相同。 方法名称后面的小括号中可以有参数序列,也可以没有参数,但是不论是否有参数,小括号都是必需的。如果参数序列中的参数有多个,则以逗号分隔开。 如果要结束某个方法的执行,可以使用return语句,程序遇到return语句后,会将执行流程交还给调用此方法的程序代码段。此外,还可以利用return语句返回一个值,而且return语句只能返回一个值。 如果声明一个非void类型的方法,则方法中必须至少有一个return语句。

16 using System; class Method { public int MyMethod() Console.WriteLine("this is MyMethod."); int i=10; return i; } static void Main() Method method=new Method(); int j=5; j=method.MyMethod(); Console.WriteLine("the value is {0}.",j); Console.Read(); 输出结果: this is MyMethod. the value is 10.

17 4.3.2 方法中的参数传递 (1)传递值类型的参数 格式:参数类型 参数名
当该方法被调用时,便会为每个值类型参数分配一个新的内存空间,然后将对应的表达式运算的值复制到该内存空间。在方法中更改参数的值不会影响到这个方法之外的变量。例如:

18 输出结果: 调用AddOne之前,x=3 调用AddOne之后,x=3 using System; class Method {
public static void AddOne(int a) a++; } static void Main() int x=3; Console.WriteLine("调用AddOne之前,x={0}",x); AddOne(x); Console.WriteLine("调用AddOne之后,x={0}",x); Console.Read(); 输出结果: 调用AddOne之前,x=3 调用AddOne之后,x=3

19 (2)传递引用类型的参数 格式: ref 参数类型 参数名 引用类型的参数并没有再分配内存空间,实际上传递的是指向原变量的地址指针,既引用参数和原变量保存的是同一个地址。为了和传递值类型参数区分,前面加上ref关键字(Reference),在方法中修改引用参数的值实际上也就是修改被引用的变量的值。 举例:

20 using System; class Method { public static void AddOne(ref int a) a++; } static void Main() int x=3; Console.WriteLine("调用AddOne之前,x={0}",x); AddOne(ref x); Console.WriteLine("调用AddOne之后,x={0}",x); Console.Read(); 输出结果: 调用AddOne之前,x=3 调用AddOne之后,x=4

21 (3)输出多个引用类型的参数 格式: out 参数类型 参数名 当一个方法计算的结果有多个时就用到了out关键字,使用out表明该引用参数是用于输出的,而且调用该参数时不需要对参数进行初始化。 举例:

22 using System; class Method { public static void MyMethod(out int a,out int b) a=5; b=6; }   static void Main() int x,y; MyMethod(out x,out y);x、y为输出参数 Console.WriteLine("调用MyMethod之后,x={0},y={1}",x,y); Console.Read(); 输出结果: 调用MyMethod之后,x=5,y=6

23 (4)传递个数不确定的参数 需要传递的参数个数不确定时,可以采用params关键字声明参数的个数是不确定的。 举例:

24 using System; class Method { public static float VarLenParam(params long[] v) long total,i; for(i=0,total=0;i<v.Length;++i) total+=v[i]; return (float)total/v.Length; } static void Main() float x=VarLenParam(1,2,3,5); Console.WriteLine(“ 的平均值为{0}",x); x=VarLenParam(4,5,6,7,8); Console.WriteLine(" 的平均值为{0}",x); Console.Read(); 运行结果: 的平均值为2.75 的平均值为6

25 4.3.3 方法重载(overloading) 方法重载是指具有相同的方法名,但参数类型或参数个数不完全相同的多个方法可以同时出现在一个类中。这种技术非常有用,在开发过程中,我们会发现C#.NET中的很多方法均使用了重载技术。 举例:

26 using System; static void Main() { class Method { Console.WriteLine(
public static int Add(int i,int j) return i+j; } public static string Add( string s1,string s2) return s1+s2; public static long Add(long x) return x+5; static void Main() { Console.WriteLine( Add(1,2)); Add("1","2")); Add(10)); Console.Read(); } 输出结果: 3 12 15

27 4.4 属性与索引 属性: 是用来封装类数据的极佳选择,常见的属性有对象名、字体、颜色等,属性的另一个好处是使应用程序看起来更直观。 属性的用处:可以限制外部对类中成员变量的存取权限。 4.4.1 属性的使用 用属性声明对属性进行定义,通过 get 和 set 访问函数将专用数据成员和公共属性关联起来。根据使用情况不同,可以只用get或者只用set,也可以同时使用get和set。 get:用来读取数据成员的值。 set:用来设置数据成员的值。

28 注意: 例如: 使用属性时,属性的名称不用括号()。 如果想要存取某个属性值,可以采用这样的语法: 类的实例名.属性名称
private int number = 0; public int MyNumber { get{ return number; } set number = value; //value是关键字,其值由编译器自动生成。 } 注意: 使用属性时,属性的名称不用括号()。 如果想要存取某个属性值,可以采用这样的语法: 类的实例名.属性名称 如果把属性定义为静态的,则用:类名.属性名称

29 4.4.2 属性和方法的区别 属性是一种特殊的方法,其不同之处有: (1)属性不必使用括号(),但方法一定要使用括号。
(2)属性不能指定参数,方法可以指定参数。 (3)属性不能使用void类型,方法则可以使用void类型。

30 4.4.3 使用索引 使用索引的原因是很多对象都是由许多子项目组成的,如ListBox是由一系列字符串组成。索引(Indexer)则允许让对象以类似数组的方式来存取,让程序更为直观,更容易编写。 定义索引的方式和定义属性非常相似,主要有两部分: (1)使用this关键字 (2)定义一个索引值。 举例:

31 using System; class MyIndexer {   private string[] myArray=new string[4]; public string this[int index] get if(index<0||index>=4) return null; else return myArray[index]; } set if(!(index<0||index>=4)) myArray[index]=value;

32 static void Main() { MyIndexer idx=new MyIndexer(); idx[0]="abc"; idx[1]="def"; for(int i=0;i<=3;i++) Console.WriteLine(idx[i]); } Console.Read(); 输出结果: abc def

33 4.5 String类 表示一系列不可变的字符。 说其实例是“不可变的”,是因为无法直接修改给 该字符串分配的堆中的字符串。
string myString = "some text"; myString += " and a bit more"; 其实际操作并不是在原来myString所占内存空间 的后面直接附加上第二个字符串,而是返回一个 新String实例,即重新为新字符串分配内存空间。 (书P45字符串格式)

34 4.6 StringBuilder类 StringBuilder类位于System.Text名称空间下,使用
成一个新实例,而是直接在原来字符串占用的内存 空间上进行处理,而且它可以动态的分配占用的内 存空间大小。因此,在字符串处理操作比较多的情 况下,使用StringBuilder类可以大大提高系统的性 能。

35 4.7 Convert类 using System; class Test { public static void Main()
{ double d1=23.5D,d2=23.4D; int i1=Convert.ToInt32(d1); int i2=Convert.ToInt32(d2); Console.WriteLine("{0},{1}",i1,i2); //24,23 int i=0; bool b1=Convert.ToBoolean(d1); bool b2=Convert.ToBoolean(i); Console.WriteLine("{0},{1}",b1,b2); //True,False string s="123"; i=Convert.ToInt32(s); Console.WriteLine("{0},{1}",s,i); //123,123 Console.Read(); }}

36 4.8 DateTime类 DateTime类可以表示范围在0001 年 1 月 1 日
午夜 12:00:00 到 9999 年 12 月 31 日晚上 11:59:59 之间的日期和时间,最小时间单位等 于 100 毫微秒。 TimeSpan类可以表示一个时间间隔。其范围可 以在 Int64.MinValue 到 Int64.MaxValue之间。 举例 :

37 using System; class Test { public static void Main() DateTime dt1 = new System.DateTime(2003, // Year 12, // Month 31, // Day 22, // Hour 35, // Minute 5, // Second // Millisecond ); DateTime dt2=new DateTime(2002,7,05); Console.WriteLine("{0:F}---{1}", dt1,dt2);

38 dt1=DateTime.Now; int i=dt1.Day; //当月第几天 int j=dt1.Month; //月
int k=dt1.Year; //年 Console.WriteLine("{0}---{1}---{2}---{3}",dt1,i,j,k); DateTime t1=dt1.Date; //日期部分 k=dt1.Hour; //小时 Console.WriteLine("{0}---{1}",dt1,k); TimeSpan ts1=dt1.TimeOfDay; //当天的时间 TimeSpan ts2=dt1-dt2; i=ts2.Days; Console.WriteLine("{0}---{1}---{2}",ts1,ts2,i); string s1=dt1.ToLongDateString(); string s2=dt1.ToShortDateString(); string s3=string.Format("{0:yyyy.MM.dd}",dt1); //注意:M为月,m为分钟

39 Console.WriteLine("{0}---{1}---{2}---{3}",
dt1,s1,s2,s3); Console.Read(); } 运行结果: 2003年12月31日 22:35: :00:00 :05: :05:53---7 07:05: :05: :05: 年6月8日

40 4.9 Math类 位于System名称空间下,为三角函数、对数函数和 其他通用数学函数提供常数和静态方法。 例如:
int i=10,j=-5; double x=1.3,y=2.7; double a=2.0,b=5.0; this.listBox1.Items.Add(string.Format( "-5的绝对值为{0}",Math.Abs(j))); “大于等于1.3的最小整数为{0}”, Math.Ceiling(x)));

41 this.listBox1.Items.Add(string.Format(
"小于等于2.7的最大整数为{0}",Math.Floor(y))); "10和-5的较大者为{0}",Math.Max(i,j))); "1.3和2.7的较小者为{0}",Math.Min(x,y))); "2的5次方为{0}",Math.Pow(a,b))); "1.3的四舍五入值为{0}",Math.Round(x))); "5的平方根为{0}",Math.Sqrt(b))); "5除以2的余数为{0}",Math.IEEERemainder(b,a)));

42 结果:

43 习题 大家在网页上经常见到类似下面的内容: 现在是××××年××月××日, × 点×分,星期× 请同学们写一个控制台应用程序,完成这个功能。
思考:(1)如何在web应用程序中完成这个功能? (2)如何求2003年1月1日到今天已经过了多少天?

44 参考解答: using System; public class Test { public static void Main() string[] weekDays={“星期日”,“星期一”,“星期二”,“星期三”, "星期四","星期五","星期六"}; DateTime now=DateTime.Now; Console.WriteLine("{0:现在是yyyy年M月d日,H点m},{1}", now,weekDays[(int)now.DayOfWeek]); DateTime start=new DateTime(2003,1,1); TimeSpan times=now-start; Console.WriteLine(“从2003年1月1日起到现在已经过了{0}天!”, times.Days); Console.Read(); }


Download ppt "第四章 类 4.1 基础知识 4.2 构造函数 4.3 方法 4.4 属性与索引 4.5 String类"

Similar presentations


Ads by Google