2491 3

第2课:Scala面向对象彻底精通及Spark源码阅读(2) [推广有奖]

  • 1关注
  • 8粉丝

硕士生

34%

还不是VIP/贵宾

-

威望
0
论坛币
305 个
通用积分
0
学术水平
5 点
热心指数
14 点
信用等级
2 点
经验
22972 点
帖子
73
精华
0
在线时间
135 小时
注册时间
2016-2-27
最后登录
2016-9-11

相似文件 换一批

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
二、Scala中的Object实战详解


object
定义一个类同名的object对象,里面存放静态的成员或者方法,把该object对象称之为该类的伴生对象

101903rpjto0tsjp1vrppt.png

图3


在图3中,SparkContextobject为SparkContext类的伴生对象,里面存放一系列静态的成员和静态的方法。而且,当我们第一次调用SparkContext时,SparkContext伴生对象会被执行一次,仅此一次。下面是一个示例:

101943kw6bltg9lyzcegg5.png

图4


图4中object Person是class Person的伴生对象,class Person称之为object Person的伴生类。伴生对象适合在里面定义一些工具方法,以及存放一些全局唯一的常量,节省空间。


//第一次调用:Person伴生对象的getSalary方法

//此时,我们发现:Person伴生对象被初始化,打印出字符串Scala

scala> Person.getSalary

Scala

res34: Double = 0.0


//第二次调用:Person伴生对象的getSalary方法

//此时,我们发现:Person伴生对象不再需要初始化,没有打印出字符串Scala

scala> Person.getSalary

res35: Double = 0.0

以上示例中确实验证了:伴生对象会被执行一次,仅此一次。

Scala中,我们在定义类的对象时, 一般都不会用new类名,再传入参数的方式来定义。而是直接用类名,或者类名加参数的方式。例如,我们重温下面的示例:

我们构造一个数组,其实是调用Array的伴生对象object Arrayapply方法。

scala> val array=Array(1,2,3)

array: Array[Int] = Array(1, 2, 3)


scala> val array=Array.apply(1,2,3)

array: Array[Int] = Array(1, 2, 3)

以上两种定义数组的方式效果是一样的。apply方法就是当前类的伴生对象的工厂方法。延伸一下,Java水平比较高的编程人员,在构造Java对象时,一般来说不会直接new一个类,而是通过工厂方法模式来创建。而Scala语言中,天生就支持这次模式,所以在具体类对象构造时,一般都是在伴生类的伴生对象的apply方法中去实现!这样可以控制对象的生成。


三、
Scala中的抽象类、接口实战详解


abstract

抽象类使用abstract关键字,以Spark源码RDD类为示例,如下图5所示:

ETZ)S4ZVD3XUF}X9OHH4.png

5

子类去继承抽象类,跟Java一样,也是使用extends关键字。如JdbcRDD就继承了RDD抽象类,如下:

  1. classJdbcRDD[T: ClassTag](
  2.    sc: SparkContext,
  3.    getConnection: () => Connection,
  4.    sql: String,
  5.    lowerBound: Long,
  6.    upperBound: Long,
  7.    numPartitions: Int,
  8.    mapRow: (ResultSet) => T = JdbcRDD.resultSetToObjectArray _)
  9.   extends RDD[T](sc,Nil) with Logging {
复制代码

那么JdbcRDD就可以使用父类RDD所有它可以使用的属性和方法。当然,子类也可以覆盖父类的属性和方法。注意,这里面有个前提,父类的属性和方法没有加final


一个抽象类,那么里面肯定是定义了某个方法,但是没有又实现体,只有方法的说明。比如:

6NILDOBR72LN3Y[MH@S73JU.png

图6

图6代码块中,compute就是RDD抽象类的一个方法,只有说明,没有实现体。


override

在上面JdbcRDD子类中,因为JdbcRDD继承了RDD抽象类,那么在JdbcRDD中一定要复写compute方法。如图7所示:

`INW[{E6_}OJ[AISWTC(E@B.png

图7

使用override关键字表示复写父类的该方法。除了覆盖父类的方法,也可以使用override来覆盖父类的val属性。父类在定义属性时没有给具体的值,就是抽象属性,在子类中,子类必须覆盖该属性。


trait

相当于Java的接口。在trait定义的类中可以定义抽象方法,但是又没有具体的实现。子类可以使用extends关键字来继承该父类。


Spark源码中的RDD类为示例,RDD继承了SerializableLogging两个父类。一个子类如果继承多个父类,那么继承的第一个父类前使用extends关键字,后面的父类使用with关键字。RDD继承的这两个父类,在定义时都使用trait关键字来定义。Scala语法中,不允许一个子类同时继承多个抽象父类,但是允许同时继承多个trait父类。

  1. abstract class RDD[T: ClassTag](
  2.    @transient private var _sc: SparkContext,
  3.    @transient private var deps: Seq[Dependency[_]]
  4.   ) extends Serializable with Logging {
复制代码

图8是Serializable类的源码:

P2GZ3W))C~5XM12~`A`$}9G.png

图8

trait的用途,更多的是作为工具方法的容器。我们把通用的功能,放在trait中。一个子类,如果需要把很多通用的功能都混进来,那么就需要继承多个trait父类,继承的第一个父类使用extends,后面的父类使用withSpark源码Master类就是一个示例,继承了多个父类。如图9所示:

5(8HG8I%4@{XAQX0YNEJV99.png

图9










二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:SCALA Spark 面向对象 Park SPAR Spark Scala DT_Spark 大数据

WNZ}IN4O13E]~UEJ7)J784N.png (25.13 KB)

WNZ}IN4O13E]~UEJ7)J784N.png

16C_XH42PT[@8%QB`{)]44N.png (72.12 KB)

16C_XH42PT[@8%QB`{)]44N.png

已有 1 人评分经验 论坛币 收起 理由
daazx + 40 + 10 精彩帖子

总评分: 经验 + 40  论坛币 + 10   查看全部评分

本帖被以下文库推荐

沙发
guo.bailing 发表于 2016-3-22 20:54:09 |只看作者 |坛友微信交流群
支持楼主推出系列文章,楼主加油。

使用道具

guo.bailing 发表于 2016-3-22 20:54
支持楼主推出系列文章,楼主加油。
多谢捧场!{:2_31:}

使用道具

注:本学习笔记来自DT大数据梦工厂——http://www.dtspark.com/

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-28 02:26