类比JS面向对象和JAVA面向对象的设计思想

(个人理解,如有误导请指正)

我们都知道JS面向对象是采用原型链的方式设计的,JAVA是采用正统的面向对象的思想设计的,通过我的类比分析,我得出一个结论,它们之间本质上是没有区别的。

先讲一讲面向对象的特点: 封装和继承和多态。

封装: 最原始的结构化编程理念是 “数据结构+操作”,比如C语言,通过结构体和对相应结构体的一堆操作函数来实现业务逻辑,相应函数的第一个参数都有一个指针形参来指向要操作的结构体。这其实也是一种封装,只是函数和函数之间的没有明显的界限。到了面向对象的世界里,我们把数据结构和其操作函数严格的封装到一块,用类的思想进行了有界限的划分,不同的类之间起操作和数据都有了明显的划分,编译器给类函数自动添加了this指针来指向要操作的数据。

继承:自然界的事物从来不是宇宙诞生之初就是这个样式的,而是进过不停的进化才变的越来越高级,比如 单细胞-多细胞-动物-人,进化的过程中,人自然有着动物的属性,那么我们编程的时候想要封装人类,把对人类的所有操作和对动物的所有操作都封装到人这个类里面显然是不合理的,我们自然的想法是给动物封装一个类来包含对动物的所有操作,给人封装一个类来包含对人类的所有操作,然后人类继承动物类,通过继承,逻辑更加清晰合理。

多态:人虽然有着动物属性,但是人说话的方式和动物说话的方式有着明显的区别,在继承里面,我们应该在动物类里实现动物说话这个操作方法,在人类里面实现人说话这个操作方法,然后人类继承动物类,然后对于要操作的数据对象,如果是数据对象是人,那么理应调用人说话这个操作来实现人说话,如果数据对象是动物,那么就应该调用动物说话这个操作来实现动物操作,如果人类里面没有实现人说话这个操作,我们应该根据继承链向上找,找到动物说话这个操作来执行人说话这个行为,这种逻辑方式是自然而然的思维,我们没有必要深入的考虑为什么~

我们仔细思考一下,上面讲的封装、继承、多态、更多关注的是类对数据的操作,是操作函数!没有体现这个类要操作的数据模型是什么样的,那么数据模型在类中如何体现呢?答案是构造函数!给类添加一个特殊的操作函数--构造函数,然后通过执行一个类的构造函数,我们就能在堆内存中是实例化出一个特定结构的数据模型,多次构造,会生成多个数据模型~  对所有数据模型的操作函数,我们只需要一套就可以了--那就是类本身。

好了,通过上面的分析我们可以得出结论,一个类的设计实现只需要设计两部分东西--- 1构造函数(代表数据模型)2一堆的操作函数!

我们来分析下JS是如何实现面向对象的。JS声明一个类的时候,最简单的情况,只实现一个构造函数就可以了,比如

function Person(){ this.name = "a";this.age = 12;}  JS解释器默认会给函数对象再添加一个prototype属性来指向一个原型对象,这个prototype对应的原型对象其实就是我上面的我说到的一堆的操作函数的包含对象!prototype原型对象默认还会包含一个__proto__引用来指向下一个原型,默认JS解释器给函数的prototype的__proto__指向Object类的原型对象,其中包含了所有对象共有的基础操作,这其实就是JS里的继承! 好了,这里我总结下JS类的组成,构造函数+构造函数对应的prototype对象来构成当前类,prototype对象的__proto__指向的下一级prototype代表了当前类继承的父类、爷爷类! 类执行的时候,同过构造函数构造出数据模型,同样给数据模型对象的__proto__属性指向对应的原型对象(逻辑上理解就是数据模型有指向对应的类的引用),调用数据模型操作的时候,解释器根据数据模型的__proto__指向的原型对象寻找对应的操作函数,顺着__proto__链一直找到爷爷类、祖先类。总结:JS类就是构造函数+原型对象链!  一个类在解释器内存中只存在一个构造函数和原型对象链!

(补充:JS中的原型对象默认属性有两个:__proto__和constructor,__proto__指向父原型,constructor指向构造函数,我们也可以这么理解JS类:一个函数的原型对象代表了一个类!一个函数的原型对象在解释器中只存在一个!new对象的时候,执行对应的原型对象的constructor来生成数据模型!)

JAVA的类模型简单说明:编译后的class文件装载进虚拟机后代表一个类,同一个虚拟机同一个ClassLoader范围内只在内存中存在一个,其中包含了类对象构造函数还有一堆操作函数,类通过extend继承关键字来引用其他的class~

大结论:JS面向对象和JAVA面向对象是一致的,本质上都是来源于面向对象理论思想!!!

 

 

你可能感兴趣的:(JAVA,JS,面向对象)