面向对象的不同实现方法
Willem Zhang Lv6

面向对象编程是编程的一种思想范式

区别于面向过程,面向对象通过不同对象的属性和方法之间的交互实现功能

但是同样是面向对象,也会有不同的方法,接下来将以java和javascript举例。

首先,这里探讨一下面向对象的本质:

面向对象本质上就是函数作用域的一种封装。 https://www.zhihu.com/question/53851561

也就是说,只要只要将数据和方法封装到一个东西(对象)里面,那么这就是面向对象。

那么现在要实现让黄猫和红猫叫的功能,只需要将这两只猫的属性和方法封装到两个对象上,然后让它们各自叫就可以了

1
2
3
4
5
6
7
8
9
10
11
12
13
黄猫 {
color: yellow;

miao() {console.log('miao')}
}

红猫 {
color: red;

miao() {console.log('miao')}
}
黄猫.miao()
红猫.miao()

以上代码就实现了面向对象(虽然不能实现传统意义上的继承多态,但是封装实现了),但是可以发现这样写代码会是冗余的,有很多行有重复。

于是,为了避免这种重复,java和js分别走到了两个方向。

java将找到对象的共性将抽象成类,然后通过给类传递不同的参数实例类来得到不同的对象,相同的类实例出来的对象具有类似的特征,而这些类似的特征通过写到类里面避免了多次重复在对象里面书写。java还通过将常用的类定义到标准库里面使得我们只需要直接引入这个库就可以使用这些类了。
于是说java面向对象是基于类的。

而js面向对象是基于对象的,专业说法是原型(原型也是一个对象)和原型链的。

每一个新的对象通过构造函数构造,而每个构造函数都会有一个显式原型,通过构造函数构造出来的函数会隐式指向构造函数的显式原型。

例如new一个Array()(Array构造函数是js语言自带的),这个Array构造函数有一个显式原型,这个显式原型就是Array对象,通过Array构造函数构造出的对象会隐式指向构造函数的显式原型,也就是Array对象。(注意分清除Array函数和Array对象)

前面一直再说构造函数,那么构造函数是是什么呢,和普通函数又有什么区别的?

其实构造函数就是一个函数,区别函数和构造函数的方法要看他们的调用方法,如果new一个函数,那么此时这个函数在当成一个构造函数用。

而Array对象也会有一个原型,它会指向Object对象,Object对象也有一个原型,它会指向null,万物归于无。

上面这个链条就是原型链。

js是通过将新构建的对象指向原来存在的对象来实现减少代码的冗余的,和java很不相同。

而且js万物皆对象,函数也是一个对象,也可以给函数添加属性而方法。

隐式指向的方法是给构造出的对象加一个proto属性,这个属性指向它的原型。
显式指向是每个函数在定义的之后都会有一个prototype属性,这个属性指向一个显式原型,将来由这个构造函数new出的对象会隐式指向这个原型。

上面的猫的例子分类用java和js的思想写出来的话就成了下面的样子。(非完全按照语法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class{ // 定义类
color;
constructor(color) {
this.color = color
}

miao() {console.log('miao')}
}

红猫 = new 猫(red);
黄猫 = new 猫(yellow);

红猫.miao()
黄猫.miao()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 代码实现
function 猫(color) { //定义一个猫函数会自动生成一个猫原型
this.color = color
}

猫.prototype.miao = function() {console.log('miao')} //给原型添加方法 定义函数和给原型添加方法相当于java的定义类

红猫 = new 猫(red) // 生成一个指向原型的新对象
黄猫 = new 猫(yellow)

红猫.miao()
黄猫.miao()

// 思想
// 原型猫 是个对象 避免多次书写相同的属性和方法
猫 {
constructor: 猫() //函数定义就有
__proto__: Object //函数定义就有

miao() {console.log('miao')} //自己添加
}

// 实例猫 也是个对象 指向原型猫(原型对象) 于是可以用原型的属性和方法
红猫 {
color: red
__proto__:猫 //指向原型,可以用原型的方法
}

黄猫 {
color: yellow
__proto__:猫
}

可以看出主要区别在于定义的时候,一个定义类并在类中添加属性和方法(constructor函数初始化),一个定义函数并给这个函数的原型添加属性和方法(原型在定义函数的时候自动生成)

在实例化的时候,java根据类创建对象,获得实例
在实例化的时候,js根据构造函数创建对象,让对象指向原型,获得实例

  • Post title:面向对象的不同实现方法
  • Post author:Willem Zhang
  • Create time:2022-05-02 11:27:10
  • Post link:https://ataraxia.top/2022/05/02/面向对象的不同实现方法/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.
 Comments