1612 2

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

  • 1关注
  • 8粉丝

硕士生

34%

还不是VIP/贵宾

-

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

楼主
无量天尊Spark 发表于 2016-3-16 19:39:32 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

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

经管之家联合CDA

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

感谢您参与论坛问题回答

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

+2 论坛币
一、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工厂方法模式来创建。


//调用scalsayName方法,用于打印出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 inclass HiScala cannot be accessed in HiScala

              scal.name

                   ^

getset

ScalagetsetJavagetset有很大的差异。Scala中,如果给变量前定义了private,那么Scala解释器会给这个变量自动生成privategetset 法;如果变量前没有定义了private,那么解释器会给这个变量自动生成publicgetset方法,这样就可以直接访问该类的实例对象的成员变量,实际访问的是它的setget方法。


//我们重新改造上面的类,把属性name前面的private访问级别去掉。

scala> class HiScala{

    |        var name ="Spark"   //去掉了private关键字

    |        defsayName(){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级别的getset方法。


//修改name属性

scala> scal.name="Scala"

scal.name: String = Scala


//再次访问name属性, 值已经变为Scala

scala> scal.name

res5: String = Scala


自定义的getset

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


// luckPerson 类的实例

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


// luckPerson 类的实例

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[this]

private[this]至关重要的,在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


//定义 p1Person对象

scala> val p1=new Person

p1: Person = Person@14555e0a

//定义 p2Person对象

scala> val p2=new Person

p2: Person = Person@1b2abca6


//p1myName 属性值改为p1

scala> p1.update("p1")

Hi p1


//p2myName 属性值改为p2

scala> p2.update("p2")

Hi p2


//查看p1myName 属性值,此时已经改为p1

scala> p1.name

res14: String = p1


//查看p2myName 属性值,此时已经改为p2

scala> p2.name

res15: String = p2


//调用p1talk方法,传入p2对象,打印出p2myName 属性值

scala> p1.talk(p2)

hello:p2


//我们修改一下代码,看看下面代码:

scala>class Person {

     |    private[this]var name = "Flink"

     |    def update(newName : String){  

     |        name = newName

     |        println("Hi " + name)      

     |    }

     |    def talk(p:Person) = {

     |        println("hello:"+p.name)

     |    }  

     | }

<console>:15:error: valuename is not a member of Person

              println("hello:"+p.name)

                                  ^

//此时,在定义类时就报错!因为talk方法中p参数是Person类的对象,而name属性被限制为private[this],所以只能在Person类内部使用,Person类的对象无权使用。也就是说在Person类中,update方法中可以使用name,但是talk方法访问对象pname是不允许的!


// private[this]改成private之后,下面的写法就能正常定义,代码如下:

scala>class Person {

     |    private varname = "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[this] var name ="Flink"

    |     private[this] 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源码中,构造器重载非常常见。从图1的源代码中可以看出,SparkContext类重写了有很多构造器,在创建SparkContext实例对象时,传递不同的参数来调用相应的构造器。

Z{IGA%F(4Y21WF]HOST6C]7.png

图1

在Spark中,与类名放在一起的构造器为默认构造器。默认构造器可以带参数也可以不带参数,在图2所示的源代码SparkContext类中,默认构造器带有一个参数。初始化类成员的工作,都放在默认构造器中完成。在SparkContext类中,creationSiteallowMultipleContexts等变量,就是在SparkContext类的默认构造器中完成。


4YJS9@KFA34S5Q`%)BIKP3Y.png

图2


注:本学习笔记来自DT大数据梦工厂        微信公众号:DT_Spark        每晚8点YY永久直播频道:68917580

二维码

扫码加我 拉你入群

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

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

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

)D${8~Q$LZABZLVW`OU)1{6.png (21.98 KB)

)D${8~Q$LZABZLVW`OU)1{6.png

7C@R%VSM~)ACTUVVYRCJD86.png (67.91 KB)

7C@R%VSM~)ACTUVVYRCJD86.png

已有 1 人评分论坛币 收起 理由
daazx + 5 精彩帖子

总评分: 论坛币 + 5   查看全部评分

沙发
javaniceyou 发表于 2016-3-17 12:09:15
非常精彩的总结!

藤椅
无量天尊Spark 发表于 2016-6-20 17:14:55
javaniceyou 发表于 2016-3-17 12:09
非常精彩的总结!

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

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2025-12-26 12:26