如何选择编程语言(二)

如何选择编程语言(二)
0

4. 面向对象范式

4.1. 是否支持面向对象

4.1.1. 不支持

汇编语言、C 语言、Bash 脚本等。

C 语言虽然有结构体,但语言层面没有提供封装和继承的功能,函数也不能与结构体紧密地绑定在一起从而构成“函数属于类”的关系。

4.1.2. 支持

C++ 、Golang、Java、C# 、Objective-C、Swift、Kotlin、Python、Ruby、JavaScript、PHP 等大多数常见的编程语言。

4.2. 是否“一切皆对象”

4.2.1. 存在不属于对象的数据类型

C++ 中的基本数据类型 int、long、short、float、double、char、bool 等以及指针(包括数组)类型都不是对象类型。

Java 中的基本数据类型 boolean、char、short、int、long、float 和 double 都不是对象类型。

JavaScript 中的基本数据类型 undefined、null、boolean、number、string 和 symbol
都不是对象类型。“123”.substring(1,2) 这样的表达式之所以能运行,是因为 JavaScript 能把 “123” 这样的基本数据类型的变量作了一个隐式的向对象的转换,即 JavaScript 运行时执行的实际上是 new String(“123”).substring(1, 2)。

PHP 中的 boolean、integer、float、string、array 等类型都不是对象类型。

4.2.2. 一切皆对象

C# 、Kotlin、Python、Ruby

4.2.3. “一切皆对象”的优劣

4.2.3.1. ”一切皆对象“的优点

与现实世界更加贴近,因为现实世界中布尔值、数字、字符这些概念也有其相应的属性和运算/操作(对应类的成员属性和成员方法),与其他概念也有从属关系(对应类的继承)。

不需要对基本数据类型和其对应的对象类型区别对待。在 Java 中的泛型不支持基本数据类型,只支持对象类型,就可能导致在使用泛型时频繁地进行装箱拆箱;在用反射 API 访问基本数据类型的字段的值的时候的处理也会变得繁琐。

4.2.3.2. ”一切皆对象“的缺点

待补充。。。

4.3. 是否允许类的静态方法或者成员方法以外的函数

4.3.1. 不允许

Java、C#

4.3.2. 允许

C++ 、Kotlin、JavaScript、Python、PHP

4.3.3. 允许类外函数的优劣

4.3.3.1. 允许类外函数的优点

可以解决某些函数难以归到某个类中的问题。

允许某些函数脱离类而存在,在某些情况下可以提升开发效率。

4.3.3.2. 允许类外函数的缺点

待补充。。。

4.4. 类与继承的实现方式

4.4.1. 用 class 关键字明确定义

C++ 、Java、C# 、Swift、Kotlin、Python、PHP

4.4.2. 用其他关键字明确定义

Objective-C 用 @interface@property@implementation 等关键字明确定义类

4.4.3. 基于原型链的类与继承

JavaScript

4.4.4. 基于原型链的类与继承的优劣

4.4.4.1. 优点

编译器 / 运行时程序实现起来比有类定义语法的语言的简单。

天然地遵循了“组合优于继承”的思想,避免了子类实现的多个接口或者继承的多个类中具有同样签名的成员方法的定义不同的问题(如 Java 中一个类实现的两个接口都定义了一个同名、参数个数与类型都相同,但返回值类型不同)。

4.4.4.2. 缺点

“类”与“实例对象”、类的继承的关系不够直观明晰,初学者理解的难度大。

4.5. 是否允许多继承

4.5.1. 允许一个类继承多个类(不包括接口)

C++ 、Python

4.5.2. 不允许多继承

Java、C# 、Kotlin

JavaScript(一个对象只能有一个原型)

4.5.3. 多继承的优劣

4.5.3.1. 多继承的优点

允许多继承能让程序更好地描述现实世界,因为现实世界中,一些事物往往会拥有两个或两个以上事物的属性,如一个人可以即是一个程序员又是一个作家。

4.5.3.2. 多继承的缺点

一个类继承两个有同样函数定义的类时,还有处理菱形继承时,会变得难以处理和难以理解。

4.6. 如何实现面向接口编程

4.6.1. 用 interface 关键字显式定义接口

Java、C# 、Kotlin、PHP

4.6.2. 利用抽象类

C++ 、Python

4.6.3. 显式定义接口的优劣

待补充。。。

5. 函数式编程范式

5.1. 函数是否“第一公民”

5.1.1. 函数是“第一公民”

函数与数字、布尔值等一样是一种基础的数据类型,可作为变量、类的成员属性、函数的输入参数或返回值的类型:
JavaScript、Python、Kotlin、Haskell、Erlang 等

5.1.2. 函数不是“第一公民”

C 语言、C++ 、Java、C#

5.2. 是否支持 Lambda 表达式

5.2.1. 不支持

C 语言、Java 1.7 及以前版本、实现 ECMAScript 6 以前的 JavaScript

5.2.2. 支持

C++ 、Java 1.8 及以后版本、Kotlin、Python、实现 ECMAScript 6 或更高版本的 JavaScript

5.2.3. Lambda 表达式的优劣

5.2.3.1. 优点

能免去函数命名、严格声明的麻烦,使代码更简洁。函数的使用范围小且明确。这在不允许类外函数的语言(如 Java、C#)中尤为明显。

5.2.3.2. 缺点

若被滥用,尤其是多层 Lambda 表达式嵌套时,会使代码可读性、可维护性变差。

3赞

请问 “第一公民” 是啥意思呢?

百度的,我也不理解 :joy:

1赞

这是一个好问题。@xiaomengxin 转的文章里说的是比较准确的:

“函数是一等公民”可以理解为一个函数可以直接被赋值给一个变量、直接作为函数的输入参数或者直接作为函数的返回值。

而且在 JavaScript 中,你可以直接在一个函数的函数体内定义一个函数,而在 C 语言里你是不能在一个函数的函数体内定义另一个函数的。

谢谢两位的耐心解答!

学习了 :blush: