zoukankan      html  css  js  c++  java
  • Golang 中的 面向对象: 方法, 类, 方法继承, 接口, 多态的简单描述与实现

    前言:

    Golang 相似与C语言, 基础语法与C基本一致,除了广受争议的 左花括号 必须与代码同行的问题, 别的基本差不多;

    学会了C, 基本上万变不离其宗, 现在的高级语言身上都能看到C的影子;


    Golang 中的 面向对象

    • 什么是面向对象?

      • 面向对象是一种编程思想, 并不是某一种开发语言独属;
    • 那什么是对象? 

      • 对象,指的是客体。所谓客体是指客观存在的对象实体和主观抽象的概念。(扩展阅读
      • 简单理解就是, 抽象一个拥有多重属性的客体, 将共有属性抽离出来为一个类, 以便实现定义多个客体的功能。
    • 面向对象有哪些特征?

      • 面向对象 通常包括三个特征 继承, 封装 和 多态; (简单理解)
        • 继承: 由子类继承父类的属性/数据/方法等;
        • 封装: 以最简单的函数形式将方法展示出去, 而不需要使用者知道方法内有什么、由什么实现, 类似黑盒子, 只需知道怎么用, 毋需知道为什么;例如, 电动车充电器, 只需知道插上两边的插头, 而不需要去理解如何变压限流;
          • 在Go语言中, 通常使用接口的方式完成封装;
        • 多态: 一种方法的多种表现形式, 可以看作是封装后的方法的集合, 根据使用场景, 自动分发到某具体方法中; 即一个同样的函数对于不同的对象可以具有不同的实现。
    • 为什么使用面向对象?

      • 面向对象是为了解决系统的可维护性,可扩展性,可重用性(详细资料)
      • 简单理解: 以对象方法代替过程完成实现, 方便以后修改及复用
    • Go语言中的面向对象如何实现? 以简单计算器为例                                                         

                                          

           

      • 抽象类型: 计算器, 可以抽象为 两个数字, 一个运算符和结果返回值;
        • 父类: 两个数字
        • 子类: 继承父类
        • 子类的方法: 做出计算并输出结果返回值
      • 定义方法, 对不同的运算符返回不同的运算结果
      • 封装: 定义接口, 将子类方法进行封装
      • 多态: 定义多态, 并将封装好的接口作为形参, 实现多态; 可以简单理解为 以接口作为形参的函数

    基于面向对象的, Go语言实现简单计算器

      1. 分析实现过程, 进行抽象化: 两个数字, 一个运算符, 一个结果返回值

    type BaseNum struct {
         num1 int
         num2 int
    } // BaseNum 即为父类型名称
    
    type Add struct {
        BaseNum
    } //加法子类, 定义加法子类的主要目的, 是为了定义对应子类的方法
    
    type Sub struct {
        BaseNum
    } //减法子类

      2. 定义子类方法, 实现运算及返回值

    func (a *Add)Opt()(value int) {
        return a.num1 + a.num2
    }//加法的方法实现
    
    func (s *Sub)Opt()(value int) {
        return s.num1 + s.num2
    }//减法的方法实现

        注意: 这里的方法名称是一样的, 这样才能使用接口进行归纳;

      3. 封装, 定义接口, 归纳子类方法为 接口

    type Opter interface { //接口定义
        Opt()int      //封装, 归纳子类方法, 注意此处需要加上返回值, 不然没有办法输出返回值(因为方法中使用了返回值)
    }

      4. 定义多态

    func MultiState(o *Opter)(value int) { //多态定义, 可以简单理解为以接口作为形参的函数, 方便学习
        value = o.Opt()
        return
    }

      5.主函数及调用

    func main(){
        var a Add = Add{BaseNum{2,3}}
       
     //使用Add对象方法
        value := a.Opt()
    
    //使用接口
        var i Opter
        i = &a
        value := i.Opt()
    
    //使用多态
        i = &a
        value := MultiState(i)
    //输出测试
        fmt.Println(value)
    }

    至此, 一个单纯的面向对象的 简单计算器完工;

    引发的问题思考:

      为什么比面向过程复杂的多?是否有意义?

      答案是肯定的, 面向对象所拥有的扩展性与维护性是面向过程无法比拟的;

        假设我需要在以上加减法计算器上加一个乘法或者除法, 那么我们需要做的工作仅仅是新建一个类和对应的方法就可以了, 其余的事情已经由接口定义下过了;


    点滴延伸:

      

    三 面对对象编程,分为几个步骤? 

    面向对象是一种思想,他让我们在分析和解决问题时,把思维和重点转向现实中的客体中来,然后通过UML工具理清这些客体之间的联系,最后用面向对象的语言实现这种客体以及客体之间的联系。它分为面向对象的分析(OOA),面向对象的设计(OOD),面向对象的编程实现(OOP)三个大的步骤。

    1、首先是分析需求,先不要思考怎么用程序实现它,先分析需求中稳定不变的客体都是些什么,这些客体之间的关系是什么。

    2、把第一步分析出来的需求,通过进一步扩充模型,变成可实现的、符合成本的、模块化的、低耦合高内聚的模型。

    3、使用面向对象的实现模型 

     摘自http://www.cnblogs.com/seesea125/archive/2012/04/20/2458940.html

    在上面的实例中, 我们提到了运算符, 并将运算符与输入值和输出值并列在一块, 这是为什么呢?

    因为我们可以通过实现模型来完成更加简洁的写法:

    下面实例使用工厂模式来解决计算器的问题:

    package main
    
    import "fmt"
    
    /*
        实例: 面向对象的计算器实现
    
            1.定义父类
            2.定义子类,以及子类的方法 运算实现
            3.定义接口, 归纳 子类方法
            4.定义空类, 定义空类的方法,即 工厂模式, 将 运算符 与 数值 分开处理, 以运算符来分发方法, 方便调用
            5.定义一个多态, 将接口归纳, 方便调用
            6.主函数, 初始化, 调用工厂模式, 进行验证
    
     */
    
     //父类
     type BaseNum struct {
         num1 int
         num2 int
     }
    
     //加法子类
     type Add struct {
         BaseNum
     }
    
     //减法子类
     type Sub struct {
         BaseNum
     }
    
     //子类方法
     func (a *Add)Opt() int {
         return a.num1 + a.num2
     }
    
     func (s *Sub)Opt() int {
         return s.num1 - s.num2
     }
    
     //定义接口, 即封装
    
     type Opter interface {
         Opt() int
     }
    
     //定义多态
     func MultiState(o Opter) int{
         value:=o.Opt()
         return value
     }
    
     //定义空类 以产生 工厂模式 的方法
     type Factory struct {
    
     }

    //⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️ func (f
    *Factory)FacMethod(a,b int,operator string) (value int){ var i Opter switch operator { case "+": var AddNum Add = Add{BaseNum{a,b}} i = &AddNum case "-": var SubNum Sub = Sub{BaseNum{a,b}} i = &SubNum } //接口实现 : value = i.Opt() value = MultiState(i) //多态实现 return } //⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️⬆️ func main() { var a Factory value := a.FacMethod(20,3,"-") fmt.Println(value) }

    上面的代码中, 我们看到 Factory 部分, 先定义了一个空类以完成对平级方法的调用, 而后定义了一个方法;

    此方法代替了主函数中每次调用前的初始化操作, 而且, 在主函数中, 也完全不需要知道其中的实现过程;


    基于本实例的简单分析, 及对Golang面向对象简单图示:


    小结:

      至此, 关于Golang中的面向对象有了一个基础的认识, 但是对于面向对象本身还是需要多加巩固和练习; 


    学习是为了写代码, 不多写代码怎么学习;

  • 相关阅读:
    【DSP开发】回马枪要你命 德州仪器发布最强ARM芯片Keystone II
    【DSP开发】回马枪要你命 德州仪器发布最强ARM芯片Keystone II
    【DSP开发】【VS开发】YUV与RGB格式转换
    【DSP开发】【VS开发】YUV与RGB格式转换
    【DSP开发】【图像处理】Gray与YUV之间的转换关系
    【DSP开发】【图像处理】Gray与YUV之间的转换关系
    【DSP开发】HyperLink 编程和性能考量
    【DSP开发】HyperLink 编程和性能考量
    【DSP开发】C6000非多核非KeyStone系列DSP中断系统
    【DSP开发】C6000非多核非KeyStone系列DSP中断系统
  • 原文地址:https://www.cnblogs.com/gettolive/p/9327323.html
Copyright © 2011-2022 走看看