Spark入门篇第2课:Scala面向对象彻底精通
Scala面向对象彻底精通
杭州-Frank
Scala中的类、object实战详解
Scala是纯面向对象语言。谈面向对象,一定要谈类,类把数据和代码封装起来。
类
跟Java一样,Scala也是用关键字class来定义类。示例如下:
scala> class HiScala{
| private var name = "Spark"
| def sayName(){println(name)}
| def getName = name
| }
defined class HiScala
以上代码,定义了一个名称为HiScala的类,默认情况下是public级别,所以public关键字可以不写。
[*]定义了一个属性name,为可变变量,访问级别为private,在类的外面不能被访问!
[*]定义一个函数:sayName
[*]定义一个函数:getName
在Scala中,变量与类中的方法是同等级的,可以直接相互赋值。
创建类实例
scala> val scal = new HiScala
scal: HiScala = HiScala@1c655221
//此时,scal就是HiScala类的一个实例。但是,在Scala中我们一边不会用new来创建类的实例,而是用apply工厂方法模式来创建。
//调用scal的sayName方法,用于打印出name成员的值。
scala> scal.sayName()
Spark
//由于sayName没有传参数,所以可以把括号去掉,这样更简洁。
scala> scal.sayName
Spark
//调用getName方法,访问name成员的值
scala> scal.getName
res2: String = Spark
//此时确实返回了name的值。
//该示例中name是私有的,所以不能直接访问scal实例的name,如下访问就出错了。
scala> scal.name
<console>:10: error: variable name in class HiScala cannot be accessed in HiScala
scal.name
^
get与set
Scala的get和set跟Java的get和set有很大的差异。
在Scala中,如果给变量前定义了private,那么Scala解释器会给这个变量自动生成private的get和set方 法;
如果变量前没有定义了private,那么解释器会给这个变量自动生成public的get和set方法,这样就可以直接访问该类的实例对象的成员变量,实际访问的是它的set和get方法。
//我们重新改造上面的类,把属性name前面的private访问级别去掉。
scala> class HiScala{
| var name = "Spark" //去掉了private关键字
| def sayName(){println(name)}
| def getName = name
| }
defined class HiScala
scala> val scal = new HiScala
scal: HiScala = HiScala@1e6d1014
//访问name属性, 值为Spark
scala> scal.name
res4: String = Spark
//此时虽然是访问属性name,但其实不是直接访问var指定的变量name,而是Scala解释器自动给name生成public级别的get和set方法。
//修改name属性
scala> scal.name="Scala"
scal.name: String = Scala
//再次访问name属性, 值已经变为Scala
scala> scal.name
res5: String = Scala
自定义的get和set
scala> class Person {
| private var myName = "Flink"
| def name = this.myName //自定义get方法
| def name_=(newName : String){//自定义set方法,注意下划线和等号之间没有空格!
| myName = newName
| println("Hi " + myName)
| }
| }
defined class Person
// luck为Person 类的实例
scala> val luck = new Person
luck: Person = Person@6a5fc7f7
//通过自定义的get方法,访问到了myName属性
scala> luck.name
res0: String = Flink
//调用自定义的set方法,修改了myName属性
scala> luck.name = "Spark"
Hi Spark
luck.name: String = Spark
//再次访问myName属性,发现属性值已经变成Spark
scala> luck.name
res2: String = Spark
//修改上面的示例,仅仅暴露属性的get方法,没有为其复写set方法。但是提供一个名为update的方法用来修改该属性的值。
scala> class Person {
| private var myName = "Flink"
| def name = this.myName//get方法
| def update(newName : String){
| myName = newName
| println("Hi " + myName)
| }
| }
defined class Person
// luck为Person 类的实例
scala> val luck = new Person
luck: Person = Person@7c469c48
//通过自定义的get方法,访问myName属性值,初始值为Flink
scala> luck.name
res4: String = Flink
//想直接通过set方法来修改myName,会提示出错,因为没有复写set方法。
scala> luck.name="Hadoop"
<console>:9: error: value name_= is not a member of Person
luck.name="Hadoop"
^
//通过额外提供的update方法来修改属性
scala> luck.update("Hadoop")
Hi Hadoop
//再次查看myName属性值,发现已经变成了Hadoop
scala> luck.name
res6: String = Hadoop
private
private至关重要的,在Spark源码中随处可见。
代表属性或方法为对象私有!在类私有的基础上更强一层的控制。
//定义一个类:Person
scala> class Person {
| private var myName = "Flink"
| def name = this.myName
| def update(newName : String){
| myName = newName
| println("Hi " + myName)
| }
| def talk(p:Person) = {
| println("hello:"+p.name)
| }
| }
defined class Person
//定义 p1为Person对象
scala> val p1=new Person
p1: Person = Person@14555e0a
//定义 p2为Person对象
scala> val p2=new Person
p2: Person = Person@1b2abca6
//把p1的myName 属性值改为p1
scala> p1.update("p1")
Hi p1
//把p2的myName 属性值改为p2
scala> p2.update("p2")
Hi p2
//查看p1的myName 属性值,此时已经改为p1
scala> p1.name
res14: String = p1
//查看p2的myName 属性值,此时已经改为p2
scala> p2.name
res15: String = p2
//调用p1的talk方法,传入p2对象,打印出p2的myName 属性值
scala> p1.talk(p2)
hello:p2
//我们修改一下代码,看看下面代码:
scala> class Person {
| private var name = "Flink"
| def update(newName : String){
| name = newName
| println("Hi " + name)
| }
| def talk(p:Person) = {
| println("hello:"+p.name)
| }
| }
<console>:15: error: value name is not a member of Person
println("hello:"+p.name)
^
//此时,在定义类时就报错!因为talk方法中p参数是Person类的对象,而name属性被限制为private,所以只能在Person类内部使用,Person类的对象无权使用。也就是说在Person类中,update方法中可以使用name,但是talk方法访问对象p的name是不允许的!
// private改成private之后,下面的写法就能正常定义,代码如下:
scala> class Person {
| private var name = "Flink"
| def update(newName : String){
| name = newName
| println("Hi " + name)
| }
| def talk(p:Person) = {
| println("hello:"+p.name)
| }
| }
defined class Person
scala>
构造器的重载
scala> class Person {
| private var name = "Flink"
| private var age = 10
| def update(newName : String){
| name = newName
| println("Hi " + name)
| }
|
|
| //重载的构造器,首先调用默认的构造器
| def this(name:String){
| this()
| this.name=name
| }
|
| //重载的构造器,调用上面已经存在的构造器
| def this(name:String, age:Int){
| this(name)
| this.age=age
| }
| }
defined class Person
在Spark源码中,构造器重载非常常见,SparkContext类重写了有很多构造器,在创建SparkContext实例对象时,传递不同的参数来调用相应的构造器。与类名放在一起的构造器为默认构造器。默认构造器可以带参数也可以不带参数。初始化类成员的工作,都放在默认构造器中完成。在SparkContext类中,creationSite、allowMultipleContexts等变量,就是在SparkContext类的默认构造器中完成。
object
定义一个类同名的object对象,里面存放静态的成员或者方法,把该object对象称之为该类的伴生对象。
在SparkContext.scala中,SparkContext object为SparkContext类的伴生对象,里面存放一系列静态的成员和静态的方法。而且,当我们第一次调用SparkContext时,SparkContext伴生对象会被执行一次,仅此一次。
下面是一个示例:
data:image/png;base64,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dUTdOTI5JYcn+FTgYWuGopNXQLQKKKKYBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVr+FdQGmeIbe7a+axCrIBOC3yEowGdoJxkjOAazp7Oe2igllTCXCb4mDAhhkg9OhyDweahoA7O21gWtzqF8fGAu9Sa1jtre7uUnZlLOpdkYoxAUbsE7WySQM4NSpqFkdV1+VfFltFb38TQgMl0BckqAJHCxHPVic87s9Qcnh6KP+GD/hztvDWtWehaFPGuvJDJJ5khS1E8dx5gBCDOwxSRnAO18Y3HGD15Z7XT10aG6XUt988xR7IQMPLQDh9/Q5PYVSoo63A9C1DV9Ek0iz0u21GO8s4tQgMdmjXkspgXIORIBGHO7kIFHYZzVnVL/VNDutIj13WDcxG5nnWC5t54oYsKohLRFEfYr5OFGAAQvevNKKOtxW0t/XX/ADO51XxbaPfWc16bXWGhjkUG1Mr7dxXAZr5JS33TgBQBk4PJp2leJdGm1Jr4NFo00SpHEZS0a7WJ8xs2UUTM2AoAYgctz0xwlFC0Gz07QZLnUdav9Q0bU5LWP+1WmuryG1nZZbfgqpk8s4x8xYSFQcgnOOKOi+MRBpMZl1OwSZnkkvFvDfPLcuSeojYRyDaFUCQ9jng15/RStpYP6/r7wooopgFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRU1pZz30rRWyb3VGfbuAJCgk4z1OAeBzUNABRRRQBteIwttHpumMkiXNlahbhW+UK7sZNu08hhvwee3QYrFoooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKANrw0q28l7qc8chtrW1kVmTg75FMaqG6K3zEjg8KeOKxaKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig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KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKVEeR1jjUu7EBVUZJPoKsrpd6+q/2WkO6780xeWrA/MDg85xgeucUAVaKCMHFbE/hTVraza6kWz8tYROVTULd38s4w2wOWxyO1HS4dbGPRRVmDT5by8t7OyZLma42hVTIwx/hO4Dkfl70AVqKdGoeVUaRYwxALtnC+5wCcfQUjqFdlDBwDgMucH355oASiiigAooooAKKms7O41C8itLWPzJ5mCogIGSfc8VDQAUUUUAFFFWbbT7m8t7q4gVGjtEEk2ZVUhSQuQCctyQOM9RQBWooooAKKKKACiiigAop/lr9nEnnJu37fKw27GPvdMY7dc+1NRGkkVEGWYgAepo8gEoqS5tprO6mtbhNk0DtHIuQdrA4IyPcVHQAUUUUAFFFTXFncWqQPPHsW4i82I5B3JkjP5qaAIaKe8arFG4mR2fO5FDZTB75GOevBNMoAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDX0maHS7SXVjKhvATFZxBvmRyOZSOwUH5fViD/CaLeaHS9EeWOVHv9QVogEbJt4c4bOOjP0x/dz/AHhWRRQAqKGdVLhASAWbOF9zjmu21i90++sIbNfE+nCO1SNLU29vcRtkLEpaU+SNwAjJHVgSOwwOIooA7rxDrttqy2AsPE4tpFnLXcsguVMsyKoW5OFbGQgCqOV4OBlsQzavbQfEBdYg8RpIkiMPtkYnDIREUUvlA3JAztDda4uigDs9K1XyPFI1C68bvL5MISS5n+1HzwQT5a4VmKBsZ3BfYUnh3UotCspre28Wx2jXF/D5zQC4GYEDFmB8vIySB2PGCME1xtFNO39fMTVz0vT7jURpd7rOkanNp9nGL2S4MNtKiXEpL+WRJs2YwUADMGUg7QCefPLSO8vdRiS286W7llGzZlnLk9RjknNV6KUUk15Dd3c9P8W6nHb65qOna7rk9zZXMscQsVt5YjbJvVmmIdNu7AbDLuLbsnjg52tazpupPokZ1ywK2lxJI+VvriOEAL5anzssVO3B246/d4zXA0UkB3174ril8U6XdL4gmxBBNvuBLPJFBK6sMRl083YSFyCGxk4zUWleIlstRvZZfEkV/evDFGmo37XqgKCS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
(图1)
上图1中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 Array的apply方法。
scala> val array=Array(1,2,3)
array: Array = Array(1, 2, 3)
scala> val array=Array.apply(1,2,3)
array: Array = Array(1, 2, 3)
以上两种定义数组的方式效果是一样的。apply方法就是当前类的伴生对象的工厂方法。延伸一下,Java水平比较高才编程人员,在构造Java对象时,一般来说不会直接new一个类,而是通过工厂方法模式来创建。而Scala语言中,天生就支持这次模式,所以在具体类对象构造时,一般都是在伴生类的伴生对象的apply方法中去实现!这样可以控制对象的生成。
Scala中的抽象类、接口实战详解
abstract
抽象类使用abstract关键字,以Spark源码RDD类为示例:
abstract class RDD(@transition private var _sc: SparkContext,@transition private var deps: Seq],) extends Serializable with Logging {...
子类去继承抽象类,跟Java一样,也是使用extends关键字。如JdbcRDD就继承了RDD抽象类,如下:
class JdbcRDD(
sc: SparkContext,
getConnection: () => Connection,
sql: String,
lowerBound: Long,
upperBound: Long,
numPartitions: Int,
mapRow: (ResultSet) => T = JdbcRDD.resultSetToObjectArray _)
extends RDD(sc, Nil) with Logging {
那么JdbcRDD就可以使用父类RDD所有它可以使用的属性和方法。
当然,子类也可以覆盖父类的属性和方法。注意,这里面有个前提,父类的属性和方法没有加final。
一个抽象类,那么里面肯定是定义了某个方法,但是没有又实现体,只有方法的说明。比如:def compute(split: Partition, context: TaskContext): Iterator
上面RDD抽象类的代码块中,compute就是RDD抽象类的一个方法,只有说明,没有实现体。
override
在上面JdbcRDD子类中,因为JdbcRDD继承了RDD抽象类,那么在JdbcRDD中一定要复写compute方法。
使用override关键字表示复写父类的该方法。除了覆盖父类的方法,也可以使用override来覆盖父类的val属性。父类在定义属性时没有给具体的值,就是抽象属性,在子类中,子类必须覆盖该属性。
trait
相当于Java的接口。在trait定义的类中可以定义抽象方法,但是又没有具体的实现。子类可以使用extends关键字来继承该父类。
以Spark源码中的RDD类为示例,RDD继承了Serializable和Logging两个父类。一个子类如果继承多个父类,那么继承的第一个父类前使用extends关键字,后面的父类使用with关键字。RDD继承的这两个父类,在定义时都使用trait关键字来定义。Scala语法中,不允许一个子类同时继承多个抽象父类,但是允许同时继承多个trait父类。
abstract class RDD(
@transient private var _sc: SparkContext,
@transient private var deps: Seq]
) extends Serializable with Logging {
下面是Serializable类的部分源码:trait Serializable extends Any with java.io.Serializable
trait的用途,更多的是作为工具方法的容器。我们把通用的功能,放在trait中。一个子类,如果需要把很多通用的功能都混进来,那么就需要继承多个trait父类,继承的第一个父类使用extends,后面的父类使用with。Spark源码Master类就是一个示例,继承了多个父类。
感谢楼主分享
页:
[1]