精华内容
下载资源
问答
  • 简述面向函数编程和面向对象编程的区别? 什么时候使用面向函数编程?什么时候使用面向对象编程? 函数式编程,顾名思义,这种编程是以函数思维做为核心,在这种思维的角度去思考问题。 这种编程最重要的基础是λ...

    简述面向函数编程和面向对象编程的区别?
    什么时候使用面向函数编程?什么时候使用面向对象编程?

    函数式编程,顾名思义,这种编程是以函数思维做为核心,在这种思维的角度去思考问题。
    这种编程最重要的基础是λ演算,接受函数当作输入和输出。
    
    面向对象编程,这种编程是把问题看作由对象的属性与对象所进行的行为组成。基于对象的概念,
    以类作为对象的模板,把类和继承作为构造机制,以对象为中心,来思考并解决问题。
    

    优点:

    函数式编程:
    支持闭包和高阶函数,闭包是一种可以起函数的作用并可以如对象般操作的对象;
    而高阶函数是可以以另一个函数作为输入值来进行编程。支持惰性计算,这就可以在求值需要表达式的值得时候进行计算
    ,而不是固定在变量时计算。还有就是可以用递归作为控制流程。函数式编程所编程出来的代码相对而言少很多,而且更加简洁明了。
     面向对象编程:
    面向对象有三个主要特征,分别是封装性、继承性和多态性。类的说明展现了封装性,类作为对象的模板,
    含有私有数据和公有数据,封装性能使数据更加安全依赖的就是类的特性,使得用户只能看到对象的外在特性,
    不能看到对象的内在属性,用户只能访问公有数据不能直接访问到私有数据。
    类的派生功能展现了继承性,继承性是子类共享父类的机制,但是由于封装性,继承性也只限于公有数据的继承(还有保护数据的继承),
    子类在继承的同时还可以进行派生。而多态性是指对象根据接收的信息作出的行为的多态,不同对象接收同一信息会形成多种行为。
    

    缺点

    函数式编程:所有的数据都是不可以改变的,严重占据运行资源,导致运行速度也不够快。
    
    面向对象编程:为了编写可以重用的代码导致许多无用代码的产生,并且许多人为了面向对象而面向对象导致代码给后期维护带来很多麻烦。
    
    展开全文
  • 主要介绍了Python面向对象程序设计构造函数和析构函数用法,结合具体实例形式分析了Python面向对象程序设计中构造函数与析构函数的概念、原理、功能及相关使用技巧,需要的朋友可以参考下
  • 主要介绍了JS面向对象编程对象构造函数,结合实例形式详细分析了JS面向对象编程对象构造函数具体概念、原理、使用方法及操作注意事项,需要的朋友可以参考下
  • 函数 面向对象 实验报告
  • JS面向对象和构造函数

    千次阅读 2019-06-24 21:31:14
    面向对象编程 需要我们掌握 对象 ...整个JS 就是基于面向对象设计开发出来的语言,我们学习实战的时候也要按照面向对象的思想去体会理解。 JS中的内置类 基于基类我们可以创建很多自己的类(自定义的类)。...

    面向对象编程 需要我们掌握 对象 类 实例
    对象:万物皆对象
    类:对象的具体细分 (按照功能特点进行分类:大类丶小类)
    实例:类中具体的一个事物 (拿出类别中具体一个实例进行研究,那么当前类别下的其它例也具备这些特点和特征)

    整个JS 就是基于面向对象设计和开发出来的语言,我们学习和实战的时候也要按照面向对象的思想去体会和理解。
    JS中的内置类

    基于基类我们可以创建很多自己的类(自定义的类)。
    构造函数constructor

     /*function Fn() {
    
        }
        fn(); ==>普通函数执行
        var f = new Fn(); //Fn是类  f是类的实例
        var f2 = new Fn()*/;//f2也是Fn 的实例  f2和f 是独立分开的,互不影响。
    
        var obj1 = {};//obj1是Object的一个实例
        var obj2 = {};//obj2是Object的一个实例
    */

    这里需要注意:

    1.在普通函数执行的基础上"new xxx()" 这样就不是普通函数执行了,而是构造函数执行,当前的函数名称之为"类名",接收的返回结果是当前类的一个实例

    2.自己创建的类名最好第一个单词首字母大写

    JS中创建值有两种方式

    1.字面量表达式

       var obj = {};// 字面量方式
       var obj = new Object();// 构造函数模式
        //无论哪一种方式创造出来的都是Object类的实例,而实例之间是独立分开的,所以 var xxx={}; 这种模式就是JS中的单利模式。
         var num1 = 12;
        var num2 = new Number(12);
        //基本数据类型基于两种 不同模式创建出来的值是不一样的
        //基于字面量方式创建出来的值是 基本类型值
        //基于构造函数创建创建出来的值是引用类型
        console.log(typeof num1);//"number"
        console.log(typeof  num2);//"Object"
      //共同点 num1 num2 是数字类的实例 它只是JS表达数字的方式之一,都可以使用数字类提供的属性和方法

    2.构造函数模式

      function Fn() {
             }
         Fn();//=>普通函数执行  形成一个私有的作用域 形参赋值 变量提升 代码执行  栈内存问题
        //构造函数执行
        function Fn(name,age) {
            var n = 10;
            this.name = name;
            this.age = age + n;
        }
        var f1=  new Fn('xxx', 20);
        var f3 = new Fn('aaa', 30);
        console.log(f1 === f3);//false 两个不同的实例
        console.log(f1.age);// 30
        console.log(f3.name);// 'aaa'
        console.log("name"in f1);// 返回true。 name & age在两个不同实例中都有存储,但都是每个实例自己私有的属性
        console.log(f1.n);// undefined  只有this.xxx=xxx才和实例有关系,n是私有作用域中的一个私有变量而已(this是当前类的实例)*/
        /*

    下面是关于构造函数运行的机制

    一些细节问题

       构造函数 执行, 不写return 浏览器 会默认返回创建的实例,但是如果写了return
          1.return 一个基本值,返回的结果依然是类的实例,没有受到影响
          2.如果返回的是引用值,则会把默认返回的实例覆盖,此时结果就不在是当前类的实例
         */
    
        function Fn () {
            var n=10;
            this.m=n;
            return {name:"jojo"}
        }
        var f=new Fn();
        console.log(f);// {name: "jojo"}name: "jojo"
         function Fn () {
          var n=10;
          this.m=n;
          return
          console.log(1);//=> 这样return 是结束代码执行的作用,并且不会覆盖返回的实例
      }
    var f=new Fn();//==> new Fn;在构造函数执行时,如果Fn不需要传递实参,我们可以省略小括号,意思还是创建实例(和加小括号没有区别)
      console.log(f);
        // =>instanceof: 检测某一个实例是否隶属于这个类
      console.log(f instanceof Fn);// true
      console.log(f instanceof Object);// true (万物皆对象, 所有的对象,包含创建的实例都是Object的实例)
    //in 检测当前对象是否存在某个属性 (不管当前这个属性 是对象的私有属性还是公有属性  只要有结果都是true)
    
    //hasOwnProperty:检测当前属性是否为对象的私有属性(不仅要有这个属性,而且必须还要是私有才可以)

     

    展开全文
  • 面向对象编程,这种编程是把问题看作由对象的属性与对象所进行的行为组成。基于对象的概念,以类作为对象的模板,把类继承作为构造机制,以对象为中心,来思考并解决问题。 优点 函数式编程:支持闭包高阶...

    是什么
    在叙述区别和优劣之前,简单介绍一下两者。
    函数式编程,顾名思义,这种编程是以函数思维做为核心,在这种思维的角度去思考问题。这种编程最重要的基础是λ演算,接受函数当作输入和输出。
    面向对象编程,这种编程是把问题看作由对象的属性与对象所进行的行为组成。基于对象的概念,以类作为对象的模板,把类和继承作为构造机制,以对象为中心,来思考并解决问题。

    优点
    函数式编程:支持闭包和高阶函数,闭包是一种可以起函数的作用并可以如对象般操作的对象;而高阶函数是可以以另一个函数作为输入值来进行编程。支持惰性计算,这就可以在求值需要表达式的值得时候进行计算,而不是固定在变量时计算。还有就是可以用递归作为控制流程。函数式编程所编程出来的代码相对而言少很多,而且更加简洁明了。
    面向对象编程:面向对象有三个主要特征,分别是封装性、继承性和多态性。类的说明展现了封装性,类作为对象的模板,含有私有数据和公有数据,封装性能使数据更加安全依赖的就是类的特性,使得用户只能看到对象的外在特性
    不能看到对象的内在属性,用户只能访问公有数据不能直接访问到私有数据。类的派生功能展现了继承性,继承性是子类共享父类的机制,但是由于封装性,继承性也只限于公有数据的继承(还有保护数据的继承),子类在继承的同时还可以进行派生。而多态性是指对象根据接收的信息作出的行为的多态,不同对象接收同一信息会形成多种行为。

    缺点
    函数式编程:所有的数据都是不可以改变的,严重占据运行资源,导致运行速度也不够快。
    面向对象编程:为了编写可以重用的代码导致许多无用代码的产生,并且许多人为了面向对象而面向对象导致代码给后期维护带来很多麻烦。

    展开全文
  • 函数式编程 (Functional Programming) 面向对象编程 (Object Oriented Programming) 是两个主流的编程范式,他们有各自独特的闪光点,比如函数式编程的数据不可变、惰性求值,面向对象编程的继承、多态等。...

    函数式编程 (Functional Programming) 和 面向对象编程 (Object Oriented Programming) 是两个主流的编程范式,他们有各自独特的闪光点,比如函数式编程的数据不可变惰性求值,面向对象编程的继承多态等。这些语言特性上的区别,可以参考之前的文章,这篇文章主要从实现相同功能的角度,来对比这两种编程范式,他们在实现上的逻辑是截然相反的

    初步实现

    在函数式编程中,代码逻辑通常是按照要做什么。而在面向对象编程中,通常是把代码逻辑抽象成 class,然后给这些 class 一些操作。这么说起来很抽象,用下面这个例子来详细说明。

    假设我们要用 函数式编程 和 面向对象编程 来分别实现下面这些功能:

    evaltoStringhasZero
    Int
    Add
    Negate

    表格左列 Int, Add, Negate 是三个变式 (Variant),eval, toString, hasZero 是三种操作,这里要做的是填满这个表格,分别实现三个变式的三种操作。

    函数式编程实现

    这里用 ML 来做函数式编程的实现,即使没用过这门语言,应该也能读懂大概意思。

    datatype exp =
        Int    of int
      | Negate of exp
      | Add    of exp * exp
    
    exception BadResult of string
    
    fun add_values (v1,v2) =
        case (v1,v2) of
        		(Int i, Int j) => Int (i+j)
          | _ => raise BadResult "non-values passed to add_values"
    
    fun eval e =
        case e of
        		Int _       => e
          | Negate e1   => (case eval e1 of
                              Int i => Int (~i)
          | _ => raise BadResult "non-int in negation")
          | Add(e1,e2)  => add_values (eval e1, eval e2)
    
    fun toString e =
        case e of
            Int i 			=> Int.toString i
          | Negate e1   => "-(" ^ (toString e1) ^ ")"
          | Add(e1,e2)  => "("  ^ (toString e1) ^ " + " ^ (toString e2) ^ ")"
    
    fun hasZero e =
        case e of
          	Int i 			=> i=0
          | Negate e1   => hasZero e1
          | Add(e1,e2)  => (hasZero e1) orelse (hasZero e2)
    

    在函数式编程中,先定义了一个数据类型 (datatype) 来表示 Int, Negate, Add,这样定义的目的是什么呢?举个表达式的例子:

    • Int 代表一个 int 的数据,比如 Int(2)
    • Negate 代表 Int 的负数,比如 Negate(Int(2)))
    • Add 代表两个 Int 相加,比如 Add((Int(2), Int(3))

    然后再分别实现三个操作 eval, toString, hasZero:

    • eval 是给一个表达式求值,比如给 Negate 求值,eval(Negate(Int(2))) = Int(-2) ,给 Add 求值,eval(Add(Int(2), Int(3))) = Int(5)
    • toString 是把这个表达式输出成字符串,比如 toString(Add(Int(2), Int(3))) = "2 + 3"
    • hasZero 是判断表达式有没有 0。

    再看刚刚这句话函数式编程的代码逻辑通常是按照要做什么,这里的主体是三个操作,eval, toString 和 hasZero,所以三个分别是一个函数,在函数里去实现三种变式怎么操作。

    可以说,函数式编程式纵向的填满了上面的表格。

    面向对象编程

    这里用 Ruby 来实现。

    class Exp
    end
    
    class Value < Exp
    end
    
    class Int < Value
      attr_reader :i
      def initialize i
        @i = i
      end
      def eval # no argument because no environment
        self
      end
      def toString
        @i.to_s
      end
      def hasZero
        i==0
      end
    end
    
    class Negate < Exp
      attr_reader :e
      def initialize e
        @e = e
      end
      def eval
        Int.new(-e.eval.i) # error if e.eval has no i method
      end
      def toString
        "-(" + e.toString + ")"
      end
      def hasZero
        e.hasZero
      end
    end
    
    class Add < Exp
      attr_reader :e1, :e2
      def initialize(e1,e2)
        @e1 = e1
        @e2 = e2
      end
      def eval
        Int.new(e1.eval.i + e2.eval.i) # error if e1.eval or e2.eval has no i method
      end
      def toString
        "(" + e1.toString + " + " + e2.toString + ")"
      end
      def hasZero
        e1.hasZero || e2.hasZero
      end
    end
    

    < 在 Ruby 里是继承的意思,class Int < Value 表示 Int 继承了 Value,Int 是 Value 的 Subclass。

    可以看到面向对象编程组织代码的方式和之前的完全不一样。这里把 Int, Negate, Add 抽象成了三个 class,然后分别给每个 class 加上 eval, toString, hasZero 三个方法。这也是刚刚那句话的说法 面向对象编程把代码逻辑抽象成 class,然后给这些 class 一些操作,这里的主体是 Int, Negate, Add 这三个 class。

    可以说,面向对象编程是横向的填满了上的表格。

    通过这个对比,可以知道 函数式编程 和 面向对象编程 是两种相反的思维模式和实现方式。这两种方式对代码的扩展性有什么影响呢?

    扩展实现

    evaltoStringhasZeroabsolute
    Int
    Negate
    Add
    Multi

    在上面那个例子的基础上,我们再加一行一列,增加 Multi 这个变式,表示乘法,增加 absolute 这个操作,作用是求绝对值。这会怎么影响我们的代码呢?

    函数式编程

    在函数式编程中,要增加一个操作 absolute 很简单,只要添加一个新的函数,不用修改之前的代码。但是要增加 Multi 比较麻烦,要修改之前的所有函数。

    面向对象编程

    和函数式编程相反的,在这里增加一个 Multi 简单,只要添加一个新的 class,但是增加 absolute 这个操作就要在之前的每一个 class 做更改。

    选择用 函数式编程 还是 面向对象编程 的一个考量因素是以后将会如何扩展代码,对之前代码的更改越少,出错的概率越小。

    Binary Methods

    前面的对比,操作都是在一个数据类型上进行的,这里进行最后一个对比,一个函数对多个数据类型进行操作时,函数式和面向对象分别怎么实现。

    IntStringRational
    Int
    String
    Rational

    这里要实现的是一个 add_values(x, y) 的操作,把两个数据相加,但是 x, y 可能是不同的类型的。

    函数式编程

    函数式编程的实现相对简单:

    datatype exp =
        Int    of int
      | String of string
      | Rational of real
    
    fun add_values (v1,v2) =
        case (v1,v2) of
    				(Int i,  Int j)         => Int (i+j)
          | (Int i,  String s)      => String(Int.toString i ^ s)
          | (Int i,  Rational(j,k)) => Rational(i*k+j,k)
          | (String s,  Int i)      => String(s ^ Int.toString i) (* not commutative *)
          | (String s1, String s2)  => String(s1 ^ s2)
          | (String s,  Rational(i,j)) => String(s ^ Int.toString i ^ "/" ^ Int.toString j)
          | (Rational _, Int _)        => add_values(v2,v1)
          | (Rational(i,j), String s)  => String(Int.toString i ^ "/" ^ Int.toString j ^ s)
          | (Rational(a,b), Rational(c,d)) => Rational(a*d+b*c,b*d)
          | _ => raise BadResult "non-values passed to add_values"
    
    

    这里的操作是 add_values,所以只要把所有可能的数据类型(总共9种)都列出来,就可以了。

    面向对象编程:二次分派

    按照上面面向对象编程的例子,我们可以这么做:

    class Int < Value
    	...
      def add_values v
        if v.is_a? Int
          i + v.i
        elsif v.is_a? MyString
          i.to_s + v.i
        else
          ...
        end
      end
    end
    
    class MyString < Value
      ...
    end
    

    在 add_values 这个方法里面去做判断,看传入参数的类型,去做相应的操作。这种做法不是那么的 面向对象,可以有另外一种写法:

    class Int < Value
    	...
      # double-dispatch for adding values
      def add_values v # first dispatch
        v.addInt self
      end
      def addInt v # second dispatch: other is Int
        Int.new(v.i + i)
      end
      def addString v # second dispatch: other is MyString (notice order flipped)
        MyString.new(v.s + i.to_s)
      end
      def addRational v # second dispatch: other is MyRational
        MyRational.new(v.i+v.j*i,v.j)
      end
    end
    
    class MyString < Value
      ...
      # double-dispatch for adding values
      def add_values v # first dispatch
        v.addString self
      end
      def addInt v # second dispatch: other is Int (notice order is flipped)
        MyString.new(v.i.to_s + s)
      end
      def addString v # second dispatch: other is MyString (notice order flipped)
        MyString.new(v.s + s)
      end
      def addRational v # second dispatch: other is MyRational (notice order flipped)
        MyString.new(v.i.to_s + "/" + v.j.to_s + s)
      end
    end
    ...
    

    这里涉及到了一个概念 二次分派 (Double Dispatch),在一次方法的调用过程中,做了两次 动态分派 (Dynamic Dispatch) 。用例子来说明

    i = Int.new(1)
    s = MyString.new("string")
    i.add_values(s)
    

    i.add_values(s)在调用这个方法时,实现了一次 dispatch,到 add_values 这个方法里后,做的其实是 s.addInt i,也就是去调用了 MyString 里的 addInt 这个方法,这是第二次 dispatch,所以叫做 double dispatch。

    总结

    函数式编程 和 面向对象编程 对比下来,我们并不能说哪一种模式更好。但是可以看出它们在思维上是截然不同的。函数式编程中侧重要做什么,面向对象编程侧重对象的抽象化,在有些编程语言里,比如 Java,是都可以实现的,但是要用哪种还要根据需求具体考虑。如果要了解更多 函数式编程 和 面向对象编程 的基础概念的话,可以看看之前的这三篇文章。

    推荐阅读:
    编程语言的一些基础概念(一):静态函数式编程
    编程语言的一些基础概念(二):动态函数式编程
    编程语言的一些基础概念(三):面向对象

    展开全文
  • 面向对象与面向过程的本质的区别

    万次阅读 多人点赞 2018-01-10 20:19:04
    如果你很想搞明白面向对象是什么,面向过程是什么,或者说二者之间的区别是什么,那么就花费一点时间来研读一下这篇博客,你一定会有很大的收获的! 一、面向对象与面向过程的区别 面向过程就是分析出解决问题所...
  • 函数在面对对象的编程中又被叫做方法,会受到作用域的制约,Lua中具有类等面向对象的特性,接下来我们就来看一下Lua中函数面向对象编程的基础知识整理
  • 回调函数面向对象设计

    千次阅读 2017-01-04 16:11:52
    面向对象的回调函数过程语言c的设计方法,在面向对象的语言c++中都有对应的实现方法。而回调函数面向对象的设计方法一直困扰着我,没有找到一种合适的面向对象的c++的方法来替代c的方法。今天在学习设计模式时,...
  • 面向对象编程和函数式编程的理解

    千次阅读 2018-09-07 14:08:52
    面向对象编程和函数式编程的理解 面向对象编程的优点 面向对象程序设计可以看作一种在程序中包含各种独立而又互相调用的对象的思想,这与传统的思想刚好相反。传统的程序设计主张将程序看作一系列函数的集合,...
  • 面向对象中的构造函数和析构函数

    千次阅读 2016-06-17 17:22:05
    面向对象包含“类”“对象”。 “类”分为——》1.抽象:包括【1.外观--》属性 2.做的事--》行为】  |  |  2.实例化 构造函数: 构造函数方法又称为构造函数,是对象被创建时自动调用的方法,用来完成...
  • Python函数面向对象及模块练习

    千次阅读 2019-05-23 11:57:30
    Python函数面向对象及模块练习 1、闭包需要满足的三个条件是什么?按照上面三个条件创建一个用于计算平方根的闭包函数(参照上课所讲解实例)。 闭包需要满足如下三个条件: ①存在于两个嵌套关系的函数中,...
  • 1.基本概念 构造函数:一个类的构造函数的名字与类名是相同的。与一般函数类似,构造函数可以被重载。...当创建一个对象时,其构造函数被调用,而对象销毁时,析构函数被调用。如果程序员没有显式
  • 如果你粗略浏览Scala的网站,你会觉得Scala是一种纯粹的面向对象编程语言,而又无缝地结合了命令式和函数式的编程风格。Christopher Diggins认为: 不太久之前编程语言还可以毫无疑义地归类成“命令式”或者“函数...
  • 函数模板_面向对象程序设计 基本概念 函数模板 类模板
  • 函数式编程vs面向对象编程

    千次阅读 2017-02-17 23:48:58
    什么是面向对象,其实我也不是很懂,我以前一直认为面向对象就是继承,而继承就是虚函数,有时候在思考,真的是这样子的吗?错了,不管虚函数的机制是为了继承多态而服务,而继承多态确实为了OO的思想而服务,...
  • 面向对象程序设计中的函数部分,主要写的是函数部分,有c里面的内容。
  • 面向对象:对函数进行分类封装,让开发“更快更好更强...” 面向过程编程虽然容易学习上手,但其往往需要一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能...
  • PHP面向对象的mysql数据库函数封装

    千次阅读 2015-09-08 22:19:32
    面向对象的方法会增强开发效率。下面给出面向对象编程的mysql数据库操作相关代码:   class mysql{ private $host; private $root; private $pwd; private $database; private $c
  • 第9章 从面向对象函数式编程 假如本书的写作时间倒退回十年前,书名可能会变成JavaScript面向对象编程思想。自上世纪90年代兴起的面向对象编程思想随Java的繁荣达于顶点,在JavaScript从一门只被用来编写零星的...
  • 面向对象 继承 闭包
  • 函数式编程与面向对象编程的优劣

    千次阅读 2018-10-28 20:44:44
    工程中不在只是面向对象编程,更多的人尝试着开始使用函数式编程来解决软件工程中遇到的问题。 什么是函数式编程?在维基百科中给出了详细的定义,函数式编程(英语:functional programming)或称函数程序设计,又...
  • 面向对象和面向过程

    万次阅读 多人点赞 2015-09-07 19:50:30
    从进入软工就开始了面向对象的程序设计,那么面向对象和面向过程到底有什么区别呢?结构化程序设计面向过程是一个概念吗? 【概念】 什么是对象? 对象是人们要进行研究的任何事物,从最简单的整数到复杂的...
  • 面向对象程序设计03多态性函数.ppt
  • 函数式编程与面向对象编程的比较

    千次阅读 2017-04-13 21:38:18
    工程中不在只是面向对象编程,更多的人尝试着开始使用函数式编程来解决软件工程中遇到的问题。  什么是函数式编程?在维基百科中给出了详细的定义,函数式编程(英语:functional programming)或称函数程序设计...
  • 一、面向对象的概念 1、理解面向对象 ... (2)面向对象和面向过程都是一种思想。  (3)面向过程强调的是功能行为。  (4)面向对象将功能封装进对象,强调具备了功能的对象。  (5)面向对象是基于面向
  • 前言上一篇文章介绍了JS里如何“封装”数据方法,以及如何从原型对象生成实例。 这篇文章要介绍的,对象之间“继承”的五种方法。例如,现在有一个Animal对象的构造函数:function Animal() { this.species = ...
  • C++ 面向对象程序设计--多态性与虚函数 C++ 面向对象程序设计--多态性与虚函数 C++ 面向对象程序设计--多态性与虚函数

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 565,290
精华内容 226,116
关键字:

面向对象和面向函数