本文只要是讲解关于继承的几个要点。
1. 父类一般是抽象的。
比如:
abstract class RDD[T:ClassTag](
...
) extends Serializable with Logging{
...}
或者父类是普通类,但是父类的方法是空实现, 继承的子类不需要修改任何代码就可以运行。
所有的子类都能复用父类的正常的方法(特定权限除外)。
有些可变的方法放在伴生对象里面。
问题思考:类继承到时候会不会继承类的伴生对象?
类继承是继承类本身,而不会继承伴生对象。
下面是RDD的继承关系:
所有RDD子类都可以复用父类的方法。
2. 类的抽象方法: 用def 定义,没有代码体,就是抽象方法.
3. 子类必须实现父类的抽象方法,必须用override关键字来复写该方法。
4. override既可以复写父类的方法,也可以复写父类的子类
示范例子:
- 父类:RDD,定义了一个抽象方法:getPartitions
/**
* Implemented by subclasses to return the set of partitions in this RDD. This method will only
* be called once, so it is safe to implement a time-consuming computation in it.
*
* The partitions in this array must satisfy the following property:
* `rdd.partitions.zipWithIndex.forall { case (partition, index) => partition.index == index }`
*/
protected def getPartitions: Array[Partition]
- 子类HadoopRDD,继承父类RDD
class HadoopRDD[K, V]( sc: SparkContext, broadcastedConf: Broadcast[SerializableConfiguration], initLocalJobConfFuncOpt: Option[JobConf => Unit], inputFormatClass: Class[_ <: InputFormat[K, V]], keyClass: Class[K], valueClass: Class[V], minPartitions: Int) extends RDD[(K, V)](sc, Nil) with Logging {
- 复写父类的方法:getPartitions
override def getPartitions: Array[Partition] = {
val jobConf = getJobConf()
// add the credentials here as this can be called before SparkContext initialized
SparkHadoopUtil.get.addCredentials(jobConf)
val inputFormat = getInputFormat(jobConf)
val inputSplits = inputFormat.getSplits(jobConf, minPartitions)
val array = new Array[Partition](inputSplits.size)
for (i <- 0 until inputSplits.size) {
array(i) = new HadoopPartition(id, i, inputSplits(i))
}
array
}
5.类继承的两个函数:isInstanceOf 和 asInstanceOf
父类有许多的子类,我们在构建对象的时候,使用父类类型来定义类,实例化时使用具体的子类。
使用isInstanceOf 用来判断是否是某种具体的子类;
asInstanceOf[T]用法:将对象类型强制转换为T类型,把子类转换成父类使用
所有对象自动拥有isInstanceOf和asInstanceOf这两个方法。
isInstanceOf 示例:
scala> val str="Hi"
str: String = Hi
scala> str.isInstanceOf[Int]
res3: Boolean = false
scala> str.isInstanceOf[String]
res4: Boolean = true
另外一个函数:getClass,具体找出是什么类型
override def toString: String = "%s%s[%d] at %s".format(
Option(name).map(_ + " ").getOrElse(""), getClass.getSimpleName, id, getCreationSite)
def toJavaRDD() : JavaRDD[T] = {
new JavaRDD(this)(elementClassTag)
}
}
另外一个函数:classOf,表示直接是这个类本身。
总结:
我们写继承的时候,父类约束了子类的行为,同时子类又有各自不同的实现,遵循约定,方便版本迭代。