C#面向对象

C#面向对象(一)

 

一:面向对象的基本知识html

C#程序分为面向过程和面向对象编程

什么是对象:一切皆为对象:Object,生活中常说的“东西”就是程序里面所指的对象;生活中遇到的东西咱们都在下意识的归类;归类意味着抽象模型;安全

类:class,对某类众多对象的共同特色抽象出来的模型。less

他们的关系:类是好多对象的抽象,对象是类的实例化。dom

建立一个名为Dog的类:编程语言

复制代码
复制代码
 class Dog  //通常首字母大写
    {
       int age;
       public void setage(int a) //用方法赋值
        {
           age = a;
        }
       public void buck()
        {
            Console.WriteLine("这是一个方法");
        }
    }
复制代码
复制代码

类中通常包括两类东西,变量(名词,也交成员变量这里age是成员变量)和函数(动词,也叫成员函数或成员方法 buck()就是方法)。ide

对象实例化:函数

Dog d1 = new Dog();

这样就实例化出了一个Dog的对象a。工具

例子:两个套在一块儿的圆,求内圆的周长和内圆与外圆之间的面积,用面向对象的思想作post

复制代码
class circle
    {
        float r;
        public circle(float a)
        {
            r = a;
        }
        public double zhouchang()
        {
            return 2 * 3.14 * r;
        }
        public double mianji()
        {
            return 3.14 * r * r;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            circle m = new circle(10);
            circle n = new circle(20);
            double bc = m.zhouchang();
            double mj = (n.mianji()-m.mianji());
            Console.WriteLine("内圆的周长为:"+bc);
            Console.WriteLine("花砖的面积为:"+mj);
        }
    }
复制代码

首先作了一个名为circle的类,它能够生产任何一个半径不一样的圆,在构造函数中,为半径赋值。

 

二:面向对象的三大特性

三大特性是指:封装,继承,多态。

类中的方法通常分为:构造方法(函数);属性方法(函数):成员变量赋值取值;行为方法(函数):变量运算。

(一): 封装

1.封装含义:

(1)不一样类的变量只属于各自的类。

(2)不一样对象的成员变量只属于各自的对象,彼此不受影响。

      (3)对象中的变量须要经过方法(函数)实现操做,比较安全。

封装为了安全,尽可能不用public来声明变量,避免在main函数中能够直接访问赋值而下降了安全性,在类中创建public的方法来赋值,main中调用此方法传值。

2. 成员变量及访问修饰

private 私有成员 ,protected 受保护的成员,public 公有成员

3. 构造函数

它是一个特殊的成员函数,通常在构造函数里进行初始化。若是不写构造函数在new的时候会自动生成一个默认空的构造函数。

写法特殊:没有返回值,函数名只能与类名同样;public 类名(){};

执行特殊:类在实例化(new出来的时候)自动执行,构造函数是最先执行的成员函数,构造函数是用来生成对象的函数。

它的主要做用:对象实例化生成的时候,作一些初始化的工做。

下面例子就是作了一个Ren()的构造函数,为其变量赋上初始化的值:

复制代码
 class Ren
    {
        string _Name;
        int _Age;

        public Ren()
        {
            _Name = "龙神";
            _Age = 25;
        }
    }
复制代码

4. 重载(函数或方法)

函数名相同,参数不一样(参数个数或类型不一样)的多个函数就造成了重载。

重载只与函数名和形参有关,与返回类型无关。

下面举个例子,构造函数的重载:

复制代码
    class Ren()
        {
            string _Name;
            int _Age;

            public Ren()
            {
                _Name = "ZSMJ";
                _Age = 25;
            }
            public Ren(string name)
            {
                _Name = name;
            }
            public Ren(string name,int age)
            {
                _Name = name;
                _Age = age;
            }
        }
复制代码

这样Ren类中就作了三个构造函数,第一个是无参的,第二个是一个string类型的参数,第三个是两个参数,类型分别为string和int。他们符合重载的条件,因此会造成重载在Main函数中new的时候根据参数的不一样会自动选择执行其中一个构造函数。

若是在Main函数中:

Ren a = new Ren("王大锤");

则执行的构造函数是第二个。

5.  属性

它的声明:public 类型 属性名;也能够选择成员变量右键重构,封装字段来生成属性方法,例如:

    string _Name;
    public string Name
   {
      get { return _Name; }
      set { _Name = value; }
   }

这样Name就是该类的一个属性,在Main函数中能够用此属性为其成员变量赋值取值:

     Ren a = new Ren("王大锤");
     a.Name = "王尼玛";

注意:(1)属性是用来为成员变量赋值和取值的,它有代替属性方法的做用,通常用属性。

(2)属性定义的时候,属性名后面没有小括号。

(3)属性都是public。

(4)属性中只能包含两个部分:get和set。代码也只能写在get和set的花括号里面。

(5)属性分为只读属性,只写属性和可读写属性,与get和set的有无有关系。

6. this关键字

概念:this引用,this在哪一个对象里面执行表明该对象自己。

用法:this.成员变量(成员方法),this._Name; this.Eat();

例子:this 调用当前对象的其它构造函数。

复制代码
  public class Mydate
    {
        int _Year;
        int _Month;
        int _Day;
        int _Hours;

       public Mydate(int year,int month) 
       {
           _Year = year;
           _Month = month;
       }
       public Mydate(int year,int month,int day,int hours): this(year,month)
       {
           _Day = day;
           _Hours = hours;
       }
    }
复制代码

这里第一个构造函数中有两个参数year和month,在作第二个构造函数的时候为了方便用“:this”来调用了本类中第一个构造函数,这样第二个构造函数只需写后day和hours的执行语句就能够了。

在new的时候传入不一样的参数,会实例出不一样的对象,这时候的this就表明不一样的对象。

7. is关键字(运算符)

用法:对象 is 类名;is左边是对象,右边是类型;

 Console.WriteLine(a is Ren);

若是a是一个Ren类的对象,则返回值为true,不然返回值为false。

8. partial关键字

若是一个类特别大,不宜挡在一个文件中实现或者一个类中有一部分代码不宜与其余混淆或者须要多人合做编写一个类,这就须要将一个类拆开来写。

用partial关键字能够实现,也能够用来补充完善类,扩展性比较强。
 
如在程序集里的一个文件里写了 partial class Ren{里面是成员} ; 在另外一个文件里也能够对Ren类进行补充,须要这样写 partial class Ren{里面是成员} 。
 
9. 静态成员

非静态变量称为实例变量,非静态方法称为实例方法,实例成员的数据存在每一个对象中,用对象名来调用。

静态成员包括:静态变量,静态属性,静态方法。

定义一个成员为静态的:在变量或方法前加static,如:static int a;

静态变量是属于类的,每一个对象都有的而且相同的东西只保存一份,不和实例变量那样在每一个对象里都面保存一份。

能够说它不属于任何对象,也能够说它又属于任何一个对象,给每一个对象用,节省空间。

例如:每包粉笔的颜色是静态成员,每支粉笔的剩余长度是实例成员。

静态变量或方法不须要new出来。

在C#中,定义了一个粉笔的类:

复制代码
   class Fenbi
   {
       static string _Color;

    public static string Color
    {
      get { return Fenbi._Color; }
      set { Fenbi._Color = value; }
    }
       int _Lenght;

    public int Lenght
    {
      get { return _Lenght; }
      set { _Lenght = value; }
    }  
   }
复制代码

(1)在当前类的花括号外,静态成员只能用类名来调用,不能用对象名来调用,而实例成员只能用对象名来调用,不能用类名来调用。

      Fenbi.Color ="Yellow";
      Fenbi b = new Fenbi();
      b.Lenght = 10;

(2)在当前类的花括号内,静态方法只能直接调用静态成员,不能调用非静态成员,实例方法能够调用非静态和静态的成员。

     public static void xiezi()
       {
           Console.WriteLine("写出"+_Color+"的文字了");
       }
     public void change()
        {
            Console.WriteLine(_Color+"的粉笔长度变为:"+_Lenght);
         }

10.  拷贝

浅拷贝:传递引用,不赋值对象。
深拷贝:建立一个新的对象。

 

(二): 继承

1. 语法:public 子类名:父类名;如:class Dog:Pet。

2. 特色:单继承,一个父类能够派生多个子类,但每一个子类只能有一个父类

             若是一个类,没有明确指定父类是谁,默认是object。除了object类以外,全部类都有一个父类。

             子类能够从父类继承下父类的成员变量和成员方法。

3. 访问修饰符合访问权限:

private 的成员不被继承,只能在该类中访问。

protected成员能够被继承,能在该类和派生类中访问到,在外界访问不到。父类中的变量通常用protected。

public成员能够被继承,能在全部地方访问到。

4. base 关键字:子类中能够用(base.父类中的成员 )来调用父类中的成员,base()调用父类构造,base.xxx()调用父类成员方法。

调用的参数值会被覆盖,方法也会被覆盖。

5. 继承关系中实例化子类的流程:

先执行父类的构造函数,再执行子类的构造函数。

6. 继承关系的实例化:

若是父类的构造函数没有空参构造函数,全是带参数的,则子类必需要写构造函数,构造函数的形参中必须包含父类构造函数所须要的参数,还要用base()把父类构造函数所须要的参数传递父类。

      例如:父类中只有这个构造函数

      public Ren(string name, int age)
      {
          _Name = name;
          _Age = age;
      }

那么子类中的构造函数应该这样写:

      public Chinese(string name, int age, string yuyan):base(name,age)
        {
            _Yuyan = yuyan;
        }

7. sealed 关键字:

若是用来修饰class,称为密封类,此类没法被继承;若是用来修饰方法,该方法没法被重写。

如: sealed class Ren{};

 

(三): 多态

1. 概念:父类引用指向不一样子类实例的时候,父类引用所调用的函数都是子类的函数,因为子类对象不一样,父类引用调用的成员表现出来的不一样状态就是一种多态。

2. 实现的方式:多态须要经过继承来实现

3. 分类:分为编译多态(重载overload)和运行多态(重写override)。父类方法被重写了以后也能够在子类中用base.方法 调用。

4. virtual关键字:虚方法,允不容许重写,要重写父类方法必须是虚方法:public virtual void Eat()。

5. 运行多态实现的条件:

(1)子类对父类方法的重写(override),父类和子类中都有相同的方法。

(2)父类引用指向子类实例。

例如,有一个Ren类是父类,一个Chinese类和American是子类,Ren r = new Chinese();父类的引用 r 指向子类实例。

复制代码
    class Ren
    {
        protected string _Name;
        protected string _Country;
        public virtual void Eat()
        {
            Console.WriteLine("正在吃饭...");
        }
    }
    class American : Ren
    {
        public override void Eat()
        {
            Console.WriteLine("正在用叉子和刀子吃饭....");
        }
    }
    class Chinese : Ren
    {
        public override void Eat()
        {
            Console.WriteLine("正在用筷子吃饭...");
        }
    }
复制代码

父类Ren中有个Eat方法为虚方法,在子类Chinese和American中进行了重写,在Main函数中:

复制代码
    Random rand = new Random();
    int n = rand.Next(100);
    Ren a;
    if (n % 2 == 0)
    {
        a = new American();
    }
    else
    {
        a = new Chinese();
    }
    a.Eat();
复制代码

随机让父类引用 a 指向 不一样的子类实例,这样用父类引用 a 调用方法Eat()的时候表现出不一样对象的操做。

6. 里氏代换原则和抽象依赖原则

里氏代换原则,若是某个方法接收的是父类引用,能够向里面传父类或其子类的元素,子类对象替代父类对象。

抽象依赖原则,用父类的引用来指向子类的实例。

例子:怪兽吃人,传入Ren的引用 r ,则r.Cry()表现出来不一样的结果。

复制代码
class Monster
    {
        public void EatFood(Ren r)   //r = a;
        {
            r.Cry();
            Console.WriteLine("人类真好吃,吃饱了!");
        }
    }
    class Ren   
    {
        public virtual void Cry()
        {
            Console.WriteLine(".......");
        }
    }
    class American:Ren
    {
       
        public override void Cry()
        {
              Console.WriteLine("MyGod,God bless me!");
        }
    }
    class Chinese:Ren
    {
        public override void Cry()
        {
            Console.WriteLine("天哪,老天爷保佑我!");
        }
    }
复制代码

在Main函数中 ,先实例出一个怪兽,随机生成一个Ren的对象,将此对象的引用传入怪兽类里,经过这个引用来表现出不一样的状态。          

复制代码
            Monster m = new Monster();
Random rand = new Random(); int n = rand.Next(100); if (n % 2 == 0) { American a = new American(); //或者是这样写 Ren a = new American(); m.EatFood(a); } else { Chinese c = new Chinese(); //或者是这样写 Ren c = new Chinese(); m.EatFood(c); }
复制代码
 
 
 

一:抽象方法

1. 在面向对象编程语言中抽象方法指一些只有方法声明,而没有具体方法体的方法。抽象方法通常存在于抽象类或接口中。

    在一些父类中,某些行为不是很是明确,所以没法用代码来具体实现,可是类还必须具有此方法,所以,把这样的方法定义为抽象方法。

2. 声明方法:public abstract Eat(); 方法声明只是以一个分号结束,而且在签名后没有大括号,没有函数体,由于太抽象不清楚,具体的实现由各个子类中重写函数实现。

3. 它的特色:

(1) 抽象方法是隐式的 virtual 方法。

(2) 只容许在抽象类中使用抽象方法声明。

(3) 由于抽象方法只声明不提供实实现,因此没有方法体。抽象方法只在派生类中真正实现,这代表抽象方法只存放函数原型(方法的返回类型,使用的名称及参数),而不涉及主体代码。

(4) 加abstract关键词。

(5)抽象方法的目的在于指定派生类必须实现与这一方法关联的行为。

二:抽象类

1. 抽象类:没法被实例化的类。关键词是abstract,凡是带有abstract关键词的类都没法被new出来。抽象类是不完整的,它只能用做基类。在面向对象方法中,抽象类主要用来进行类型隐藏和充当全局变量的角色。

2. 声明:抽象类声明:public abstract class Ren{};

3. 注意:

(1)凡是带有抽象方法的类确定是抽象类;抽象类却不必定包含抽象方法。

(2)构造方法,静态成员方法不能声明为抽象方法。

(3)一个非抽象类必须实现从父类继承来的全部抽象方法,若是有一个抽象方法没有实现,则此类必需要加abstract关键字。若是父类被声明为抽象类,并存在未实现的抽象方法,那么子类就必须实现父类中全部的abstract成员,除非该类也是抽象的。

4. 特征:

(1)抽象类不能实例化。

(2)一个抽象类能够同时包含抽象方法和非抽象方法。

(3)不能用sealed修饰符修饰抽象类,由于这两个修饰符的含义是相反的,采用sealed修饰符的类没法继承,而abstract修饰符要求对类进行继承。

(4)从抽象类派生的非抽象类必须包括继承的全部抽象方法和抽象访问器的实际实现。

例子:Ren类中有一个抽象方法Eat(),在其派生类Chinese和American中必须重写这个方法

复制代码
abstract class Ren
    {
        protected string name;
        public abstract void Eat();
    }

    class Chinese:Ren
    {
        public override void Eat()
        {
            Console.WriteLine("用筷子吃饭");
        }
    }
    class American : Ren
    {
        public override void Eat()
        {
            Console.WriteLine("用刀叉吃饭");
        }
    }
复制代码

三:接口

1. 关键字:interface,用interface 关键词来定义。

2. 概念:极度抽象的类,无成员变量,无实例属性和实例方法,只有抽象方法或抽象属性,生活中的例子:标准,规则。

 

3. 写法:接口不用class,用interface,名字通常以I做为首字母;不用写abstract,里面全部都是,不用写public,必须是public。

    interface IUSB         //接口
    {
        void start();
        void stop();
    }

4. 特色:

(1)接口中的方法都是抽象的,所以无需加abstract修饰符。

(2)接口中的方法都是公用的,所以无需加public修饰符。

(3)接口就是一个规则标准。

(4)接口能够继承父接口。

(5)一个类能够实现(继承)多个接口。一个类只能有一个父类,但能够实现多个接口。

例子:简单的IUSB接口,里面有两个抽象方法start()和stop(),派生类实现接口必须实现接口中的全部方法。

复制代码
 interface IUSB         //接口
    {
        void start();
        void stop();
    }
    class UDisk : IUSB  //实现接口必须实现里面的全部方法
    {
        public void start()
        {
            Console.WriteLine("U盘启动了");
        }
        public void stop()
        {
            Console.WriteLine("U盘中止了");
        }
    }
    class Cammer : IUSB
    {

        public void start()
        {
            Console.WriteLine("摄像头启动了");
        }

        public void stop()
        {
            Console.WriteLine("摄像头关闭了");
        }
    }

    class computer
    {
        public void CheckUSB(IUSB usb)
        {
            usb.start();
        }
        public void CloseUSB(IUSB usb)
        {
            usb.stop();
        }
    }
复制代码

用的时候:

复制代码
       computer c = new computer();
       UDisk u = new UDisk();
       Cammer m = new Cammer();

       c.CheckUSB(u); //插入U盘
       c.CheckUSB(m); //插入摄像头

       c.CloseUSB(u); //拔出U盘
       c.CloseUSB(m); //插入摄像头
复制代码

四:命名空间

1. 概念:namespace 至关于一个包,它是对类进行分类管理的工具,给计算机看的,相同命名空间下的类能够分在不一样的文件中存储。

2. 通常写法:namespace 公司名.项目名.模块名

3. 在别的命名空间上面要使用其它命名空间内的类,能够在它的上面写 using 要使用的命名空间;

五:项目名

通常默认:ConsoleApplication1,用来给人类标识出这个项目是作什么的,给人看的。

六:程序集

在项目名上打右键:属性,便可修改程序集名称

编译出来的exe或dll文件就是程序集。exe是控制台应用程序,dll是库类。

程序集的名字就是编译出来的exe或dll名字。

若是一个项目分三我的来写,A写一个类库,B写一个类库,C写Main函数,把他们整合在一块儿的流程是:

1. A写完了编译出一个名字如 cc.dll 的文件;

2. B写的时候要用到A命名空间中的某个类,B先将A的cc.dll文件拷贝到本身的目录下,B须要在项目中的引用上打右键:添加引用,经过浏览找到该引用添加进来,而后using A 的命名空间;

3. B写完了编译出一个名字如 dd.dll 的文件;

4. C要写Main函数,在Main函数中操做AB中的类,他须要将AB的dll文件拷贝过来,而后再项目中的引用上打右键,添加引用,经过浏览找到该引用添加进来,而后using A 的命名空间; using B的命名空间,这样就能够在Main函数中用了。

5. 若是A的命名空间中有个类Ren和B的命名空间中有个类Ren重名了,这C在用的时候要用哪个命名空间下的Ren类就要用该命名空间点出来再用。

相关文章
相关标签/搜索