分享

C# 面向对象编程(OOP)

 建筑小不懂 2022-07-13 发布于广东

    这节讲一下,什么是面向对象(Object Oriented Programming)。说面向对象之前,我们不得不提的是面向过程(Process Oriented Programming),C语言就是面向过程的语言,这两者的区别在哪呢?我们可以设想一个情景——厨房做菜:

    以面向过程的形式解释来说,第一步:准备材料,第二步:起火,第三步:炒菜,第四步:上菜;面向过程就是编写一个个函数,每个函数执行一部分操作,最后根据这一套函数,执行下来完成一个整体需求为目的。

    那面向对象呢,我们同样的解释做菜说,第一步:要有厨师,灶台,要有服务生,第二步:厨师准备材料,第三步:灶台起火,第四步:厨师炒菜,第五步:服务生上菜。面向对象的编程方式,将原本各个独立的函数,用它所属的对象规整了起来,并封装成方法(面向对象中的"函数"有个新的称呼叫方法Method)。虽然实际上代码量会变多,但是这种编程思维是合情合理的,符合实际的,让人更容易理解,因为每个对象的职责是明确的,从而后期维护会变得更方便。

    下面在代码层面,演示一下面向对象和面向过程的区别:

    过程化:

  1. #include "stdio.h"
  2. void Prepare(){
  3. printf("准备食材。\n");
  4. }
  5. void Fire(){
  6. printf("起火\n");
  7. }
  8. void Cooking(){
  9. printf("炒菜,\n");
  10. printf("炒完了\n");
  11. }
  12. void Serve(){
  13. printf("请享用。");
  14. }
  15. main(){
  16. Prepare();
  17. Fire();
  18. Cooking();
  19. Serve();
  20. }

975a166199a4d8ef3e94c7a79185d086.png

    对象化:

  1. //创建三个对象
  2. //厨师
  3. class Cook
  4. {
  5.     //准备食材的方法
  6. public void Prepare()
  7. {
  8. Console.WriteLine("厨师准备食材。");
  9. }
  10.     //做饭的方法
  11. public void Cooking()
  12. {
  13. Console.WriteLine("厨师正在做饭...");
  14. Console.WriteLine("厨师做好了。");
  15. }
  16. }
  17. //灶台工具类
  18. static class CookingBench
  19. {
  20.     //静态工具方法:起火
  21. public static void Fire()
  22. {
  23. Console.WriteLine("灶台生火。");
  24. }
  25. }
  26. //服务员
  27. class Waiter
  28. {
  29.     //上菜方法
  30. public void Serve()
  31. {
  32. Console.WriteLine("请享用。");
  33. }
  34. }

    在主方法中调用:

  1. Cook cook=new Cook();
  2. Waiter waiter=new Waiter();
  3. cook.Prepare();
  4. CookingBench.Fire();
  5. cook.Cooking();
  6. waiter.Serve();

b05a78f88234f36480423da96b07410a.png

    面向对象有三大特征:封装,继承,多态。下面详细讲一下:

    封装:

   每个人都有自己的秘密,在面向对象的代码中也是如此,对象中,有可以被外界查看的,也有不对外界查看的,这种将一些成员隐藏起来的思想就是封装,实现封装,需要先了解一下四个访问修饰符:public, private, protect, internal

    访问修饰符可以修饰类,属性,方法,使用修饰符修饰类或属性、方法,具有不同的访问级别。声明时访问修饰符要写在最前:

  1. public class publicClass{}//声明一个类
  2. private bool isPublic;//声明一个属性

    public:公共的,这个访问级别最低。

    private:私有的,故名思义,这个访问级别最高,只能在声明的作用域内访问。
    protect:受保护的,只能在继承链上被访问,说白了只有继承了一个类,才能访问这个类中protect修饰的成员。

    internal:内部的,只能在同一个程序集中访问。可以狭义的理解为同一个命名空间下可以访问。

    还有一个组合拳:protect internal,这就是既要满足同一个程序集,又得是继承的关系才能访问。

    通过这几个关键字,我们就可以实现封装。开发的时候只需要明确写的类或者属性,方法等分配什么样的访问权限即可。

    继承:

    继承的概念,也很容易理解,它就好比现实生活中,孩子继承父母的家产,那么父母的东西就成了孩子的,在C#中,类和类之间实现继承是通过":"来实现的。

  1. public class Father{}
  2. public class Chlid:Father{}//Child类继承了Father

    注意,C#是单继承的语言,也就是说一个类只能继承一个父类。

    子类可以继承父类中非private的属性或方法,如果private的属性或方法能访问,也就不会有protect这个关键字存在。通过继承,我们可以将子类共有的重复代码抽离到父类中,这样所有的子类就不必声明这些成员,就减少了很多代码量。在C#的继承结构中,object类是所有类的父类,任何一个类都是默认继承object。object类为我们提供了一些类中最最基础的成员,如我们常用的tostring()方法。

    面向对象中有个原则叫开闭原则,这个原则规定对修改封闭,对扩展开放,也就是说,当写了一个类并使用了一段时间后,因为项目升级或者其它原因,我们需要修改这个类(添加一些新东西),这时,根据开闭原则,我们就不能直接修改,而是要再写一个类,去继承它,在子类中添加新的业务逻辑,这也是继承的一个用途。

   继承中,还有一个概念叫做方法的重写,就是说,子类中有一个方法和继承父类的方法名一样,这样子类方法就把父类方法给覆盖了,这个过程就是重写。这个概念在具体介绍类和方法的小节中会详细展开。

    多态:

    多态依赖继承,有继承才能实现多态。同一个类,有不同的形态就是多态。比如狗这种动物,有不同的形态:哈士奇,田园犬,柯基等。在代码中的体现就是父类可以接收子类为其赋值。还是拿上面的例子来说,以下代码就是多态例子:

Father f=new Chlid();

    多态性的依据是里氏转换原则:子类继承父类,那么,原来适用于父类的场景,一定适用于子类,因为子类继承了父类的所有显式功能,父类能做的,子类也能做。这一原则就是定义这个理论的存在,子类可以直接替代父类,将父类全部转换为子类,程序的行为没有区别。

    多态性也面向对象编程中很重要的基石,我们一般在编程中尽可能地使用接口,面向抽象,降低耦合,因为多态性,我们才能通过接口或一些抽象的数据结构来实现实例的操作。

    最后通过一个例子演示一下多态(涉及到类和方法的一些知识会在下节类和方法中详解):

  1. public class Dog
  2. {
  3. public string name { get; set; }
  4.     public Dog(string name)
  5. {
  6. this.name = name;
  7. }
  8. public void introduce()
  9. {
  10. Console.WriteLine("这是一只:" + name);
  11. }
  12. }
  13. public class Husky : Dog
  14. {
  15.     //调用父类的构造方法,为name赋值
  16.     public Husky():base("Husky"){}
  17. }
  18. public class Koji : Dog
  19. {
  20. public Koji() : base("Koji"){}
  21. }
  22. class DogStore
  23. {
  24. public Dog dog { get; set; }
  25. public DogStore(Dog dog)
  26. {
  27. this.dog = dog;
  28. }
  29. public void wantBuy()
  30. {
  31. Console.WriteLine("Do u want this "+dog.name+"?");
  32. }
  33. }

    以上代码中有一个共同的Dog类,分别有两个类哈士奇,柯基继承了它。还有一个宠物狗商店,需要Dog这个属性。

    下面看一下主方法中的代码:

  1. DogStore dogStore=new DogStore(new Husky());
  2. dogStore.wantBuy();
  3. dogStore=new DogStore(new Koji());
  4. dogStore.wantBuy();

0395a8ce130f7138b8e90957b8f09c2e.png

  我们通过父类,接收更加具体的子类,这就是多态性很好的体现,这也是很优雅高效的编程方式。

    本节到此结束...

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多