第九课:Scala类和对象彻底实战

1.关于类的构造

abstract class RDD[T: ClassTag](

    @transient private var _sc: SparkContext,

    @transient private var deps: Seq[Dependency[_]]

  ) extends Serializable with Logging {

 

1.类名后面直接有括号,括号里面的成员从理论上讲,都是这个类的成员

2.在类构造的时候,必须传入的参数

这个构造器叫主构造器,当然构造器可以重载

/** Construct an RDD with just a one-to-one dependency on one parent */

  def this(@transient oneParent: RDD[_]) =

    this(oneParent.context , List(new OneToOneDependency(oneParent)))

但是可以见到,重载的构造器也是一定直接或者间接地去调用了主构造器

 

 

class SparkContext(config: SparkConf) extends Logging with ExecutorAllocationClient

 

def this() = this(new SparkConf())

def this(config: SparkConf, preferredNodeLocationData: Map[String, Set[SplitInfo]]) = {

    this(config)

    logWarning("Passing in preferred locations has no effect at all, see SPARK-8949")

  }

 

def this(master: String, appName: String, conf: SparkConf) =

    this(SparkContext.updatedConf(conf, master, appName))

//以下的重在构造器是间接调用主构造器

private[spark] def this(master: String, appName: String) =

    this(master, appName, null, Nil, Map())

 

所以重载构造器要么直接调用主构造器,要么间接调用主构造器

 

2.在类的代码中,那些不被方法封装的代码,什么时候会被执行实例化的呢?

其实就是在主构造器调用的时候,它会实例化很多全局的变量,而且还能强制让你做一些事情(很多框架都会做这件事情)

那是不是说类的所有成员,在类被实例化的时候,就必须实例化呢?

有些成员是,后面会用到,但是不需要在启动的时候用到

这时候,scala出现另外一个语法现象:lazy!!!!

 

 @transient

  lazy val listenerManager: ExecutionListenerManager = new ExecutionListenerManager

  @transient

  protected[sql] lazy val catalog: Catalog = new SimpleCatalog(conf)

  @transient

  protected[sql] lazy val functionRegistry: FunctionRegistry = FunctionRegistry.builtin.copy()

  @transient

  protected[sql] lazy val analyzer: Analyzer =

    new Analyzer(catalog, functionRegistry, conf) {

      override val extendedResolutionRules =

        ExtractPythonUDFs ::

        PreInsertCastAndRename ::

        (if (conf.runSQLOnFile) new ResolveDataSource(self) :: Nil else Nil)

      override val extendedCheckRules = Seq(

        datasources.PreWriteCheck(catalog)

      )

    }

  @transient

  protected[sql] lazy val optimizer: Optimizer = DefaultOptimizer

 

这些都是在第一次使用的时候才进行实例化!!!例如,这里就是需要解析SQL的时候,这些实例才会用到,如果不写语句,就用不到

 

3.object就相当于class的唯一的静态的单例,Scala没有static关键字,使用object作为全局唯一的实例,一般情况下,都会复写apply方法

 

当全局只能有一个唯一的实例的时候,我们一般不会复写apply方法

一般,想要构造很多实例的时候,都会复写apply方法

 

object RDD {

 

  // The following implicit functions were in SparkContext before 1.3 and users had to

  // `import SparkContext._` to enable them. Now we move them here to make the compiler find

  // them automatically. However, we still keep the old functions in SparkContext for backward

  // compatibility and forward to the following functions directly.

 

  implicit def rddToPairRDDFunctions[K, V](rdd: RDD[(K, V)])

    (implicit kt: ClassTag[K], vt: ClassTag[V], ord: Ordering[K] = null): PairRDDFunctions[K, V] = {

    new PairRDDFunctions(rdd)

  }

 

  implicit def rddToAsyncRDDActions[T: ClassTag](rdd: RDD[T]): AsyncRDDActions[T] = {

    new AsyncRDDActions(rdd)

  }

 

  implicit def rddToSequenceFileRDDFunctions[K, V](rdd: RDD[(K, V)])

      (implicit kt: ClassTag[K], vt: ClassTag[V],

                keyWritableFactory: WritableFactory[K],

                valueWritableFactory: WritableFactory[V])

    : SequenceFileRDDFunctions[K, V] = {

    implicit val keyConverter = keyWritableFactory.convert

    implicit val valueConverter = valueWritableFactory.convert

    new SequenceFileRDDFunctions(rdd,

      keyWritableFactory.writableClass(kt), valueWritableFactory.writableClass(vt))

  }

 

  implicit def rddToOrderedRDDFunctions[K : Ordering : ClassTag, V: ClassTag](rdd: RDD[(K, V)])

    : OrderedRDDFunctions[K, V, (K, V)] = {

    new OrderedRDDFunctions[K, V, (K, V)](rdd)

  }

 

  implicit def doubleRDDToDoubleRDDFunctions(rdd: RDD[Double]): DoubleRDDFunctions = {

    new DoubleRDDFunctions(rdd)

  }

 

  implicit def numericRDDToDoubleRDDFunctions[T](rdd: RDD[T])(implicit num: Numeric[T])

    : DoubleRDDFunctions = {

    new DoubleRDDFunctions(rdd.map(x => num.toDouble(x)))

  }

}

object中的方法是所有的实例都能使用的

class可以访问object的一切内容,即使是private的

class和object必须写在同一个文件中

 

为什么很多人写框架的时候都用伴生对象?

除了1.节省空间

2.全局

3.唯一

4.工厂方法

5.隐式转换

海油6.虽然class可以直接调用object中的成员,但是object并不是class的接口一部分,所以会把很多实验性的api放到object中

 

归纳总结:1.看类的构造的笔记

2.在类的代码中,那些不被方法封装的代码,什么时候会被执行实例化的呢?这样做的好处是什么?那是不是说类的所有成员,在类被实例化的时候,就必须实例化呢?

3.再次思考object与class的。为什么很多人写框架的时候都用伴生对象?

转载于:https://my.oschina.net/u/1449867/blog/725351

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值