zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Scala深入学习之面向对象学习(一)

scala学习 深入 面向对象
2023-09-27 14:25:56 时间
一、封装

定义一个类 实际上就是把一类事物的共有的属性和行为提取出来 形成一个物理模型 模板 。这种研究问题的方法称为抽象。


面向对象编程有三大特征:封装、继承和多态。


封装 encapsulation 就是把抽象出的数据和对数据的操作封装在一起 数据被保护在内部 程序的其它部分只有通过被授权的操作 成员方法 才能对数据进行操作。

封装的理解和好处


隐藏实现细节 可以对数据进行验证 保证安全合理

如何体现封装


对类中的属性进行封装

通过成员方法 包实现封装

封装的实现步骤将属性进行私有化提供一一个公 共的set方法 用于对属性判断并赋值

提供一个公共的get方法 用于获取属性的值


封装的示例代码

package encapsulationDemo

 * author : 蔡政洁

 * email :caizhengjie888 icloud.com

 * date : 2020/9/17

 * time : 10:57 下午

 * scala的类的定义

 * Scala和Java一样 都是用关键字class来进行声明

 * 在Scala中刚刚创建的这个类 其实就模拟了Java中的javabean 当然在Scala中有一个专门的类结构来表示Java中的bean -- case class 样例类 

 * 会自动的给其中的字段提供getter和setter方法

object ClassOps {

 def main(args: Array[String]): Unit {

 // 创建类的对象

 val person:Person new Person()

 person.setName( 张三 )

 person.setAge(14)

 println(s name:${person.getName},age:${person.getAge} )

// 定义了一个Scala的类 类名为Person

class Person{

 // 定义了一个String类型的成员name 并赋予默认值 默认值为null

 private var name:String _

 // 定义了一个Int类型的成员age 并赋予默认值 默认值为0

 private var age:Int _

 // 提供getter和setter来处理

 def setName(n:String):Unit {

 name n

 // 单行函数

 def getName name

 def setAge(a:Int):Unit {

 if (a 1 || a 150){

 throw new RuntimeException( 年龄不能小于1 或者不能超过150岁 )

 age a

 def getAge age

运行结果

name:张三,age:14


二、类的构造

1、和Java或C 一样 Scala可以有任意多的构造器。不过Scala类有一个构造器比其他所有构造器都更为重要 它就是主构造器 primary constructor 。除了主构造器之外 类还可以有任意多的辅助构造器 auxiliary constructor


2、辅助构造器的名称为this。在Java或C 中 构造器的名称和类名相同 当你修改类名时就不那么方便了。每一个辅助构造器都必须以一个对先前已定义的其他辅助构造器或主构造器的调用开始


3、scala中构造器的定义

1 Scala中和类名相同的方法并不是构造器

2 通过分析 Scala的其中一个构造器就在类名后面 因为是无参的 所以默认省略 也是参数列表

问题分析


1、该构造器的方法体呢

通过代码验证 说明Scala类的构造器的函数体和类的定义交织在了一起

2、可不可以拥有其他的构造器

Scala不能用类名做构造器 而是使用this关键字来代替这里的类名

3 由2的内容 我们可以归纳如下


Scala的构造器有两种 一种在类名后面定义的 一种在类中使用关键字来定义的

第一种的构造器 被称为Scala类的主构造器

第二种的构造器 被称为Scala类的辅助构造器

Scala中的辅助构造器的第一句话 必须要调用本类的主构造器或者其他辅助构造器

类的构造示例代码

package encapsulationDemo

 * author : 蔡政洁

 * email :caizhengjie888 icloud.com

 * date : 2020/9/18

 * time : 1:37 下午

 * scala中构造器的定义

 * 1、Scala中和类名相同的方法并不是构造器

 * 2、通过分析 Scala的其中一个构造器就在类名后面 因为是无参的 所以默认省略 也是参数列表

 * 问题分析 

 * 1、该构造器的方法体呢 

 * 通过代码验证 说明Scala类的构造器的函数体和类的定义交织在了一起

 * 2、可不可以拥有其他的构造器 

 * Scala不能用类名做构造器 而是使用this关键字来代替这里的类名

 * 3、由2的内容 我们可以归纳如下

 * 1、Scala的构造器有两种 一种在类名后面定义的 一种在类中使用关键字来定义的

 * 第一种的构造器 被称为Scala类的主构造器

 * 第二种的构造器 被称为Scala类的辅助构造器

 * 2、Scala中的辅助构造器的第一句话 必须要调用本类的主构造器或者其他辅助构造器

object ConstructorOps {

 def main(args: Array[String]): Unit {

 val teacher:Teacher new Teacher()

 teacher.show()

 teacher.Teacher()

 println( 这里使用Scala的有参数的构造器 )

 val teacher1 new Teacher( 李四 ,20)

 teacher1.show()

 println( 这里使用Scala的有参主构造器 )

 val teacher2 new Teacher1( 张三 ,23)

 teacher2.show()

// Scala中有参主构造器

class Teacher1/*private主构造器的私有化*/ (name:String,age:Int){

 def show():Unit {

 println(s name:${name},age:${age} )

class Teacher(/*这是Scala的默认的类的无参构造器 而且这还是最特殊的一个构造器*/){

 private var name:String _

 private var age:Int _

 println( 如果这是类的构造器的话 该语句将会被调用 )

 // Scala中Teacher()不是构造器 就是普通方法

 def Teacher():Unit {

 println( 如果这是类的构造器的话 该方法将会被调用 )

 def this(name:String,age:Int){

 this()

 this.name name

 this.age age

 println( 如果这是类的有参构造器的话 该语句将会被调用 )

 def show():Unit {

 println(s name:${name},age:${age} )

运行结果

如果这是类的构造器的话 该语句将会被调用 

name:null,age:0

如果这是类的构造器的话 该方法将会被调用 

 这里使用Scala的有参数的构造器 

如果这是类的构造器的话 该语句将会被调用 

如果这是类的有参构造器的话 该语句将会被调用

name:李四,age:20

 这里使用Scala的有参主构造器 

name:张三,age:23


三、内部类

示例代码

package encapsulationDemo

 * author : 蔡政洁

 * email :caizhengjie888 icloud.com

 * date : 2020/9/18

 * time : 2:30 下午

 * Scala内部类

object InnerClassOps {

 def main(args: Array[String]): Unit {

 val outer:Outer new Outer()

 // 创建Scala的内部类对象

 val inner new outer.Inner()

 inner.show()

class Outer { o // 此时o就是本类对象的引用

 val x 5

 class Inner{ i // 此时就是本类对象的引用

 val x 6

 def show(): Unit {

 val x 7

 println( x x)

 println( x this.x)

 println( x i.x)

 println( x Outer.this.x)

 println( x o.x)

运行结果

x 7


四、Object对象

scala中的Object结构

在Java的一个类中 既可以拥有static静态 也可以拥有非static 同时Java中的主函数必须是static。但是Scala中的class只能提供非static的成员 所以要想Scala也能提供static的成员 就必须使用object结构。Scala的object中定义的成员都是类似于Java中的静态成员 也就是直接可以通过类名.调用 无需创建对象。


object的主要作用


给Scala类提供程序运行入口 静态的main函数

给Scala类也能够提供静态成员–Scala类的伴生对象来实现

object ObjectOps {

 def main(args: Array[String]): Unit {

 println( hello world )


五、伴生对象

scala中的伴生对象 scala中把同一个源文件中相同名称的object结构称为class结构的伴生对象 反过来把这个class结构称之为object结构的伴生类。


class CompanionClass 是object CompanionClass的伴生类

object CompanionClass 是 class CompanionClass的伴生对象

构建伴生类/伴生对象成立的几个前提

1、二者必须在同一个.class源文件

2、二者名称必须相同


伴生类/伴生对象的特点

1、伴生对象可以访问伴生类中非私有和私有的成员

2、通常我们需要在伴生对象中覆盖一个方法–apply 用于构造伴生类的实例

比如,Array,ArrayBuffer,Map 等等都是通过伴生对象来创建对象 该构造的时候其实就是调用了伴生对象apply方法。该apply方法的特点


返回值类型是本类引用

参数列表对应伴生类的构造器的参数列表

3、有了伴生对象 同时覆盖了apply方法 便给伴生类提供了一个简化的对象构造器方式 即省略了new关键字


代码示例

package encapsulationDemo

 * author : 蔡政洁

 * email :caizhengjie888 icloud.com

 * date : 2020/9/21

 * time : 9:48 上午

 * scala中的伴生对象

 * scala中把同一个源文件中相同名称的object结构称为class结构的伴生对象 反过来把这个class结构称之为

 * object结构的伴生类。

 * class CompanionClass 是object CompanionClass的伴生类

 * object CompanionClass 是 class CompanionClass的伴生对象

 * 构建伴生类/伴生对象成立的几个前提

 * 1、二者必须在同一个.class源文件

 * 2、二者名称必须相同

 * 伴生类/伴生对象的特点

 * 1、伴生对象可以访问伴生类中非私有和私有的成员

 * 2、通常我们需要在伴生对象中覆盖一个方法--apply 用于构造伴生类的实例

 * 比如,Array,ArrayBuffer,Map 等等都是通过伴生对象来创建对象 该构造的时候其实就是调用了伴生对象apply方法

 * 该apply方法的特点 

 * 1、返回值类型是本类引用

 * 2、参数列表对应伴生类的构造器的参数列表

 * 3、有了伴生对象 同时覆盖了apply方法 便给伴生类提供了一个简化的对象构造器方式 即省略了new关键字

object CompanionObjectOps {

 def main(args: Array[String]): Unit {

 val cc new CompanionClass()

 println( ------------------- )

 val cc1 CompanionClass

 println( ------------------- )

 val cc2 CompanionClass( 张三 ,13)

class CompanionClass{

 private val x 6

 def this(name:String,age:Int){

 this()

 println( name: name)

 println( age: age)

object CompanionClass{

 val cc new CompanionClass

 println(cc.x)

 def apply(): CompanionClass {

 new CompanionClass()

 def apply(name:String,age:Int): CompanionClass {

 new CompanionClass(name,age)

运行结果

-------------------

-------------------

name:张三

age:13


六、类的继承

Scala扩展类的方式和Java一样 使用extends关键字:


继承就代表 子类可以从父类继承父类的field和method 然后子类可以在自己内部放入父类所没有 子类特有的field和method 使用继承可以有效复用代码。


不可扩展关键字

子类可以覆盖父类的field和method 但是如果父类用final修饰 field和method用finaI修饰 则该类是无法被扩展的 field和method是无法被覆盖的。


scala 中的继承/扩展


使用关键字extends来产生这种继承或者扩展关系

子类可以继承父类中所有非私有的成员

子类不能覆盖父类中被final所修饰的成员

Scala中子类覆盖父类的方法时 必须要添加关键字override进行修饰 以标识要对父类方法进行覆盖 否则认为子类重新定义一个同名方法 这就会造成方法同名 会报错

子类要想访问父类的成员时候 就需要使用super关键字来完成

示例代码

package extendsDemo

 * author : 蔡政洁

 * email :caizhengjie888 icloud.com

 * date : 2020/9/22

 * time : 2:53 下午

 * scala 中的继承/扩展

 * 1、使用关键字extends来产生这种继承或者扩展关系

 * 2、子类可以继承父类中所有非私有的成员

 * 3、子类不能覆盖父类中被final所修饰的成员

 * 4、Scala中子类覆盖父类的方法时 必须要添加关键字override进行修饰 以标识要对父类方法进行覆盖 

 * 否则认为子类重新定义一个同名方法 这就会造成方法同名 会报错

 * 5、子类要想访问父类的成员时候 就需要使用super关键字来完成

object ExtendsOps1 {

 def main(args: Array[String]): Unit {

 val stu new Student( 张三 )

 stu.show()

// 父类

class Person{

 var name:String _

 var age:Int 15

 def this(name:String,age:Int){

 this()

 this.name name

 this.age age

 def show(): Unit {

 println(s name:${name},age:${age} )

 def setName(name:String) this.name name

// 子类

class Student extends Person{

 def this(name:String){

 this()

 // 完成name的赋值

 // this.name name

 super.setName(name)

 override def show(): Unit {

 // 调用父类的show方法

 super.show()

 println( ------student-----show------ )

运行结果

name:张三,age:15

------student-----show------

Scala学习三-面向对象 前面我们已经学习了特质类似接口,其可以被继承,同时如果需要继承多个特质的话,则需要使用extends…with…进行继承。其类似java中的接口和抽象方法的结合体,但又比java中的其要强大,因为其可以定义抽象字段和普通字段、抽象方法和普通方法。而在java中接口中可以定义常量,不能定义变量。同时特质还可以继承class类,而在java中接口通常是用来实现的。 Object继承trait
Scala学习一 Scala中的方法与函数: 方法是属于类或者对象的,在运行时,它是加载到JVM的方法区中,而函数则是加载到JVM的堆内存中,同时可以将函数对象赋值给一个变量。函数是一个对象,继承自FunctionN,函数对象有apply、curried、toSting、tupled这些方法,而方法则没有。这是scala与java不同的地方。
终于,为了大数据分析我还是开启了Scala学习之路 要问当下最热门的IT技术,大数据可占一席之地;要问当下最网红的IT岗位,数据分析师也必将榜上有名。二者结合,自然就是大数据分析师。所谓大数据分析,个人理解就是在传统数据分析思维和技能的基础上,加持大数据工具,而Spark作为一个优秀的分布式计算框架,自然可作为大数据分析的必备技能。进一步地,虽然Spark提供了4种主流语言,但Scala作为Spark的原生开发语言,仍不失为应用Spark开发的首选。 基于以上考虑,我终于还是入坑了Scala的学习之旅——尽管Scala实际上属于一门小众语言,小众到似乎除了Spark甚至没什么用武之地