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

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

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

    优点:

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

    缺点

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

    2018-03-19 23:05:00
    主要讲解函数编程好处和优缺点。 主要讲解函数编程好处和优缺点。 主要讲解函数编程好处和优缺点。
  • 面向函数编程总结

    千次阅读 2018-12-07 15:52:23
    闭包最显而易见的,就是其函数嵌套函数的写法。一个典型的闭包代码如下 function foo(){ var local = 1 function bar(){ local++ return local } return bar } var func = foo() func() 因...

    从闭包谈起

    闭包的原文是Closure。也就是“闭”。包这个字是翻译者私自加上的。闭包最显而易见的,就是其函数嵌套函数的写法。一个典型的闭包代码如下

    function foo(){
      var local = 1
      function bar(){
        local++
        return local
      }
      return bar
    }
    
    var func = foo()
    func()
    

    因为是“闭”,上述代码隐藏了一个变量(local)。显然,如果你希望别人随便访问这个变量,就只能把这个变量写成一个局部变量。然而,你又希望别人按照你定义的方式可以访问这个变量。上述代码之所以能运行,是因为JS的作用域————函数内部可以访问外部的变量。java里也有类似的设定。那就是内部类能够访问外部类的所有属性和方法。

    public class Milk {
    	public final static String name = "纯牛奶";//名称
    	private static int num = 16;//数量
    	public Milk()
    	{
    		System.out.println(name+":16/每箱");
    	}
    	/**
    	 * 闭包
    	 * @return 返回一个喝牛奶的动作
    	 */
    	public Active HaveMeals()
    	{
    		return new Active()
    				{
    					public void drink()
    					{
    						if(num == 0)
    						{
    							System.out.println("木有了,都被你丫喝完了.");
    							return;
    						}
    						num--;
    						System.out.println("喝掉一瓶牛奶");
    					}
    				};
    	}
    	/**
    	 * 获取剩余数量
    	 */
    	public void currentNum()
    	{
    		System.out.println(name+"剩余:"+num);
    	}
    }
    
    /**
     * 通用接口
     */
    interface Active
    {
    	void drink();
    }
    /**
     * 测试Main方法
     */
    public class Person {
    	public static void main(String[] args) {
    		//买一箱牛奶
    		Milk m = new Milk();
    		Active haveMeals = m.HaveMeals();
    		//没事喝一瓶
    		haveMeals.drink();
    		//有事喝一瓶
    		haveMeals.drink();
    		//看看还剩多少?
    		m.currentNum();
    	}
    }
    

    原来虽然我们从不把内部类的用法叫做闭包。但是我们的代码里充斥着关于闭包的用法。比如安卓的点击事件处理

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Toast.makeText(MainActivity.this, "Hello World!", Toast.LENGTH_SHORT).show();
        }
    });
    

    处于对JAVA的简洁性和一贯性的原因,JDK设计人员一直拒绝把函数也当作对象。所以,才必须实现一个接口,把一个函数伪装成一个对象。我认为,函数不是一个对象,这应该是JAVA所剩不多的底线之一。

    Lambda 表达式

    在JAVA里,如果我们提到闭包,第一个想到的就是Lambda 表达式。语法非常简洁。如果只有一个参数,则可以省略括号。如果可以推断出类型,则可以在参数列表中省去类型。

    (参数) -> 表达式
    

    函数式【接口】(FunctionalInterface)

    我们举ArrayList的sort方法。

        @Override
        @SuppressWarnings("unchecked")
        public void sort(Comparator<? super E> c) {
            final int expectedModCount = modCount;
            Arrays.sort((E[]) elementData, 0, size, c);
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
            modCount++;
        }
    

    我们注意到,没有变化。仍然是接受一个Comparator对象。这不过Comparator接口发生了一个变化。增加了一个注解@FunctionalInterface。注意,这个注解只是强制编译器检查下面约束

    1. 函数式接口的方法中有且只能有个一个抽象方法,只有方法定义,没有方法体
    2. 在接口中覆写Object类中的public方法,不算是函数式接口的方法。
    

    比如说如下这个Comparator接口。

    @FunctionalInterface
    public interface Comparator<T> {
        int compare(T o1, T o2);//唯一一个
        boolean equals(Object obj);//覆盖compare类中的方法
    }
    

    这个注解表示,可以使用一个Lambda表达式作为接口的一个实现。

    方法引用

    java为了进一步简化,引入方法引用的概念

    button.setOnClickListener(event -> System.out.println(event));
    

    可以进一步被简写为

    button.setOnAction(System.out::println);
    

    面向流的编程

    JDK8中引入了流的概念。下面两个代码等价。

    long count = 0;
    for (Person p : persons) {
        if (p.getAge() > 20) {
            count ++;
        }
    }
    
    long count = persons.stream()
                        .filter(person -> person.getAge() > 20)
                        .count();
    

    据说使用Stream可以充分利用多核CPU。

    函数式编程

    函数式编程关心数据的映射,命令式编程关心解决问题的步骤。
    简介是函数式编程最大的特点。不过我们当然不是为了省键盘选择去磨脑子。两大好处,第一个是扔给程序员的甜头————更容易并行了。第二个则是送给程序员的毒酒————代码写成这样可以方便的进行数学研究。数学家对这群干活慢BUG多擅长装逼的程序员容忍到了极限了。不过程序员并非是傻子。haskell是人类公认的语法最为简介而优美的语言。前提是你理解什么叫单子就是自函子范畴中的独异点。
    在函数式编程中,一个循环可以写成(实际上是一个递归实现)

    factorial n = if n > 1
    
                  then n * factorial (n-1)
    
                  else 1
    

    正常写其实是这样的

    long factorial (int n)
    {
      long result = 1;
      while (n > 1)
        result *= n--;
      return result;
    }
    

    函数式编程的特点如下

    • 函数结果只依赖输入不依赖于上下文, 使得每个函数都是一个高度独立的单元, 便于进行单元测试和除错.

    • 函数结果不依赖于上下文也不修改上下文, 从而在并发编程中不需要考虑线程安全问题, 也就避免了线程安全问题带来的风险和开销. 这一特性使得函数式程序很容易部署于并行计算和分布式计算平台上。

    柯里化

    函数的柯里化(currying)是指将一个接受n个参数的函数变成n个接受一个参数的函数.

    def add(x:Int, y:Int):Int = {return x+y}
    

    等价于

    scala> def add(x:Int)= (y:Int)=>x*y
    add: (x: Int)Int => Int
    

    个人看法

    面向函数的编程可以完全替代命令式编程。
    但是,这并不意味着这种编程很容易。面向函数编程之所以能解决并发的问题,是因为这种语法本身就强迫你在写代码时想清楚并发问题再动笔。
    并发的实质是多个CPU的并行计算和单个CPU的分时复用。CPU是命令式的,所以人类顺理成章的按照命令式的思维构建了自己的编程理念。时至今日再来探讨是否当初错了,似乎已经为时太晚。
    面向函数的编程一直广为诟病的是其效率问题。但是实际上这种思路的效率并没有硬伤。只是其代码严重依赖优化,而整个编程社会完全没有准备好面向函数编程的基本组件,也没有足够的投入去优化代码。
    还是那句话,编程世界唯一重要的是算法,而非形式。算法能做到的事情就一定能实现。至于如何实现是最合适的,最优雅的,不过是成王败寇罢了。

    展开全文
  • 函数编程 (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,是都可以实现的,但是要用哪种还要根据需求具体考虑。如果要了解更多 函数式编程 和 面向对象编程 的基础概念的话,可以看看之前的这三篇文章。

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

    展开全文
  • 函数式编程作为结构化编程的一种,正在受到越来越多的重视。工程中不在只是面向对象编程,更多的人尝试着开始使用函数式编程来解决软件工程中遇到的问题。 什么是函数式编程?在维基百科中给出了...函数编程语言...

        函数式编程作为结构化编程的一种,正在受到越来越多的重视。工程中不在只是面向对象编程,更多的人尝试着开始使用函数式编程来解决软件工程中遇到的问题。

        什么是函数式编程?在维基百科中给出了详细的定义,函数式编程(英语:functional programming)或称函数程序设计,又称泛函编程,是一种编程范型,它将电脑运算视为数学上的函数计算,并且避免使用程序状态以及易变对象。函数编程语言最重要的基础是λ演算(lambda calculus)。而且λ演算的函数可以接受函数当作输入(引数)和输出(传出值)。

        而在面向对象编程中,面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是种具有对象概念的程序编程范型,同时也是一种程序开发的方法。它可能包含数据、属性、代码与方法。对象则指的是类的实例。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性,对象里的程序可以访问及经常修改对象相关连的数据。在面向对象程序编程里,计算机程序会被设计成彼此相关的对象。

        对象与对象之间的关系是面向对象编程首要考虑的问题,而在函数式编程中,所有的数据都是不可变的,不同的函数之间通过数据流来交换信息,函数作为FP中的一等公民,享有跟数据一样的地位,可以作为参数传递给下一个函数,同时也可以作为返回值。

     

    面向对象编程的优点

        面向对象程序设计可以看作一种在程序中包含各种独立而又互相调用的对象的思想,这与传统的思想刚好相反。传统的程序设计主张将程序看作一系列函数的集合,或者直接就是一系列对电脑下达的指令。面向对象程序设计中的每一个对象都应该能够接受数据、处理数据并将数据传达给其它对象,因此它们都可以被看作一个小型的“机器”,即对象。目前已经被证实的是,面向对象程序设计推广了程序的灵活性和可维护性,并且在大型项目设计中广为应用。此外,支持者声称面向对象程序设计要比以往的做法更加便于学习,因为它能够让人们更简单地设计并维护程序,使得程序更加便于分析、设计、理解。同时它也是易拓展的,由于继承、封装、多态的特性,自然设计出高内聚、低耦合的系统结构,使得系统更灵活、更容易扩展,而且成本较低。

        在面向对象编程的基础上发展出来的23种设计模式广泛应用于现今的软件工程中,极大方便了代码的书写与维护。

        创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

        结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

        行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

     

    面向对象编程的缺点

        面向对象编程以数据为核心,所以在多线程并发编程中,多个线程同时操作数据的时候可能会导致数据修改的不确定性。

        在现在的软件工程中,由于面向对象编程的滥用,导致了很多问题。首先就是为了写可重用的代码而产生了很多无用的代码,导致代码膨胀,同时很多人并没有完全理解面向对象思想,为了面向对象而面向对象,使得最终的代码晦涩难懂,给后期的维护带来了很大的问题。所以对于大项目的开发,使用面向对象会出现一些不适应的情况。

        面向对象虽然开发效率高但是代码的运行效率比起面向过程要低很多,这也限制了面向对象的使用场景不能包括那些对性能要求很苛刻的地方。

     

    函数式编程的优点

        在函数式编程中,由于数据全部都是不可变的,所以没有并发编程的问题,是多线程安全的。可以有效降低程序运行中所产生的副作用,对于快速迭代的项目来说,函数式编程可以实现函数与函数之间的热切换而不用担心数据的问题,因为它是以函数作为最小单位的,只要函数与函数之间的关系正确即可保证结果的正确性。

        函数式编程的表达方式更加符合人类日常生活中的语法,代码可读性更强。实现同样的功能函数式编程所需要的代码比面向对象编程要少很多,代码更加简洁明晰。函数式编程广泛运用于科学研究中,因为在科研中对于代码的工程化要求比较低,写起来更加简单,所以使用函数式编程开发的速度比用面向对象要高很多,如果是对开发速度要求较高但是对运行资源要求较低同时对速度要求较低的场景下使用函数式会更加高效。

     

    函数式编程的缺点

        由于所有的数据都是不可变的,所以所有的变量在程序运行期间都是一直存在的,非常占用运行资源。同时由于函数式的先天性设计导致性能一直不够。虽然现代的函数式编程语言使用了很多技巧比如惰性计算等来优化运行速度,但是始终无法与面向对象的程序相比,当然面向对象程序的速度也不够快。

        函数式编程虽然已经诞生了很多年,但是至今为止在工程上想要大规模使用函数式编程仍然有很多待解决的问题,尤其是对于规模比较大的工程而言。如果对函数式编程的理解不够深刻就会导致跟面相对象一样晦涩难懂的局面。

     

    总结

        函数式编程和面向对象编程各有利弊,一个语法更加自由,一个健壮性更好。作为程序员应该对两种编程方式都有所了解,不管是哪种方式,只要能够很好的解决当前的问题就是正确的方式,毕竟对于软件工程来说解决问题是最主要的,用的工具反而没有那么重要,就像对程序员来说语言不重要,重要的是解决问题的思想。

        现在这两者的发展趋势是相互借鉴的,许多以面向对象作为基础的语言例如Java等都在新的版本中添加了对函数式编程的支持,而函数式编程则借鉴了一些在面向对象语言里用的一些编译技巧使得程序运行更快。

    展开全文
  • 1、概念 面向过程编程(procedure oriented Programming)(POP) ...面向过程编程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。 面向对象编程是...
  • 函数编程vs面向对象编程

    千次阅读 2017-02-17 23:48:58
    什么是面向对象,其实我也不是很懂,我以前一直认为面向对象就是继承,而继承就是虚函数,有时候在思考,真的是这样子的吗?...,如果在面向过程的编程模式中,我们可能要为每一个学生建立一个存放他/她属性的一个
  • 面向对象编程函数编程的理解

    千次阅读 2018-09-07 14:08:52
    面向对象编程函数编程的理解 面向对象编程的优点 面向对象程序设计可以看作一种在程序中包含各种独立而又互相调用的对象的思想,这与传统的思想刚好相反。传统的程序设计主张将程序看作一系列函数的集合,...
  • 面向对象 继承 闭包
  • 面向对象编程面向过程编程函数编程)都是程序设计的方法,不过稍有区别。 套路 面向过程编程 1. 导入各种外部库 2. 设计各种全局变量 3. 写一个函数完成某个功能 4. 写一个函数完成某个功能 5. 写一个函数...
  • 主要介绍了JS面向对象编程对象和构造函数,结合实例形式详细分析了JS面向对象编程对象和构造函数具体概念、原理、使用方法及操作注意事项,需要的朋友可以参考下
  • 函数编程面向对象编程的优劣

    千次阅读 2018-10-28 20:44:44
    函数式编程作为结构化编程的一种,正在受到越来越多的重视。工程中不在只是面向对象编程,更多的人尝试着开始使用函数式编程来解决软件工程中遇到的问题。 什么是函数式编程?...函数编程语言最重要的基础...
  • 第9章 从面向对象到函数编程 假如本书的写作时间倒退回十年前,书名可能会变成JavaScript面向对象编程思想。自上世纪90年代兴起的面向对象编程思想随Java的繁荣达于顶点,在JavaScript从一门只被用来编写零星的...
  • 所谓面向对象编程,就是把一切万物看着对象(即一切皆对象),此对象具有一定的属性和方法。对象怎么理解呢?我的理解:好比如我们人,人有名字、有性别、有年龄等等一些本身具有的属性,还有人能跑、能吃饭、能睡觉...
  • 主要介绍了Python3.5面向对象编程,结合图文与实例形式详细分析了Python面向对象编程相关的概念、类定义、实例化、实例变量、类变量、析构函数等相关原理及使用技巧,需要的朋友可以参考下
  • 面向对象编程,这种编程是把问题看作由对象的属性与对象所进行的行为组成。基于对象的概念,以类作为对象的模板,把类和继承作为构造机制,以对象为中心,来思考并解决问题。 优点 函数编程:支持闭包和高阶...
  • [59]python函数编程面向对象编程

    千次阅读 2018-06-13 08:51:22
    函数编程 函数:function。 函数式:functional,一种编程范式。函数编程是一种抽象计算机的编程模式。 函数!= 函数式(如计算!=计算机) 如下是不同语言的抽象 层次不同 - 高阶函数 能接收...
  • 目标-Swift 游乐场是玩耍的地方。 麻省理工学院许可。
  • 现代C++函数编程模式

    2018-06-27 02:50:56
    本文档介绍了c++11之后添加的函数编程特性,令C++除了面向对象编程之外还可用函数编程,更加适合多线程并发的编程场景.
  • 面向过程,面向对象,面向函数编程的理解 // 1. 面向过程 // 面向过程将编程任务当作完成一件事情,这件事情需要按步骤完成。比如说,煮咖啡这件事:先拿一定量的咖啡豆,然后磨成粉末,再倒入咖啡机,等待几分钟,...
  • 编程思想对比:面向过程对比面向对象 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发“更快更好更强.....
  • 函数在面对对象的编程中又被叫做方法,会受到作用域的制约,Lua中具有类等面向对象的特性,接下来我们就来看一下Lua中函数面向对象编程的基础知识整理
  • 函数编程的思想主要为:先编好一个个我们需要的具有特定功能的函数,然后再声明(Python 只用把所要用的函数全部写在最前面即可),比如 C 或者一些其他面向过程的程序设计语言,写完函数就需声明。 接下来我就用...
  • 上一篇文章我们已经介绍了部分Python面向对象编程基础的知识,大家可以参阅:Python面向对象编程基础解析(一),接下来,我们看看另一篇。 封装 1.为什么要封装? 封装就是要把数据属性和方法的具体实现细节隐藏...
  • 20年Python3.7零基础入门到爬虫实战正则IO面向对象函数编程考证教程
  • Javascript 面向对象编程:构造函数的继承 本节主要介绍,如何生成一个”继承”多个对象的实例。 比如,现在有一个”动物”对象的构造函数, function Animal(){ this.species = "动物"; } 还有一个”猫”对象的...
  • 编程范例 这是针对面向9年级学生的面向对象编程函数编程暑期课程的课程。 有关每周会议的注释,请参阅课程表文件夹,有关编程任务的起点,请参见代码文件夹。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 388,210
精华内容 155,284
关键字:

面向函数编程