zoukankan      html  css  js  c++  java
  • 面向对象的演进过程

    计算机高级语言可以分为解释型语言(interpreting)和编译型语言(compiling),具体可以参考漫谈计算机编程语言。除了这种分类方式,其实还可以分为面向对象和面向过程,本期我们就来聊聊面向对象的演进过程。

    远古时期

    我们知道 程序 = 数据结构 + 算法,其中数据结构包括数组、栈、队列、链表、树以及图等,而算法是包含顺序、循环、分支三种逻辑结构的代码,为了使算法能够到处复用,通常将算法封装在函数中。

    为了加深大家的理解,我来举个具体的例子--栈,它的定义如下:

    typedef struct Stack{
      int elements[10];
      int top;
    }Stack;
    

    它的算法即功能,包含入栈、出栈、显示栈顶。

    void push(Stack *s,int data);
    int pop(Stack *s);
    int top(Stack *s);
    

    现在,我们就可以使用push、pup、top来维护Stack,同时,我们可以直接持有Stack,操作Stack内部的elementstop。这样一来可能导致Stack内部数据不好维护。

    Object时期

    针对这个问题,我们的先辈们想出了一种方法:将数据结构和算法结合起来,形成Object,将数据结构部分变成Object的属性,算法变成Object的行为,并且只能通过访问Object的行为来操作Object的属性,我们不能直接访问Object的属性。

    现在我们就可以使用Object创建对象,例如:

    object1 {
      int elements[10];
      int top=6;
      void push(int data);
      int pop();
      int top();
    }
    
    object2 {
      int elements[10];
      int top=9;
      void push(int data);
      int pop();
      int top();
    }
    

    我们发现object1objec2中有很多重复的代码即push()、pop()和top(),我们需要提取这些复用的代码,将它们放到一个地方,即Class。object1object2的方法部分只要指向Class就可以。

    由于函数定义只有一份存在Class文件中,但是对应的Object却有很多份。那么,我们在操作pop、push等函数时是如何确定是哪个Object的?这里不得不称赞我们的先辈,他们在每次调用函数的时候,都将调用者自己作为一个隐藏的参数传递过去,其中隐藏的参数用this表示。

    继承时期

    我们通过Class解决各个Object中的重复代码问题,同理,我们也在Class中发现了代码重复问题。针对这个问题,我们又该如何破解呢?使用继承,也就是说将那些共性的、重复的代码放到父类中去,这样子类就可以直接使用而不用重新写一遍。其中,继承可以分为单继承和多继承。单继承就是使子类拥有一个父类的特征,而多继承指的是子类同时拥有多个父类的特征。虽然多继承可以最大限度的减少重复代码,但是当多个父类中有相同的方法名时,子类就会产生歧义,也就是说子类不知道真正继承哪个父类。因此,Java语言就采用了单继承。一个父类可以有多个子类,而在子类里可以重写父类的方法,这样每个子类里重写的代码是不一样的,这就是多态。为加深大家对这句话的理解,我就以购物车为例。它的代码如下:

    public abstract class Product{
      public String getName(){
        return "Product";
      }
      public abstract float getPrice();
    }
    class TV extends Product{
      public String getName(){
        return "TV";
      }
      public  float getPrice(){
        return 6000.0f;
      };
    }
    class Food extends Product{
      public String getName(){
        return "Food";
      }
      public  float getPrice(){
        return 100.0f;
      };
    }
    

    TV 和 Food这两个类继承于Product,购物车类可以这么写:

    public class ShopCart{
      List<Product> items = new ArrayList<Product>();
      public void addProduct(Product p){
        float total = 0.0f;
        for(Product p:items){
          total += p.getPrice();
        }
      }
    }
    

    我们发现ShopCart类中持有的是一个抽象概念Product,而不是它的具体实现,即它的两个子类。这符合面向对象设计原则中的针对接口编程,而不是实现编程。


    image

    欢迎关注微信公众号:木可大大,所有文章都将同步在公众号上。

  • 相关阅读:
    解决:Could not resolve archetype org.apache.maven.archetypes
    Spring MVC配置MyBatis输出SQL
    Spring集成MyBatis 通用Mapper以及 pagehelper分页插件
    关于SpringMVC或Struts2接受参数接收不到的原因
    配置quartz启动时就执行一次
    ajaxFileUpload进行文件上传时,总是进入error
    spring mvc注入配置文件里的属性
    java中将一个文件夹下所有的文件压缩成一个文件
    flume failed to start agent because dependencies were not found in classpath
    ubuntu不能安装pip unable to install pip in unbuntu
  • 原文地址:https://www.cnblogs.com/neal-ke/p/8917596.html
Copyright © 2011-2022 走看看