回头看——面向对象

          前段时间,八期给我们讲设计模式学术交流,由于设计模式大家都学的不是很好,所以,我们九期听的也非常费力,就算不费力,也只限于弄明白理论上的了,也不是太会用。后来米老师又给我们讲,结合我们实际的项目,来讲设计模式,通过深刻的挖掘,和对比,使我们收获很大。其中对多问几个为什么,追根溯源等有了进一步的理解。

 

         下来,我认真的思考过,为什么我们学习不好设计模式,为什么一直不会用,就算不合理的也用不上。一方面和我们对囫囵吞枣学习有误解,这个仅限于我们初级阶段的学习,而随着我们项目的实践,知识的运用,我们必须深刻的理解知识,学习触类旁通,必须在实践中弄懂知识之间的联系与区别,弄清楚知识的来龙去脉,这样才能举一反三,才能在项目中运用自如,这样才能走向高手的地位!


         但是对于我现阶段的学习,我认为学习设计模式,必须先把设计模式的必备知识——面向对象的基础学习的很透彻,学习设计模式才会更容易些,因为设计模式就是为了更好的实现面向对象,而设计模式这些框架,就是很好的运用来搭配运用面向对象的基础知识。再次看面向对象的基础,感觉清晰很多,理解更深刻,总结一下。

        

       先看这张图,大概说了下各部分之间的关系,可能有的地方不合理,但是为了比较,我也放到哪里了,有什么问题还请提出:




   一,首先说类,这是面向对象最最基础的:

                1,类的实例化很简单:

		class Cat
		{
		         Public string Shout()
		         {
		               renturn"喵";
		         }
		}
		
		Private void button1_Click(object  sender,EventArgs e)
		{
		      Cat cat=new Cat();//类的实例化
		      messageBox.show(cat.shout());
		}

              2,类的初始化:构造方法(又叫构造函数)

                   a,特点:构造方法与类同名,无返回值,也不需要void,在new时候调用。如果不写,则系统默认为空的构造方法。


                   b,例子:

		Class Cat
		{
		     private string name="";//声明Cat类的私有字符串变量
		     public Cat(string name)//定义Cat类的构造方法
		     {
		         this.name=name; //将参数赋值给私有变量
		     }
		
		   public string shout()
		   {
		      return"我的名字叫做" +name+"喵";
		   }
		}

                      c,对于构造方法的继承,继承中给出!


    3,类的属性和方法,大家应该都非常属性,这里我重点区分一下面向对象中类的修饰符:public,private,protected.

         public:声明全局变量,也就是说整个项目都可以访问到。

         private:声明私有变量,也就说只有这个类内部可以访问。

         protected:声明局部保护变量,只有其继承类可以访问。


        注意:在将类抽象时,需要将类中的private修饰符,变为protected,因为抽象类就是用来继承的。

 

           二,封装:也就是每个对象都包含它们能进行操作所需要的所有信息。也是我们类,对象,抽象类等需要满足的。这样才会有一下几个优点:

            1,良好的封装能够减少耦合;

            2,类内部的实现可以自由的修改;

            3,类具有清晰的对外接口。

    

            三,继承:对于定义就不说了,


                         1,我们需要先记住这三句话:


                             a,子类拥有父类的非private的属性和功能;


                             b,子类具有自己的属性和功能,也就说子类可以扩展父类没有的属性和功能;


                             c,子类还可以以自己的方式实现父类的功能(方法重写)。


                        2a,构造方法:在子类中用base关键字调用父类的构造方法。


                              b,虚方法:为了使子类能够完全接替父类方法,有些必须要声明为虚方法,用virtual关键字声明,这样不同的子类就可以通过方法重写,用自身的方式实现父类的方法了。


                             c,抽象类,就是类的抽象,例如,人类是对每个具体人的抽象,猫类是对每个具体猫的抽象,而动物类就是对人类和猫类的抽象。用abstract class 类名来声明。里边的虚方法也加上abstract就成了抽象方法了。


                              d,接口,声明用interface,里边的方法,属性能有修饰符,因为不能实例化。是将公共方法和属性组合起来,供其他类实现这些的一个集合。


                       例子:

                      Animal

   class Animal//声明一个父类 ,加上abstract就是抽象类了。 
       
    {  
        protected string name = "";//声明类的的私有字符串变量name,用protected
         
        public Animal(string name)//构造方法,参数是输入一个字符串  
        {  
            this.name = name; 
        }  
  
        public Animal()//将构造方法重载  
        {    
            this.name = "无名";  
        }  
  
        protected int shoutNum1 = 3;  
        public int ShoutNum1 
        {  
            get//get表示外界调用属性的值  
            {  
                return shoutNum1;  
            }  
            set//set表示外界可以给属性的赋值  
            {  
                shoutNum1= value;  
            }  
        }  
                  public virtual string Shout()//用virtual定义虚方法,被子类重写,换位abstract为抽象方法了
                  {
                          return"";
                  }
  
    }  

          接口:


		interface IChange
		{
		     string   ChangeThing(string thing);
		}

        声明类来继承上边的父类和接口:


		class Cat:Animal,Ichange
		{
		      public MachineCat():base()//构造方法的继承
		     {
		     }
		    public  MachineCat():base(name)//构造方法的继承
		    {
		    }
		   public override string Shout()//虚方法的重写
		    {
		        return"我的是"+name+"  喵";
		    }  
		    public string ChangeThing(string thing)//接口方法的实现
		   {
		       return  "我是猫,我可以变出:"+ thing;
		   }
		}

          备注:a,虚方法和抽象方法的区别:虚方法是写在普通类里的供子类重写的方法,而抽象方法,可以看做是抽象类里边的虚方法。


                        b,抽象类和接口的区别:1,从继承角度上来说,继承抽象类的子类,可以重写抽象类的方法,可以拓展功能;而继承接口,也就是实现接口,必须完全实现接口的方法;  2,从数量上说,子类只能继承一个抽象类,而类可以死实现一个或好几个接口;    3,从生成角度上看,抽象类是由对象抽象出类,由类抽象出抽象类的,为自底向上的形成,而接口,是自己制定方法,由子类去实现的,为自顶向下的形成。

 

           四,多态,表示不同的对象可以执行相同的动作,但要通过它们自己的实现代码来执行。

                1,实现多态的两种根本方法:方法重写(override)和方法重载,这两个上边代码都出现过。


                2,两者的区别:方法重写,一般是将虚方法,抽象方法等,在子类中进行实现,方法名,参数等都一样。     方法重载,是在一个类中,为了实现多态,将某些方法,进行改变参数或者返回值,而方法名不变,来实现重载。             而编译和运行来看,方法重写是在运行时进行动态绑定调用,而方法重载则是在编译时。


               3,对于数组和集合,为什么我放到这里呢?因为多态么,多个对象,需要我们用数组或集合来实现,我以前写过篇博客,有内容,看连接:C#语言知识汇总


               4,两者的优缺点:数组优点,在内存中存储,很容易从头到尾遍历元素,可以快速修改元素。 缺点:必须要限制数组的长度,两个元素直接添加元素也比较困难。     集合呢?优点:使用大小可以根据需要动态的增加删除元素,非常方便。缺点:就是集合为不类型安全的,输入什么类型都可以,容易引起错误。


               5,泛型呢?就是为了弥补上边集合缺点而设计的。也就是来声明集合的变量的。此时集合成为泛型集合。一般在集合后加<变量类型>。看个例子:


 IList<Animal> arrayAnimal;//声明一个泛型集合变量,用接口Ilist,注意Ilist<Animal>表示此集合变量只能接受Animal类型 ,也可以直接用List<Animal>   
        private void button3_Click(object sender, EventArgs e)//动物报名按钮,  
        {  
            //arrayAnimal = new Animal[5];//实例化最多可以可报名5个的动物数组对象  
            arrayAnimal = new List<Animal> ();//实例化List对象  
            arrayAnimal.Add(new Cat ("小花"));//报名分别是猫和狗  
            arrayAnimal.Add( new Dog("阿毛"));  
            arrayAnimal.Add ( new Dog("小黑"));  
            arrayAnimal.Add(new Cat("娇娇"));  
            arrayAnimal.Add( new Cat("咪咪"));  
      
            MessageBox.Show(arrayAnimal.Count.ToString());//打印出我们添加的个数  
  
            arrayAnimal.RemoveAt(1);//这里还可以删除我们多添加的。  
  
        }  

  

    五,委托:是一种引用方法的类型,一旦为委托分配了方法,委托将与该方法具有完全相同的行为。声明委托的关键字。


                   事件:发生其他类或对象关注的事情时,类或对象可通过事件通知它们。声明事件的关键字event

               委托例子:


Class Cat//声明一个猫类
{
     private string name;
     public Cat(string name)
     {
         this.name=name;
     }
    public delegate void CatShoutEventHandler();//声明一个委托

    public event CatShoutEventHandler CatShout;//声明事件CatShout它的事件类型是上边声明的委托
    public void Shout()
   {
       Console.WriteLine("喵,我是{0}.",name);
        if (CatShout!=null)
        {
            CatShout();//表明当执行Shout()方法时,如果CatShout中有对象登记事件,则执行CatShout()!
        }
   }
}

Class Mouse
{
    private string name;
    public Mouse(string name)
   {
     this.name=name;
   }
   public void Run()//逃跑的方法
   {
     Console.WriteLine("老猫来了,{0}快跑",name);
   }
}

Static void Main(string[] args)
{
     Cat cat =new Cat("Tom");
     Mouse mouse1=new Mouse("John");
     Mouse mouse2=new Mouse("Jack");
  
    cat.CatShout+=new Cat.CatShoutEventHandler(mouse1.Run);//将Mouse的Run方法通过实例化委托Cat.CatShoutEventHandler登记到Cat的事件CatShout当中。
    cat.CatShout+=new Cat.CatShoutEventHandler(mouse2.Run);
    
    cat.Shout
    Console.Read();
}

    委托也就是将Mouse的方法,添加到猫叫当中,当猫叫时,直接通过老鼠,使其发生run的动作。

  

          事件+委托,可以更好的完善委托,使我们的程序更加合理。EventArgs是我们代码经常见的,它是包含事件数据的类的基类。我们来看上边的例子加上事件后的写法,看是不是方便了:


public classCatShoutEventArgs:EventArgs//声明一个事件类,继承EventArgs
{
   private string name;
   public string Name
    {
      get{return name;}
      set {name=value;}
    }
}
 
Class Cat//声明一个猫类
{
     private string name;
     public Cat(string name)
     {
         this.name=name;
     }
    public delegate voidCatShoutEventHandler(object sender,CatShoutEventArgs  args);//声明一个委托,此时有两个参数。注意和上边的不同
 
    public eventCatShoutEventHandler CatShout;//声明事件CatShout它的事件类型是上边声明的委托
    public void Shout()
   {
      Console.WriteLine("喵,我是{0}.",name);
        if (CatShout!=null)
        {
            CatShoutEventArgs e =new CatShoutEventArgs();
            e.Name=this.name;
           CatShout(this,e);//当事件触发时,通过所有登记过的对象,并将发送通知,以及需要的数据传递过去。
        }
   }
}
 
ClassMouse
{
    private string name;
    public Mouse(string name)
   {
     this.name=name;
   }
   public void Run(object sender,CatShoutEventArgs args)//逃跑的方法
   {
     Console.WriteLine("老猫来{0}了,{1}快跑",args.Name,name);
   }
}

   客户端不变,这样猫的名字就传过来了,更加合理化了。这就是事件在委托中的运用。

 

         对于委托和观察者模式:相同点就是,都是被动变为主动,使被委托的人,被通知的人,主动来接受信息,主动来进行各种动作。不同点:其实就是观察者模式将委托很好的运用,委托为观察者的核心。委托只是一种方法,而观察者为一种结构。

  

 

    综上为面向对象的基础,感觉这次理解更加深刻了,剩下就是利用这些东西来学习设计模式!如何能够更好的学习设计模式,领会它的本质,精华,才是更本!




  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 28
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值