首页 > 代码库 > 15-01-10 C# 面向对象 09

15-01-10 C# 面向对象 09

面向过程;面向的是完成这件事儿的过程,强调的是完成这件事儿的动作;

用面向过程的思想去解决问题,当执行这件事的人不同的时候,我们必须为他量身定做不同的方式来解决问题;

面向对象;找个对象帮你做事; 面向对象就是屏蔽差异,写出通用的代码; 对象一般都是被动的那个;

我们在代码中描述一个对象,通过描述这个对象的属性和方法;

我们把这些具有相同属性和相同方法的对象进行进一步的封装,抽象出来类这个概念;

类就是个模子,确定了对象应该具有的属性和方法;对象是根据类创建出来的;

[public] class 类名

{  

字段;

属性;

方法;

}

如果方法前面加了static,那么调用的时候就要用类名.方法 ;如果这个方法和Main函数在同一个类中,那么可以省略类名,直接写方法名;

写好了一个类之后,我们需要创建这个类的对象,我们管创建这个类对象过程称之为类的实例化;使用关键字new; Person p = new Person(); 跟结构一样,通过对象.字段的方式调用;p.age = 24;

public void CHLSS()

{

 Console.WriteLine("我叫{0},我今年{1}岁了",this._name,this._age);

}

this表示当前类的对象; 通过对象.方法名的方式调用;p.CHLSS();

类是不占内存的;而对象是占内存的;

Person p; 跟int a;其实都是一个道理,声明一个变量;

我们自己写的类,我们称之为自定义类;

Person p;如果不创建对象,它的值是null;null在内存中是不占内存的; 如果创建了对象,那对象的字段就有了初值,因此开辟了内存空间;与其说对象占内存,不如说类当中的字段占内存;

如果方法不是static的,叫做非静态方法;那么调用它的时候,应该先创建一个对象,在用对象.的方式去调用方法;

结构和类的区别,结构是面向过程的,类是面向对象的;结构不具备面向对象的任何特征;类是真正的面向对象的;

属性的作用就是保护字段;对字段的赋值和取值进行限定;

属性应该写在类当中

public string _name;

public string Name

{

 get {return _name;}

 set {_name = value;}

}

属性的本质是两个方法,一个是get(),控制取值,一个是set();控制赋值;

通过反编译器可以看到程序的源代码;先把写好的程序编译一下,编译成功后,在文件资源管理器中找到bin下的debug目录下的.exe可执行文件,把它拖到反编译器 里面;就可以看到源代码;如果找到了属性,但是还想继续看下面的代码,先在上面把C#转换为IL&Bytes,继续往里点到最后,再把IL中间语言转化为C#,就能看懂代码了;

fields字段;methods方法;Properties属性

给字段赋值的时候会执行set方法,外面传进来一个值,通过属性,把值传给字段; 赋值的时候不能给字段赋值,要通过属性赋值,虽然是给属性赋值,但是最终赋值到的还是字段;属性在中间只起到过渡中间的作用;

当你给属性赋值的时候,首先会执行set()方法; 当你输出属性的值的时候,会执行get()方法

蓝色的长方体是字段;扳手图标是属性;

通过属性有2种方式对字段的取值和赋值进行限定;一个是在set()方法里面,一个是在get()方法里面;

在整个过程中,属性是没有存储值的。

打属性的快捷键 Ctrl+R,E两下回车;

字段是女人,存储数据用的,我们要好好保护起来;不能轻易得被别人访问到;属性才是男人,所有跟外界打交道的事应该交给属性去做;因此字段的访问修饰符是 private

访问修饰符 public:公开的,公共的,在哪都能访问  private:私有的,只能在当前类的内部进行访问,出了这个类就访问不到了;

类中,如果字段不加访问修饰符,默认就是private;

 get

{    

if(_gender != ‘男‘ && _gender != ‘女‘)  

   {

    return _gender = ‘男‘; 

   }

      return _gender;

 }

set

  if(value < 0 || value > 100)

  { 

    value = http://www.mamicode.com/0;

  }    

  _age = value;

  }

对同一个属性,在get()中控制值和在set()中控制值的效果是一样的; 等我们学了构造函数,在构造函数中也可以设定;

并不是所有的属性都有get()和set(); 如果一个属性既有get()又有set()我们称之为可读可写属性;只有get()我们称之为只读属性 只有set()我们称之为只写;

在set里面我们控制的是value的值,在get里面我们控制的是字段的值,先set()后get()因为先赋值后取值;

字段在类中必须是私有的,属性是公有的; 类中的成员,不加访问修饰符,默认是private;

给对象的每个属性赋值的过程叫做对相的初始化;

看一个成员是不是静态成员,就要看这个成员有没有被static修饰;

在非静态类中,即可以有实例成员,也可以有静态成员; 在调用实例成员的时候,需要使用对象名.实例成员(); 在调用静态成员的时候,需要使用类名.静态成员名; 静态成员必须使用类名去调用,而实例成员使用对象名调用;

在非静态类中可以有静态属性,静态字段,非静态属性,非静态字段,静态方法,非静态方法;

静态函数中,只能访问静态成员;不允许访问实例成员; 实例函数中,既可以使用静态成员,也可以使用实例成员; 静态类当中只允许有静态成员;不允许出现实例成员;

静态类不能创建实例对象,因为在调用静态成员的时候是用类名.的方法去调用,因此即使能够创建静态类的对象,也是没有意义的;

什么时候使用静态类:如果你想要你的类当做一个"工具类"去使用,这个时候可以考虑将类写成静态类; 我们把经常会使用的函数封装到一个类当中,我们称这个类是工具类;

静态类的特点:1.调用方便; 2.静态类在整个项目中,资源共享。

类是不占内存的,但是对象是占内存的,不过静态类例外;静态类没有对象,静态类的成员由于没有对象,因此只能用静态类本身来存;所以静态类本身是占内存的;

堆   栈    静态存储区域(存的是静态类的资源) 在整个项目中,谁都可以访问静态存储区域,因此也就造成了静态类在整个项目中资源共享;

QQ登陆之后,把账号,密码保存到一个静态类当中;因此访问不同的模块的时候不需要重新输入用户名和密码;

.net释放资源是用GC来完成的,垃圾回收器,但是有些东西是它释放不了的,比如我们所说的文件流; 静态类资源越少越好,1多的话占内存;2.只有在程序全部结束之后,静态类才会释放资源;所以静态类不要太多,它会始终消耗你的资源;

构造函数用来创建对象,并且可以在构造函数中对对象进行初始化(给对象的每个属性依次的赋值);

构造函数是用来创建对象的特殊方法; 1.构造函数没有返回值,连void都不能写 2.构造函数的名称必须跟类名一样;

构造函数可以有参数,new对象的时候传递函数参数即可

如果不指定构造函数,则类有一个默认的无参构造函数。如果指定了构造函数,则不再有默认的无参构造函数,如果需要无参构造函数,则需要自己来写

类里面可以有字段,属性,方法,构造函数;

构造函数的访问修饰符必须是public;

public Student()

{  

}

在我们创建对象的时候,首先会执行构造函数; 如果想初始化对象的话,就在构造函数中对对象的每个属性赋值;

public Student

(string name,int age,char gender,int chinese,int math,ing english)

{  

this.Name = name;  

this.Age = age;  

this.Chinese = chinese;  

this.Gender = gender;  

this.Math = math;  

this.English = english;

}

创建对象的时候会调用构造函数,要求你传入6个参数,构造函数把你传入的值依次得赋值给这个对象对应的属性;

 Student zsStudent = new Student("张三",18,‘男‘,100,100,100);    

//zsStudent.Name = "张三";    

//zsStudent.Age = 18;    

//zsStudent.Gender = ‘男‘;    

//zsStudent.Chinese = 100;    

//zsStudent.Math = 100;    

//zsStudent.English = 100;  用了有参数的构造函数这些给属性赋值的代码就不必用了;因此构造函数可以大大减少代码量;    

zsStudent.SayHello();    

zsStudent.ShowScore();

new关键字;     Student s = new Student();    

new帮助我们做了三件事;     1.在内存中开辟一块空间;     2.在开辟的空间中创建对象;     3.调用对象的构造函数进行初始化对象;     

这三步有一步完不成这个对象就创建不出来;因此构造函数的访问修饰符必须是public;如果是private的话其他类里面创建对象的时候就访问不到这个构造函数了;    

public Student(string name,int age,char gender)   

{      

this.Name = name;      

this.Age = age;      

this.Gender = gender;    

}

构造函数可以重载,也就是有多个参数不同的构造函数。

我们写好一个类之后,就有一个自带的默认无参的构造函数; 类当中会有一个默认的无参的构造函数,当你写一个新的构造函数之后,不管是有参数的还是无参数的,那个默认的无参数的构造函数都被干掉了;

 public Student(string name,int chinese,int math, int english):this(name,"0",‘男‘,chinese,math,english)   

{         

}

public Student(string name,int chinese,int math, int english):this(name,"0",‘男‘,chinese,math,english)

调用的时候   Student zhangSan = new Student("张三",100,100,100);

执行的过程是先调用这个构造函数,调用这个构造函数的时候又调用全参的构造函数; 把(string name,int chinese,int math, int english)这些参数传给全参的构造函数;再由全参的构造函数赋值给每个属性;归根结底调用的是全参的构造函数; 这就是通过类中的构造函数去显示的调用另外的构造函数;目的就是减少冗余代码;

this的作用 1.代表当前类的对象;  2.在类当中显示的调用本类的构造函数:this

类里面可以有字段,属性,方法,构造函数,析构函数;

析构函数

~Student()    //这就是析构函数;

{   

}

当程序结束的时候,析构函数才被执行;

析构函数对我们的作用就是释放资源;.net有GC  GarbageCollection垃圾回收器,能够自动的帮助我们释放资源; 但一般我们不去手动的调用GC帮我们回收,而是我们的程序自动使用GC帮我们回收程序;这时候有个问题,有可能我们的程序结束后,GC没有马上帮助我们 释放资源;如果你想要资源马上去释放的话,那我们就要去使用析构函数;如果不使用析构函数的话,那么就由我们的垃圾回收器GC自动帮我们释放资源;

public class Ticket

{  

private double _distance;    

public double Distance  

  {     

  get{return _distance;

  }   

}     

public Ticket(double distance)   

{      

 if(distance < 0 )      

   {        

        distance = 0;       

    }      

    this._distance = distance;      //在构造函数中也能控制字段的值的非法性,另外还有在属性的get和set方法中也能控制字段的非法性;    

}

   privete double _price;      

   public double Price   

   {

      get

          { 

              if(_distance > 0 && _distance <= 100)          

               {  return distance * 1.0; }         

             else if(_distance >= 101 && _distance < 200)          

               {  return distance * 0.95; }           

             else if(_distance >= 201 && _distance < 300)          

                {   return distance * 0.9;}           

              else           

              {   return distance * 0.8;}        

               }             //get是一个天然的方法;在取值的时候就会调用这个方法;

           }

     public void ShowTicket()     

    {        

     Console.WriteLine("{0}公里的价格是{1}",Distance,Price);      

    }   

}

15-01-10 C# 面向对象 09