第24课:关于继承和Trait进阶及Spark源码鉴赏

来源:互联网 发布:2015淘宝双十一交易额 编辑:程序博客网 时间:2024/05/29 16:45

Scala首先是作为一门面向对象的语言,在此基础之上发展出函数式编程。
Class Any is the root of the Scala class hierarchy(Java , object). Every class in a Scala execution environment inherits directly or indirectly from the class
Scala中的任何一个类,在执行中都是直接和间接继承了Any。因此,Scala的函数式编程其实还是面向对象的,Scala中一切皆对象。

那么Scala中的object在哪里呢?
Class AnyRef is the root class of all reference types. All types descend from this class.
AnyRef的继承自Any,Scala中定义的接口,类,抽象类都继承自AnyRef,即AnyRef相当于Java中的object。
这里写图片描述

Java不是完全面向对象的,而Scala是的。那么,Scala是怎么cover所有 东西使之面向对象呢?
AnyVal is the root class of all value types, which describe values not implemented as objects in the underlying host system
从继承结构的角度讲,Any是终极父类, 他包含AnyRef和AnyVal两个子类。AnyRef是所有类,子类,抽象类,接口等的所有引用类型的父类;AnyVal是所有值类型如Int,Char,Double Float等的父类,即把基本类型封装成对象级别。

这里写图片描述

Java比较弱的一面是没有直接把值类型封装成一个对象,在Java中的值事实上就是一个值,即使虽然后来有拆箱装箱的操作,但事实上是,在Java中,一个整数就是一个整数,就不是一个对象。
Java没有把值类型封装成类和对象,而Scala在值类型和引用类型之上有更高级别的Any类型,一切均为Any类型的实现,而Any是对象级别的,所以Scala中一切皆对象。
这也充分的说明了为什么Java不是一门彻底的面向对象的语言,而Scala是的。简单来讲,Java中的1 就是一个数值1,1不具有任何方法的。 而Scala中的1 自身是具有像ToString这样的方法的(其中含有隐身转换),因为这个方法直接继承自它的Root,即 Any类型。

几乎编程中所有解决不掉的问题一定需要进行抽象,一旦进行抽象,往往没有解决不掉的问题。
例如Spark为了把自己的性能提高到更高的境界,也是一步一步抽象的, RDD本身就是一个抽象,后来又有RDDFrame更高级别的抽象,再后来又有一个DataSet更高级别的抽象。抽象程度越高,它的优化程度越高。
例:
这里写图片描述
赋值给succ的匿名函数本身其实就是Function1
手动定义的Function1和此匿名函数是一样的
从继承结构的角度看,匿名函数其实是实现接口,接口中的callback具有apply方法,所以将其赋值给匿名函数时,匿名函数自己调用了apply方法。因此,没有所谓的函数式编程,其背后都是对象。

Null is - together with scala. Nothing – at the bottom of Scala type hierarchy.
Null is a subtype of all reference types; its only instance is the null reference. Since Null is not a subtype of value types null is not a member of any such type. For instance, it is not possible to assign null to a variable of type scala.Int
Nothing is – together with Scala.Null – at the bottom of Scala’s type hierarchy
从继承体系结构的角度讲,Nothing处在Scala类型结构的最底部
这里写图片描述

Nothing和Null的区别:
假设从一个杯子的角度讲,Null就是什么都没有,连那个杯子都没有;而Nothing是空杯子,处于道德经所谓虚空状态

总结:Scala继承体系,源头在Any,一分为二为AnyRef和AnyVal,终结于Nothing

为什么无论是Java还是Scala,都不允许继承多个抽象类?
C继承自抽象的A和B, A和B继承自D, C的父类同时是A和B, D是A和B的父类, D中可能有公共的方法,A和B继承了这个公共的方法,C也继承了公共的方法,实现调用的时候不知道该调用哪一个,造成二义性。
为什么Java和Scala允许同时继承多个接口?多个接口不存在二义性。
Trait中不可以定义var类型的变量
Trait背后到底是什么?
这里写图片描述
Java自身有带反编译工具,其他工具也是封装了Java的反编译工具。
通过反编译告诉我们的事实真相toCode是一个Abstract级别的方法,trait完全作为一个interface,没有抽象方法的实现,ScalaTrait就是Java中的一个普通的interface
这里写图片描述
这里写图片描述
**这里写图片描述**

而在toCode方法中加入其实现后反编译的结果显示,trait和之前的interface不同,有interface成为一个抽象类,而且其中的toCode方法由abstract级别变为Static级别,这给了我们很好的启发,即 trait中的各种工具方法,如logger之类的都可以通过with的方式引进来,则引进来的方法是静态的方法,这是通过反编译告诉我们的事实真相,所以这个JVM把它加载进来是,整个进程运行时就是一份,所以可不断的复用,这是为什么我们喜欢吧工具方法封装在trait里的重要的原因,因为可以节省内存。

**配套视频链接:http://www.tudou.com/listplay/rd3LTMjBpZA/5aMksv8nHTo.html
课程及技术交流QQ:460507491**

0 0
原创粉丝点击