码迷,mamicode.com
首页 > Windows程序 > 详细

C#类基础

时间:2015-05-27 00:54:37      阅读:257      评论:0      收藏:0      [点我收藏+]

标签:

  学习C#.net已有一段时间了,学的快忘的也快,在博客园开博也是很久很久了,是时候留下点东西了,从这篇笔记开始,将对前面所学编程知识进行复习。要知道,想让我坚持一件事情是很不容易的,我不知道这次能走多远--第1天就这样兢兢战战滴来了!

类是C#中的一种特殊又复杂的数据类型,但是不要怕,没那么简单,也没那么难!

C#中如何定义类

class Person
{
}
默认情况下,class关键字前没有写访问修饰符,那类的访问修饰符就是internal,当然也可以写上,但这又是没有必要的,默认就是internal嘛。
当然类还可以指定其他访问修饰符:public、private、protected、abstract、sealed等,还可以组合使用。
1、C#类的成员

类的成员包括字段、属性、方法、构造函数等。
这些成员也可设置访问权限,和类一样。
还可以使用static关键字将其声明为静态成员。静态成员属类级别概念,它不属于类的实例(对象)。

2.1、 字段

字段由三部分组成:访问修饰符、字段类型、字段名称。
字段一般声明为private

1 public class Person
2 {
3   private string name;
4   public int age;
5   protected bool sex;
6 }

用关键字readonly或const定义字段

1 public class Person
2 {
3   private readonly string name;//只读字段,不需要在定义时初始化,可在构造函数中完成初始化
4   public const int age=18;//加了const就要给定初始化值
5   protected bool sex;
6 }

使用关键字static来声明静态字段。
静态字段和实例字段的区别是:静态字段必须通过类.字段名访问,实例名则通过类的对象.字段名

1 public class Person
2 {
3     public static string name;//静态成员字段
4     public const int age=18;//实例成员字段
5 }

2.2 属性

属性是字段的扩展。
为了不让外界随意修改成员的值,最好将字段设置为private。
C#中提供了一种属性机制,可以灵活的控制外界对字段的读写。

 1 public class Person
 2     {
 3         private string name;
 4         //方法是类的“行为”,接受外界设定的“名字”值
 5         public void SetName(string value)
 6         {
 7             this.name = value;
 8         }
 9         //返回字段name的值
10         public string GetName()
11         {
12             return this.name;
13         }
14         private int age;
15         //方法是类的“行为”,接受外界设定的“年龄”等值
16         public void SetAge(int value)
17         {
18             this.age = value;
19         }
20         //返回字段age的值
21         public int GetAge()
22         {
23             return this.age;
24         }
25         //执行问好的动作
26         public void SayHello()
27         {
28             Console.WriteLine("大家好,我是" + this.name + ",我今年" + this.age + "岁了");
29         }
30         //上面对字段的读取和写入是用方法实现.
31         //而C#提供的属性机制更方便,使我们不用再麻烦的调用方法就可以对字段进行读写。
32         public string Name
33         {
34             get { return name; }
35             set { name = value; }
36         }
37         //简写
38         public string Name { get; set; }
39     }

可以使用只写get或给set设置private来定义只读属性,只写属性也一样。但只是不能被外界读取(比如Main方法不能读取它)

还可以给属性加入逻辑控制代码,比如人的年龄一般在0-120之间,为了避免用户输入这个范围之外的数值,可在属性中添加限制代码或抛出异常代码。

 1         private int age;
 2         public int Age
 3         {
 4             get
 5             {
 6                 return age;
 7             }
 8             set
 9             {
10                 if (age <= 0 || age > 120)
11                 {
12                     throw (new ArgumentOutOfRangeException("AgeIntPropery", value, "年龄必须在0-120之间"));
13                 }
14                 age = value;
15             }
16         }    

 

2.3 方法

Main方法是每个C#应用程序的入口,程序启动时,Main由公共语言运行时(CLR)负责调用。
方法由方法签名和一系列语句的代码块组成。
方法就是一堆可以重复使用(复用)的代码段,执行过程中无法确定的数据以参数形式传递;方法执行的执行结果以返回值进行返回。
方法签名包括方法的访问级别(如public、private)、可修饰符(如abstract、static等)、方法名和参数来。
方法可以没有参数,可以没有返回值(void).return返回处理结果,执行return之后方法内部的代码就执行结束了。

 1 public class Person
 2         {
 3             //这是一个有参数无返回值的方法
 4             public static void SayHello()
 5             {
 6                 Console.WriteLine("大家好!");
 7             }
 8             //这是一个由参数有返回值的方法
 9             public int Print(int age)
10             {
11                 Console.WriteLine("我的年龄是" + age);
12                 return age;
13             }
14         }

因为定义的是实例方法,要调用实例方法必须实例化一个对象。
带有static关键字的方法叫做静态方法,静态方法属于类级别,不能通过实例进行访问,必须通过Person.SayHello()方式调用。

class Program
{
    static void Main(string[] args)
    {
        Person p=new Person();
        p.Print(18);
        Person.SayHello();
    }
}

方法的重载
同一个类中,允许存在一个以上的同名方法,只要其参数个数、参数类型或参数顺序不同即可。与返回值无关。

 1 class Program
 2  {
 3             static void Main(string[] args)
 4        {
 5         Person p = new Person();
 6         //参数个数、类型、顺序不同区分调用哪一个方法重载
 7         p.Print("Lucy")
 8         p.Print(1, "Sean");
 9         p.Print("Jack", 2);
10         Console.ReadKey();
11        }
12  }
13 public class Person
14  {
15             public int Print(int age)
16             {
17                 Console.WriteLine("年龄:" + age);
18                 return 100;
19             }
20             public void Print(string name)
21             {
22                 Console.WriteLine("我的名字叫:" + name);
23             }
24             public void Print(int age, string name)
25             {
26                 Console.WriteLine("我的名字叫:" + name + "年龄是:" + age);
27             }
28             public void Print(string name, int age)
29             {
30                 Console.WriteLine("我的名字是:" + name + "今年" + age);
31             }
32 }

构造函数
构造函数是创建对象,并且在创建完成前对类进行初始化的特殊函数。
有实例构造函数和静态构造函数两种。
特征:

  • 方法名必须和类名一致,
  • 无返回值。
  • 构造函数可以重载,Person(String name,int age)
  • 可以对实例构造函数指定访问级别,即可以使用public、protected和private修饰符来修饰。要构成实例构造函数,必须满足以下两个条件:必须和类同名;不允许有返回值。
  • 用构造函数初始化和new之后通过属性初始化的区别:
  • 有的对象生来就要有一些成员变量被赋值,否则就是怪胎。有些属性是出生时设置的,不能后期set改

也可以这么理解:
当你在主方法中new一个对象时,Person p=new Person();这个Person()是不是很像在调用一个方法(函数),这个方法(函数)其实就是构造方法,不写的话默认会给出一个无参构造方法;
那么构造方法怎么写:
因为在主方法中调用时是Person p=new Person(),显然要先读取Person这个类,那么构造函数也要和这个类名一致。

private和protected修饰的是私有构造函数

 1 class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             /*
 6             Person p = new Person();
 7             //参数顺序和参数类型,参数个数不同都构成重载。
 8             p.Print("Sean", 1);
 9             p.Print(2, "Shawn");*/
10             //一般写了有参构造函数默认无参就没了,如果要用需要自己写出来
11             Person p1 = new Person();
12             Person p2 = new Person("Sean");
13             Person p3 = new Person() { Name = "Jack", Age = 18 };//简写的,属性赋值
14             Console.ReadKey();
15         }
16     }
17     public class Person
18     {
19         private string name;
20         public string Name { get; set; }
21         private int age;
22         public int Age { get; set; }
23         public Person()
24         {
25             name = "Tom";
26         }
27         public Person(string name)//这是公共构造函数
28         {
29             //使用this关键字来引用字段name,与参数name(局部变量)区别开来。
30             this.name = name;//this代表当前类的实例对象。
31         }
32     }

私有构造函数典型应用是设计模式中单例模式的实现:

 1  class Person
 2 { 
 3     private string name;
 4     public static Person person;
 5     public string Name;
 6     {
 7         get{ return this.name;}
 8     }
 9 
10     //私有构造函数,只能在类内部调用
11     //也就是说类的实例化只能在类定义时被实例化
12     private Person()
13     {
14         this.name="sean";
15     }
16     //静态方法,用于返回类的实例
17     public static Person GetInstance()
18     {
19         person = new Person();
20         return person;
21     }
22 }
23 
24 class Program
25 {
26     static void Main(string[] args)
27     {
28         //通过调用GetInstance()静态方法返回一个Person的实例
29         //不能使用new Person()创建实例
30         Person person=Person.GetInstance();
31         Console.WriteLine("类实例的属性为:"+person.Name);
32         Console.Read();
33     }
34 }

 

静态构造函数

  • 静态构造函数用于初始化类中的静态成员,在实例构造函数或引用任何静态成员之前执行,
  • 静态构造函数只会执行一次。
  • 静态构造函数不能带有任何参数。
  • 静态构造函数不能使用任何访问修饰符
  • 不能直接调用静态构造函数。
  • 无法控制执行的时机。
  • 静态构造函数,在实例构造函数执行前执行

结合下面代码,在Main方法中,创建两个Person对象,启动程序会发现,首先打印的是“静态构造函数被调用了”,随后才是两个“实例构造函数被调用了”。

 1     private static string name;
 2     //静态构造函数,仅执行一次
 3     public Person()
 4     {
 5             Console.WriteLine("实例构造函数被调用了");
 6     }
7 static Person() 8 { 9 Console.WriteLine("静态构造函数被调用了"); 10 name="sean"; 11 } 12 public static string name 13 { 14 get{return name;} 15 }

 

析构函数
用于在类销毁之前释放实例所使用的托管和非托管资源。
定义析构函数,需要注意:

  • 不能再结构体中定义析构函数,只能对类使用析构函数。
  • 一个类只能有一个析构函数
  • 无法继承和重载析构函数
  • 无法显示调用析构函数,析构函数由垃圾回收器自动调用。
  • 析构函数既没有修饰符也没有参数
1 class Person
2 {
3     ~Person()
4     {
5         Console.WriteLine("析构函数被调用了");
6     }
7 }

该析构函数隐式的调用了基类Object的Finalize方法,上面代码中的析构函数将隐式的转换为如下代码:

protected override void Finalize()
{
    try
    {
        Console.WriteLine("析构函数被调用了");
    }
    finally
    {
        //调用FinalLize方法
        base.Finalize();
    }
}

索引器 当一个类包含数组成员时,索引器的使用将大大简化对类中数组成员的访问。索引器的定义类似于属性,也具有get访问器和set访问器,代码示例:

[修饰符] 数据类型 this[索引类型 index] 

get{//返回类中数组某个元素} 
set{//对类中数组元素赋值} 

数据类型对应intarray字段的数据类型,索引类型表示该索引器使用哪一个类型的索引来存取数组元素,可以是整型,也可以是字符串;this表示所操作的是类对象的数组成员,可以简单理解为索引器的名字(注意,索引器不能自定义名称)

 

 1  class Person
 2     {
 3         //可容纳10个整数的数组
 4         private int[] intarray = new int[10];
 5         //索引器的定义
 6         public int this[int index]
 7         {
 8             get
 9             {
10                 return intarray[index];//返回类中数组某个元素
11             }
12             set
13             {
14                 intarray[index] = value;//对类中数组元素赋值
15             }
16         }
17     }

如何使用索引器

Main方法中:

1 Person person = new Person();
2 Person p3 = new Person();
3 p3[0] = 15;
4 p3[1] = 32;
5 p3[2] = 20;
6 p3[3] = 19;
7 Console.WriteLine(p3[2]);

 


索引器和属性的区别:索引器也是一种对私有字段的一种访问,不同的是索引器是对数组类型的私有字段进行访问,而属性是对简单数据类型的一种访问。

3. 类和结构体的区别

  • 定义类要使用关键字class,结构体使用struct
  • 结构体不可对声明字段进行初始化。
  • 类默认有无参构造函数,并且为隐式函数。而在结构体中无论你是否显式定义了构造函数,隐式构造函数都一直存在。
  • 结构体中不能显式定义无参数构造函数,类可以显示定义一个无参构造函数同时会覆盖默认无参构造函数。
  • 结构体的构造函数中,必须给所有字段赋值。
  • 结构体不能继承结构或者类,但可以实现接口;类可以继承类但不能继承结构,可以实现接口。
  • 类是引用类型,结构体是值类型。
  • 结构体不能定义析构函数,类可以有析构函数。
  • 不能用abstract和sealed关键字修饰结构体,类可以。
 1  struct Point
 2     {
 3         private int x;
 4         private int y;
 5         public Point(int i1, int i2)
 6         {
 7             this.x = i1;
 8             this.y = i2;
 9         }
10     }

 

C#类基础

标签:

原文地址:http://www.cnblogs.com/sean100/p/4532189.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!