大数据——Scala面向对象

这篇具有很好参考价值的文章主要介绍了大数据——Scala面向对象。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Scala

面向对象

案例

  1. 定义类表示矩形(Rectangle),提供对外获取周长(girth)和面积(area)的函数,并且为这个矩形类提供一个子类表示正方形(Square)

    package com.fe.exer
    
    object ObjectDemo1 {
    
      def main(args: Array[String]): Unit = {
    
        val r = new Rectangle(5.2, 8.5)
        println(r.girth)
        println(r.area)
    
        val s = new Square(4.8)
        println(s.girth)
        println(s.area)
    
      }
    
    }
    
    // 定义一个类表示矩形
    // 矩形肯定要包含两个属性:height和width
    // 矩形定义好之后,宽和高不能发生改变
    // 定义在构造器中的常量属性,允许在创建对象的时候给值
    class Rectangle(val height: Double, val width: Double) {
    
      def girth: Double = (height + width) * 2
    
      def area: Double = height * width
    
    }
    
    // 子类:正方形
    class Square(override val width: Double) extends Rectangle(width, width)
    

抽象类和抽象方法

  1. 在Scala中,依然是通过abstract来定义抽象类。不同的地方在于,Scala中不需要使用abstract来定义抽象方法;如果一个方法在定义的时候没有函数体,那么默认就是抽象方法,不需要写abstract

  2. Scala中,抽象类中还可以定义抽象属性!!!

  3. 案例

    // 定义类表示图形Shape
    // 凡是图形,都应该有获取面积和周长的方法
    // 问题在于,不同的图形,获取面积和周长的方式是不同的
    // 那么也就意味着,需要在Shape中提供函数来获取面积和周长
    // 但是函数不需要具体的实现,而是由不同的子类来具体实现
    abstract class Shape {
    
      // 抽象属性
      // 子类继承抽象类的时候来覆盖这个属性
      // 抽象属性,就意味着子类必须有这个属性,但是父类不确定这个属性的值
      val versionUID: Long
    
      // 周长
      def girth: Double
    
      // 面积
      def area: Double
    
    }
    
  4. 抽象类中可以包含抽象方法和实体方法

  5. 子类继承抽象类,就需要覆盖其中的抽象函数

    package com.fe.abstractx
    
    object AbstractDemo1 {
    
      def main(args: Array[String]): Unit = {
    
        val s:Shape = new Circle(5)
        println(s.area)
        println(s.girth)
    
      }
    
    }
    
    // 定义类表示图形Shape
    // 凡是图形,都应该有获取面积和周长的方法
    // 问题在于,不同的图形,获取面积和周长的方式是不同的
    // 那么也就意味着,需要在Shape中提供函数来获取面积和周长
    // 但是函数不需要具体的实现,而是由不同的子类来具体实现
    abstract class Shape {
    
      // 抽象属性
      // 子类继承抽象类的时候来覆盖这个属性
      // 抽象属性,就意味着子类必须有这个属性,但是父类不确定这个属性的值
      val versionUID: Long
    
      // 周长
      def girth: Double
    
      // 面积
      def area: Double
    
    }
    
    // 圆形
    class Circle(val radius: Double) extends Shape {
    
      override val versionUID: Long = 4589512675L
    
      override def girth: Double = 2 * radius * Math.PI
    
      override def area: Double = Math.PI * radius * radius
    }
    

伴生对象(object)

  1. 在Java中,提供了static表示静态,可以通过类来调用静态属性或者静态方法,但是Scala作为一门完全面向对象的语言,认为静态是不合理的,因为静态和对象是无关的,Scala就认为static破坏了面对象对象的原则,因此Scala干脆不支持static

  2. 为了实现和static类似的效果,在Scala提供了伴生对象(object)。可以为每一个类提供一个同名的object(伴生对象),定义在伴生对象中的属性和函数,在编译之后会自动变成静态的。此时和object同名的类称之为伴生类

    // 伴生类
    class Person{}
    // 伴生对象
    object Person{}
    
  3. 伴生类和伴生对象必须同名,编译的时候才会编译到一个class文件中

    package com.fe.objectx
    
    object CalcDemo {
    
      def main(args: Array[String]): Unit = {
    
        // add可以通过类名来调用
        println(Calculator.add(5, 8))
        // test必须通过对象来调用
        val c = new Calculator
        c.test()
    
      }
    
    }
    
    object Calculator {
    
      def add(x: Int, y: Int): Int = x + y
    
    }
    
    class Calculator {
    
      def test(): Unit = println("running")
    
    }
    
  4. 案例:单例模式

    package com.fe.objectx
    
    object SingletonDemo {
    
      def main(args: Array[String]): Unit = {
    
        val a = A.getInstance
        println(a)
        val b = B.getInstance
        println(b)
    
      }
    
    }
    
    // 单例模式:全局过程中只存在唯一实例
    // 不能对外创建对象 - 构造器私有化
    class A private()
    
    // 定义伴生对象
    object A {
      // 提供本类对象,一般不会直接对外操作,所以需要私有化
      // 饿汉式
      private val a = new A
    
      // 对外提供函数来获取这个对象
      def getInstance: A = a
    }
    
    class B private()
    
    object B {
      private var b: B = _
    
      // 懒汉式
      def getInstance: B = {
        if (b == null) b = new B
        b
      }
    }
    

特质/特征(trait)

  1. 在Scala中,没有接口的说法,而是提供了类似的机制:trait

  2. 定义结构

    trait 特质名 {
        特质体
    }
    
  3. 不同于Java的地方在于,特质中可以有抽象方法和抽象属性,也可以有实体方法和实体属性

  4. 在Scala中,一个类可以混入(mixin)多个特质!所以,特质可以看作是对单继承的补充

  5. 注意:在Scala中,如果一个类本身没有继承父类,那么在混入一个特质的时候需要使用extends,混入其他特质的时候使用with

    package com.fe.traitx
    
    object TraitDemo {
    
      def main(args: Array[String]): Unit = {
    
        val s = new Student
        s.study()
        s.break()
        s.play()
    
      }
    
    }
    
    trait Study {
      // 抽象函数
      def study(): Unit
    }
    
    trait Break {
      def break(): Unit
    }
    
    trait Play {
      def play(): Unit
    }
    
    // 没有父类
    // 使用第一个特质的时候,需要使用extends关键字
    // 类混入特质之后,需要覆盖特质中的抽象方法
    // 从第二个特质开始,需要使用with来关联
    class Student extends Study with Break with Play {
    
      override def study(): Unit = println("学习中~~~")
    
      override def break(): Unit = println("休息中~~~")
    
      override def play(): Unit = println("玩耍中~~~")
    }
    
  6. 如果一个类本身已经有了父类,那么此时所有的特质只能使用with来混入

    package com.fe.traitx
    
    object TraitDemo2 {
    
      def main(args: Array[String]): Unit = {
    
        val c = new Circle(5)
        println(c.girth)
        println(c.area)
    
      }
    
    }
    
    trait Girth {
      def girth: Double
    }
    
    trait Area {
      def area: Double
    }
    
    class Shape {
      val name: String = "Shape"
    }
    
    // 如果一个类本身已经有了父类,那么此时所有的特质只能使用with来混入
    class Circle(val r: Double) extends Shape with Girth with Area {
    
      override val name: String = "Circle"
    
      override def girth: Double = 2 * Math.PI * r
    
      override def area: Double = Math.PI * r * r
    }
    
  7. 需要注意的是,在Scala中,不只是类中可以混入特质,在声明对象的时候也可以单独的混入特质,这种方式称之为动态混入

    package com.fe.traitx
    
    object TraitDemo3 {
    
      def main(args: Array[String]): Unit = {
    
        // Teacher对象 - 是否能够确定这个老师对应的科目
        // val t: Teacher = new Teacher
        // 就希望在定义对象的时候,能够顺便指定老师对应的科目
        val t1: Teacher with Chinese = new Teacher with Chinese {}
        println(t1.subject)
        val t2:Teacher with  Maths = new Teacher with Maths {}
        println(t2.subject)
    
      }
    
    }
    
    // 代表老师的类
    class Teacher
    
    // 语文课程
    trait Chinese {
      def subject: String = "语文"
    }
    
    // 数学课程
    trait Maths {
      def subject: String = "数学"
    }
    
  8. 正因为一个类中可以混入多个特质,且特质中还可以定义实体方法,所以在混入特质的时候就可能会产生冲突

    package com.fe.traitx
    
    object TraitDemo4 {
    
      def main(args: Array[String]): Unit = {
    
        val d = new D
        println(d.m(5))
        val e = new E
        println(e.m(5))
        val f = new F
        println(f.m(5))
    
      }
    }
    
    trait A {
      def m(x: Int): Int = x
    }
    
    trait B {
      def m(x: Int): Int = x * 2
    }
    
    trait C {
      def m(x: Int): Int = x * 3
    }
    
    // D混入特质A、B、C
    // 如果不指定,编译的时候会从右到左来依次寻找这个函数,只要能够找到,编译就不报错
    // 此时建议在类中重写这个函数
    class D extends A with B with C {
      override def m(x: Int): Int = x * 4
    }
    
    class E extends A with B with C {
      // 需要使用B特质的逻辑
      // 调用特质B中的m函数
      override def m(x: Int): Int = super[B].m(x)
    }
    
    // 不指定,那么会先使用C中的特质 --- 从右到左
    class F extends A with B with C {
      override def m(x: Int): Int = super.m(x)
    }
    
  9. 注意:如果混入了多个特质,且特质中有同名函数,但是函数的返回值类型不同,那么此时混入后会报错

    package com.fe.traitx
    
    object TraitDemo5 {
    
      def main(args: Array[String]): Unit = {
    
        val t = new T3
        t.m(5)
    
      }
    
    }
    
    trait T1 {
      def m(x: Int): Int = x
    }
    
    trait T2 {
      def m(x: Int): Unit = println(x)
    }
    
    class T3 extends T1 with T2 {
      // 此时返回值无论是Unit还是Int都会报错
      // override def m(x: Int): Int = x * 2
    }
    
  10. 因此,在混入特质的时候,需要检查特质中的同名同参数列表的函数的返回值类型是否一致

  11. 在Java中,接口之间是可以通过extends来基础,同样,Scala中,trait之间也可以通过extends来继承

    trait A
    trait B extends A
    
  12. 正因为特质之间允许被继承,所以存在菱形继承的问题

    package com.fe.traitx
    
    object TraitDemo6 {
    
      def main(args: Array[String]): Unit = {
    
        val s = new SubA
        println(s.m(5))
    
      }
    
    }
    
    trait SuperA {
      def m(x: Int): Int = x
    }
    
    // SubA1继承了特质SuperA
    trait SubA1 extends SuperA {
      override def m(x: Int): Int = x * 2
    }
    
    // SubA2继承了特质SuperA
    trait SubA2 extends SuperA {
      override def m(x: Int): Int = x * 3
    }
    
    // 由于SubA1和SubA2有共同的父特质,所以构成了菱形继承关系
    // 此时由于子特质SubA1和SubA2中重写了函数,没有调用父特质中的函数
    // 所以调用的时候是从右到左来寻找这个函数
    class SubA extends SubA1 with SubA2
    
  13. 菱形继承中的特质叠加

    package com.fe.traitx
    
    object TraitDemo7 {
    
      def main(args: Array[String]): Unit = {
    
        val s = new SubB
        println(s.repeat("abc"))
    
      }
    
    }
    
    trait SuperB {
    
      def repeat(str: String): String = str
    
    }
    
    trait Sub1 extends SuperB {
    
      override def repeat(str: String): String = {
        println("Sub1 running ~~~")
        super.repeat(str) * 3
      }
    
    }
    
    trait Sub2 extends SuperB {
    
      override def repeat(str: String): String = {
        println("Sub2 running ~~~")
        super.repeat(str) + str
      }
    }
    
    // 如果混入了多个特质,且混入的特质之间有公共父特质,那么此时就会形成"特质叠加"现象:
    // 从右到左,Sub2中的super不是SuperB,而是Sub1,Sub1中的super才是SuperB
    class SubB extends Sub1 with Sub2
    

其他

自身类型(self-type)
  1. 自身类型,指的是在另一个类或者特质中指定一个其他类型,那么这个类或者这个特质的子类或者子特质就需要满足指定类型

    class 类名 {
        别名:类型 =>
        函数
    }
    // 或者
    trait 特质名 {
        别名:类型 =>
        函数
    }
    
  2. 案例

    package com.fe.other
    
    object SelfTypeDemo {
    
      def main(args: Array[String]): Unit = {
    
        val r = new Register("Bob", "abc12343", "13547894512")
        r.register()
      }
    
    }
    
    // 代表用户的类
    class User(val username: String, val password: String, val phoneNumber: String)
    
    // 产生用户数据之后,需要将数据放入数据库中
    // 这个类负责和数据库来进行交互
    trait UserDao {
      // UserDao的子类或者子特质需要满足使用User类的要求
      // 凡是本类中使用到User的地方,都可以用u来表示User对象
      // u:User =>
      // 如果需要将User类和本类结合
      this: User =>
    
      def insert(): Unit = println(s"username:${this.username}, password:${this.password}, phone number:${this.phoneNumber}")
    }
    
    // 表示注册的类
    class Register(override val username: String, override val password: String, override val phoneNumber: String) extends User(username, password, phoneNumber) with UserDao {
      def register(): Unit = super.insert()
    }
    
APP类
  1. APP类是Scala中提供的一个特殊的特质。当一个类混入了APP之后,那么这个类就变成了一个快速启动类,利用这个特质,可以省略主函数的书写

    package com.fe.other
    
    object APPDemo extends App {
      
      println("Hello world")
    
    }
    
type
  1. 在Scala中,可以通过type关键字来定义数据类型,其实就是给这个类起别名

    package com.fe.other
    
    object TypeDemo {
    
      def main(args: Array[String]): Unit = {
    
        val d1: Double = 3.2
        println(d1)
        // 起别名
        // Double类型的别名就是D
        type D = Double
        val d2: D = 5.87
        println(d2)
    
      }
    
    }
    
枚举类
  1. 当一个类中有多个固定个数的实例,并且可以一一列举的时候 ,可以定义为枚举。例如:季节、星期、月份等

  2. 案例

    package com.fe.other
    
    object EnumDemo {
    
      def main(args: Array[String]): Unit = {
    
        val w = Week.MONDAY
        println(w)
        // 获取这个类中的所有的枚举常量,然后放入一个Set集合中返回
        val values: Week.ValueSet = Week.values
        for (elem <- values) {
          println(elem)
        }
    
      }
    
    }
    
    // 定义一个枚举表示星期
    // 在Scala中,没有enum关键字,而是通过object来定义枚举
    // 在Scala中,所有的枚举都有一个顶级父类:Enumeration
    object Week extends Enumeration {
    
      // val MONDAY = Value(1)
      // val MONDAY = Value("Monday")
      // 实际过程中,习惯上枚举常量都是大写的
      val MONDAY: Week.Value = Value(1, "Monday")
      val TUESDAY: Week.Value = Value(2, "Tuesday")
      val WEDNESDAY: Week.Value = Value(3, "Wednesday")
      val THURSDAY: Week.Value = Value(4, "Thursday")
      val FRIDAY: Week.Value = Value(5, "Friday")
      val SATURDAY: Week.Value = Value(6, "Saturday")
      val SUNDAY: Week.Value = Value(7, "Sunday")
    
    }
    
密封类(sealed)
  1. sealed是Scala中提供的一个特殊的关键字,可以用于修饰类或者特质。如果sealed修饰类或者特质,形成如下限制

    1. 被修饰的类或者特质的子类或者子特质必须必须和当前类处在同一个scala文件中,不能跨文件
    2. 被修饰的类或者特质参与模式匹配的时候,那么会进行检查,如果没有罗列所有的情况,那么会警告
  2. 案例

    package com.fe.other
    
    object SealedDemo {
    }
    
    sealed trait Student {
      def study(): Unit
    }
    
    class Pupil extends Student {
    
      override def study(): Unit = println("小学生学习中")
    }
    
  3. sealed增强了封装特性文章来源地址https://www.toymoban.com/news/detail-860083.html

到了这里,关于大数据——Scala面向对象的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Scala之面向对象

    目录 Scala包: 基础语法: Scala包的三大作用: 包名的命名规范: 写包的好处: 包对象: 导包说明: 类和对象: 定义类: 封装: 构造器:  主从构造器的加载机制: 继承: 基础语法: 抽象属性: 多态: Java中的多态测试 Scala测试如下: Scala的面向对象思想和Java是一致的

    2023年04月15日
    浏览(29)
  • 06-Scala面向对象

    ​ Scala是一门完全面向对象的语言,摒弃了Java中很多不是面向对象的语法。 ​ 虽然如此,但其面向对象思想和 Java的面向对象思想还是一致的 1)基本语法 Scala中基本的package包语法和 Java 完全一致 例如: 2)Scala包的三大作用(和Java一样) 区分相同名字的类 当类很多时,可

    2024年02月07日
    浏览(35)
  • 【Scala】——面向对象

      Scala 有两种包的管理风格。 第一种 Java 的包管理风格相同,每个源文件一个包(包 名和源文件所在路径不要求必须一致),包名用“.”进行分隔以表示包的层级关系,如 com.atguigu.scala。 另一种风格,通过嵌套的风格表示层级关系,一个源文件中可以声明多个 package,子

    2024年01月25日
    浏览(41)
  • Scala面向对象

    组成结构 •构造函数: 在创建对象的时候给属性赋值 •成员变量: •成员方法(函数) •局部变量 •代码块 每个类都有一个主构造器,这个构造器和类定义\\\"交织\\\"在一起类名后面的内容就是主构造器,如果参数列表为空的话,()可以省略 scala的类有且仅有一个主构造器,要想提

    2024年02月09日
    浏览(32)
  • Scala面向对象编程(高级部分)

    (1)回顾Java中的静态概念 public static 返回值类型 方法名(参数列表) {方法体} 静态属性… 说明: Java中静态方法并不是通过对象调用的,而是通过类对象调用的,所以静态操作并不是面向对象的。 (2)Scala中静态的概念-伴生对象 ①Scala语言是完全面向对象(万物皆对象)的语言

    2024年02月09日
    浏览(49)
  • 大数据开发语言Scala(一)——scala入门

    累了,基础配置不想写了,直接抄了→Scala的环境搭建 这里需要注意的是,创建新项目时,不要用默认的Class类,用Object,原因看→scala中的object为什么可以直接运行 package : 包,等同于java中的package object :,声明一个单例对象(伴生对象) main方法 :从外部可以直接

    2024年02月05日
    浏览(56)
  • 十分钟带汝入门大数据开发语言Scala

    大家好,我是百思不得小赵。 创作时间:2022 年 6 月 7 日 博客主页: 🔍点此进入博客主页 —— 新时代的农民工 🙊 —— 换一种思维逻辑去看待这个世界 👀 今天是加入CSDN的第1193天。觉得有帮助麻烦👏点赞、🍀评论、❤️收藏 Scala是一门多范式的编程语言,一种类似Ja

    2024年02月02日
    浏览(53)
  • spark底层为什么选择使用scala语言开发

    基于Scala的语言特性 集成性:Scala 是一种运行在 Java 虚拟机(JVM)上的静态类型编程语言,可以与 Java 代码无缝集成。由于 Spark 涉及到与大量 Java 生态系统的交互,例如 Hadoop、Hive 等,使用 Scala 可以方便地与这些组件进行集成和交互。 函数式编程支持:Scala 是一种面向函数

    2024年02月10日
    浏览(54)
  • 大数据开发之Scala

    scala将面向对象和函数式编程结合成一种简洁的高级语言 特点 1、scala和java一样属于jvm语言,使用时都需要先编译为class字节码文件,并且scala能够直接调用java的类库 2、scala支持两种编程范式面向对象和函数式编程 3、scala语言更加简洁高效 Scala注释使用和Java完全一样。 注释

    2024年01月23日
    浏览(37)
  • Scala大数据开发

    本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 在此,简要介绍 Scala 的基本信息和情况。 Scala 源自于英语单词scalable,表示可伸缩的、可扩展的含义。 Scala编程语言是由瑞士洛桑联邦理工学院(EPFL )的Martin Odersky于2001年开始设计并研发的。 Martin Odersky主要

    2024年04月11日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包