关键词搜索

源码搜索 ×
×

回头看——面向对象

发布2013-08-07浏览3410次

详情内容

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

 

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


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

        

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




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

                1,类的实例化很简单:

  1. class Cat
  2. {
  3. Public string Shout()
  4. {
  5. renturn"喵";
  6. }
  7. }
  8. Private void button1_Click(object sender,EventArgs e)
  9. {
  10. Cat cat=new Cat();//类的实例化
  11. messageBox.show(cat.shout());
  12. }

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

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


                   b,例子:

  1. Class Cat
  2. {
  3. private string name="";//声明Cat类的私有字符串变量
  4. public Cat(string name)//定义Cat类的构造方法
  5. {
  6. this.name=name; //将参数赋值给私有变量
  7. }
  8. public string shout()
  9. {
  10. return"我的名字叫做" +name+"喵";
  11. }
  12. }

                      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

  1.   class Animal//声明一个父类 ,加上abstract就是抽象类了。 
  2.        
  3.     {  
  4.         protected string name = "";//声明类的的私有字符串变量name,用protected
  5.          
  6.         public Animal(string name)//构造方法,参数是输入一个字符串  
  7.         {  
  8.             this.name = name; 
  9.         }  
  10.   
  11.         public Animal()//将构造方法重载  
  12.         {    
  13.             this.name = "无名";  
  14.         }  
  15.   
  16.         protected int shoutNum1 = 3;  
  17.         public int ShoutNum1 
  18.         {  
  19.             get//get表示外界调用属性的值  
  20.             {  
  21.                 return shoutNum1;  
  22.             }  
  23.             set//set表示外界可以给属性的赋值  
  24.             {  
  25.                 shoutNum1= value;  
  26.             }  
  27.         }  
  28. public virtual string Shout()//用virtual定义虚方法,被子类重写,换位abstract为抽象方法了
  29. {
  30. return"";
  31. }
  32.   
  33.     }  

          接口:


  1. interface IChange
  2. {
  3. string ChangeThing(string thing);
  4. }

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


  1. class Cat:Animal,Ichange
  2. {
  3. public MachineCat():base()//构造方法的继承
  4. {
  5. }
  6. public MachineCat():base(name)//构造方法的继承
  7. {
  8. }
  9. public override string Shout()//虚方法的重写
  10. {
  11. return"我的是"+name+" 喵";
  12. }
  13. public string ChangeThing(string thing)//接口方法的实现
  14. {
  15. return "我是猫,我可以变出:"+ thing;
  16. }
  17. }

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


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

 

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

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


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


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


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


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


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

  

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


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

               委托例子:


  1. Class Cat//声明一个猫类
  2. {
  3. private string name;
  4. public Cat(string name)
  5. {
  6. this.name=name;
  7. }
  8. public delegate void CatShoutEventHandler();//声明一个委托
  9. public event CatShoutEventHandler CatShout;//声明事件CatShout它的事件类型是上边声明的委托
  10. public void Shout()
  11. {
  12. Console.WriteLine("喵,我是{0}.",name);
  13. if (CatShout!=null)
  14. {
  15. CatShout();//表明当执行Shout()方法时,如果CatShout中有对象登记事件,则执行CatShout()!
  16. }
  17. }
  18. }
  19. Class Mouse
  20. {
  21. private string name;
  22. public Mouse(string name)
  23. {
  24. this.name=name;
  25. }
  26. public void Run()//逃跑的方法
  27. {
  28. Console.WriteLine("老猫来了,{0}快跑",name);
  29. }
  30. }
  31. Static void Main(string[] args)
  32. {
  33. Cat cat =new Cat("Tom");
  34. Mouse mouse1=new Mouse("John");
  35. Mouse mouse2=new Mouse("Jack");
  36. cat.CatShout+=new Cat.CatShoutEventHandler(mouse1.Run);//将Mouse的Run方法通过实例化委托Cat.CatShoutEventHandler登记到Cat的事件CatShout当中。
  37. cat.CatShout+=new Cat.CatShoutEventHandler(mouse2.Run);
  38. cat.Shout
  39. Console.Read();
  40. }

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

  

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


  1. public classCatShoutEventArgs:EventArgs//声明一个事件类,继承EventArgs
  2. {
  3. private string name;
  4. public string Name
  5. {
  6. get{return name;}
  7. set {name=value;}
  8. }
  9. }
  10. Class Cat//声明一个猫类
  11. {
  12. private string name;
  13. public Cat(string name)
  14. {
  15. this.name=name;
  16. }
  17. public delegate voidCatShoutEventHandler(object sender,CatShoutEventArgs args);//声明一个委托,此时有两个参数。注意和上边的不同
  18. public eventCatShoutEventHandler CatShout;//声明事件CatShout它的事件类型是上边声明的委托
  19. public void Shout()
  20. {
  21. Console.WriteLine("喵,我是{0}.",name);
  22. if (CatShout!=null)
  23. {
  24. CatShoutEventArgs e =new CatShoutEventArgs();
  25. e.Name=this.name;
  26. CatShout(this,e);//当事件触发时,通过所有登记过的对象,并将发送通知,以及需要的数据传递过去。
  27. }
  28. }
  29. }
  30. ClassMouse
  31. {
  32. private string name;
  33. public Mouse(string name)
  34. {
  35. this.name=name;
  36. }
  37. public void Run(object sender,CatShoutEventArgs args)//逃跑的方法
  38. {
  39. Console.WriteLine("老猫来{0}了,{1}快跑",args.Name,name);
  40. }
  41. }

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

 

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

  

 

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




相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载