• Scala系列-3、scala中的类和对象有哪些?


    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

    传送门:大数据系列文章目录
    在这里插入图片描述

    如何使用IDEA创建scala项目

    创建普通的scala项目

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    接下来, 即可创建包结构, 编写scala代码

    创建scala的maven项目

    1. 创建一个maven项目, 添加如下依赖
        <properties>
            <project.build.source.Encoding>UTF-8project.build.source.Encoding>
            <maven.compiler.source>1.8maven.compiler.source>
            <maven.compiler.target>1.8maven.compiler.target>
        properties>
    
        <dependencies>
            <dependency>
                <groupId>org.scala-langgroupId>
                <artifactId>scala-libraryartifactId>
                <version>2.12.11version>
            dependency>
    
        dependencies>
    
        <build>
            <sourceDirectory>src/main/scalasourceDirectory>
            <testSourceDirectory>src/test/scalatestSourceDirectory>
            <plugins>
                
                <plugin>
                    <groupId>org.scala-toolsgroupId>
                    <artifactId>maven-scala-pluginartifactId>
                    <version>2.15.2version>
                    <executions>
                        <execution>
                            <id>scala-compile-firstid>
                            <goals>
                                <goal>compilegoal>
                            goals>
                            <configuration>
                                <includes>
                                    <include>**/*.scalainclude>
                                includes>
                            configuration>
                        execution>
                        <execution>
                            <id>scala-test-compileid>
                            <goals>
                                <goal>testCompilegoal>
                            goals>
                        execution>
                    executions>
                plugin>
                
                <plugin>
                    <groupId>org.apache.maven.pluginsgroupId>
                    <artifactId>maven-compiler-pluginartifactId>
                    <version>3.7.0version>
                    <configuration>
                        <source>1.8source>
                        <target>1.8target>
                    configuration>
                plugin>
            plugins>
        build>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    1. 分别在src/main下构建scala目录(创建完文件夹是白色的,往下看)

    在这里插入图片描述

    1. 点击刷新, 将scala目录变更为source目录

    在这里插入图片描述

    刷新完的效果:
    在这里插入图片描述

    1. 编写代码进行书写即可

    scala的中普通类

    创建类也是使用class的关键词来构建的
    在这里插入图片描述
    创建普通类:

    package com.lwh
    
    /**
     * @author lwh
     * @date 2022/11/17
     * @description
     **/
    class Person {
      // 注意: 在普通类中定义成员变量的时候, 如果使用val定义, 必须要进行赋值,
      //   如果使用 var定义, 可以使用 _ 替代 , 此时赋上默认值
      //  在类中不存在 Public  scala认为 只要不带权限修饰符的都是 public , 支持的权限符号:  private || protected
      //private  val name:String  = "张三"
      val name:String  = "张三"
      var age:Int = 20
      var birthday:String = _
    
    
      def eat(name:String): Unit = {
        println(name + "饿了.....")
      }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    定义main方法: main必须放置在Object类

    package com.lwh
    
    /**
     * @author lwh
     * @date 2022/11/17
     * @description
     **/
    object MainTest {
      def main(args: Array[String]): Unit = {
        //1. 创建对象:
        val perosn1:Person = new Person()
        // 说明 如果 无参数, () 是可以省略的
        val perosn2:Person = new Person
    
        // 获取成员变量
        println(perosn1.name)
        println(perosn1.age)
        println(perosn1.birthday)
        // 设置成员变量: 只能设置被 var修饰
    
        // perosn1.name = "李四"   name是被 val修饰 编译直接报错
        perosn1.age = 30
        perosn1.birthday = "2020-10-10"
    
        println(perosn1.age)
        println(perosn1.birthday)
    
        // 调用方法:
    
        perosn1.eat("老王")
      }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    构造器:

    在scala中普通类也是存在构造方法的, 默认情况下都是会有一个无参构造方法, 在scala即使有了有参构造, 无参依然存在的

    在scala中将构造分为两大类:

    • 主构造: 直接放置在类的后面, 通过括号来执行构造器的参数即可

    • 主构造器的格式:

    class 类名(var/val 参数名:类型 = 默认值, var/val 参数名:类型 = 默认值){
        // 构造代码块
    }
    
    说明: 
    	- 主构造器的参数列表是直接定义在类名后面,添加了val/var表示直接通过主构造器定义成员变量
    	- 构造器参数列表可以指定默认值
    	- 创建实例,调用构造器可以指定字段进行初始化
    	- 整个class中除了字段定义和方法定义的代码都是构造代码
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 相关的操作

    在这里插入图片描述

    • 辅助构造器:
    • 格式:
    def this(参数名:类型, 参数名:类型) {
        // 第一行需要调用主构造器或者其他构造器
        // 构造器代码
    }
    
     - 辅助构造器的第一行代码,必须要调用主构造器或者其他辅助构造器
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    创建对象:
    	//2. 基于辅助构造器, 创建person对象
        val person3 = new Person(Array("李四"))
        println(person3.name)
    
        val person4 = new Person(List("王五"))
        println(person4.name)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    scala的单例对象

    在scala中是不支持static修饰的, 所以在普通类中创建的成员变量和成员的方法都是非静态的, 那么如果我们想构建静态的变量或者静态的方法就得需要scala提供的单例对象

    在单例对象中定义的成员变量和成员方法都是静态的, 可以直接通过类名调成员即可。
    如何构建单例对象: 与构建普通类类似的, 只是将 class修改为Object即可

    相关的操作:

    • 创建单例对象:
    package com.lwh
    
    /**
     * @author lwh
     * @date 2022/11/17
     * @description
     **/
    object Student {
      val name: String = "李四同学"
      var age: Int = 20
      val address: String = "北京"
    
      def study(name: String): Unit = {
        println(name + "说:我要努力好好学习scala")
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 使用单例对象
    package com.lwh
    
    /**
     * @author lwh
     * @date 2022/11/17
     * @description
     **/
    object StudentTest {
    
      def main(args: Array[String]): Unit = {
        println(Student.address)
        Student.study("老王")
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    单例对象一般被用于构建工具类:

    需求

    • 编写一个DateUtil工具类专门用来格式化日期时间
    • 定义一个方法,用于将日期(Date)转换为年月日字符串,例如:2030-10-05
    package com.lwh
    
    import java.text.SimpleDateFormat
    import java.util.Date
    
    /**
     * @author lwh
     * @date 2022/11/17
     * @description
     **/
    object DateUtil {
    
      private val dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    
      def format(date: Date): String = {
        dateFormat.format(date)
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    使用工具类:

    package com.lwh
    
    import java.util.Date
    
    /**
     * @author lwh
     * @date 2022/11/17
     * @description
     **/
    object DateUtilTest {
    
      def main(args: Array[String]): Unit = {
        val dateStr: String = DateUtil.format(new Date)
        println(dateStr)
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    main方法

    在java中, 执行代码必须有主入口main , 同样对应scala也是需要的, 在java中main方法是静态的方法, 在scala中如果要使用main方法, 那么必须将其定义在单例对象才可以

    object Main5 {
      def main(args:Array[String]) = {
        println("hello, scala")
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    除了直接显现使用main方法, scala还支持其通过继承一个特质来完成main方法的编写

    object 单例对象名 extends App {
        // 方法体
    }
    
    • 1
    • 2
    • 3
    package com.lwh
    
    import java.util.Date
    
    /**
     * @author lwh
     * @date 2022/11/17
     * @description
     **/
    object DateUtilAppTest extends App {
      private val dateStr: String = DateUtil.format(new Date)
      println(dateStr)
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    scala的伴生对象

    伴生对象主要解决什么问题: 一个类中既有静态的成员 又有非静态的成员, 此时在scala中采用伴生对象来解决

    使用伴生对象的操作条件:

    一个class和object具有同样的名字。这个object称为伴生对象,这个class称为伴生类

    • 伴生对象必须要和伴生类一样的名字
    • 伴生对象和伴生类在同一个scala源文件中
    • 伴生对象和伴生类可以互相访问private属性

    示例
    示例说明

    • 编写一个CustomerService类,有一个save方法,打印
    服务类名称:保存客户
    
    • 1
    • 编写一个CustomerService伴生对象,定义一个私有变量,用于保存服务类名称

    • 创建CustomerService对象,调用save方法1

    package com.lwh
    
    /**
     * @author lwh
     * @date 2022/11/17
     * @description
     **/
    //伴生类
    class CustomerService {
    
      // 在伴生类定义变量 或者 方法 都是非静态的
      def save() = {
        println(CustomerService.serviceName + "保存客户")
      }
    
    }
    
    //伴生对象
    object CustomerService {
    
      // 在伴生对象中定义的变量或者方法 都是静态的
      private val serviceName = "业务端"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 操作伴生对象
    package com.lwh
    
    /**
     * @author lwh
     * @date 2022/11/17
     * @description
     **/
    object CustomerServiceTest extends App {
    
      private val service = new CustomerService
      service.save()
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    目前存在一个问题: 伴生对象在创建的时候, 可以不使用new的方式, 但是经过测试发现, 无法实施 如何解决呢?

    解决方法: 需要在伴生对象中重写 apply的方法, 那么这样的化,就可以直接不采用new的方式来构建对象了

    package com.lwh
    
    /**
     * @author lwh
     * @date 2022/11/17
     * @description
     **/
    //伴生类
    class CustomerService {
    
      // 在伴生类定义变量 或者 方法 都是非静态的
      def save() = {
        println(CustomerService.serviceName + "保存客户")
      }
    
    }
    
    //伴生对象
    object CustomerService {
    
    //  特别注意:
    //    在重写apply方法适合, 如果空参, 一定带上 括号, IDEA快捷方式可能没有生产正确
      def apply(): CustomerService = new CustomerService()
    
      // 在伴生对象中定义的变量或者方法 都是静态的
      private val serviceName = "业务端"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    注意: 一旦在成员变量的添加 添加 private[this] 仅能在当前类中使用, 其他的类就无法使用, 即使是伴生类也不行

    scala的继承

    scala的继承基本与java的继承是一致的, 也是通过extends方式来继承, 同时也是单继承的操作, 在scala中我们既可以使用普通类来继承父类, 也可以使用单例对象来继承父类

    在继承后, 相当于将父类的所有的成员变量和成员方法都继承了过来

    相关的操作:

    • 创建一个父类
    package com.lwh
    
    /**
     * @author lwh
     * @date 2022/11/17
     * @description
     **/
    class Animal(var eatFood:String = "吃东西") {
    
      def eat(name:String) = {
        println(name + ":" + eatFood)
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 普通类继承父类
    package com.lwh
    
    /**
     * @author lwh
     * @date 2022/11/17
     * @description
     **/
    class Dog extends Animal {
    
      // override 表示是重写方法
      // super  调用父类的方法
      override def eat(name: String): Unit = {
        // 先调用父类的方法
        super.eat(name)
    
        println("狗吃骨头.....")
      }
    
      def work() = {
        println("狗能看门")
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 单例对象继承父类
    package com.lwh
    
    /**
     * @author lwh
     * @date 2022/11/17
     * @description
     **/
    object Cat extends Animal {
    
      override def eat(name: String): Unit = {
        super.eat(name)
        println("猫吃鱼......")
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 使用操作
    package com.lwh
    
    /**
     * @author lwh
     * @date 2022/11/17
     * @description
     **/
    object AnimalTest extends App {
    
      private val dog = new Dog
      dog.eat("哈士奇")
      dog.work()
    
      println(Cat.eatFood)
      Cat.eat("波斯猫")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    scala中抽象类

    scla的抽象类的操作与java是一致的

    • 定义抽象类
    package com.lwh
    
    /**
     * @author lwh
     * @date 2022/11/17
     * @description
     **/
    abstract class AnimalAbstract {
      // 抽象的成员变量
      var name:String
    
      val age:Int
    
      val address:String = "森林里"
    
      // 抽象的方法:
      def eat()
    
      def run() = {
        println("动物都是可以跑的.....")
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 实现抽象类
    package com.lwh
    
    /**
     * @author lwh
     * @date 2022/11/17
     * @description
     **/
    class Tiger extends AnimalAbstract {
      override val age: Int = 10
      override var name: String = "东北虎"
    
      override def eat(): Unit = {
        println("老虎喜欢吃肉")
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 操作下
    package com.lwh
    
    /**
     * @author lwh
     * @date 2022/11/17
     * @description
     **/
    object AnimalAbstractTest extends App {
      private val tiger = new Tiger
      tiger.run()
      tiger.eat()
    
      println(tiger.name +"  "+tiger.age +"  "+tiger.address)
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    scala中匿名内部类

    package com.lwh
    
    /**
     * @author lwh
     * @date 2022/11/17
     * @description
     **/
    object AnimalInnerTest extends App {
    
      // 假设目前使用cat的操作, 此操作只需要使用一次, 此时可以采用匿名内部类来实现, 因为如果直接构建一个实现类, 有点大材小用
    
      val cat = new AnimalAbstract {
        override var name: String = "加菲猫"
        override val age: Int = 5
    
        override def eat(): Unit = {
    
          println("猫吃鱼..........")
    
        }
    
        override def run(): Unit = {
          super.run()
    
          println("猫在追耗子的时候, 可以跑起来")
        }
      }
    
      cat.eat()
      cat.run()
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
  • 相关阅读:
    LAMP平台搭建-Centos6
    14:00面试,14:06就出来了,问的问题有点变态。。。
    python笔记记录神器 jupyter notebook
    Linux下JSON解析工具
    【iOS ARKit】RealityKit 中的物理组件
    Redis缓存(缓存预热,缓存穿透,缓存雪崩,缓存击穿)
    Java学习 --- super关键字
    简单宠物网页设计作业 静态HTML动物介绍网页作业 DW宠物网站模板下载 大学生简单野生动物网页作品代码
    医学影像坐标系问题(世界坐标系、解剖坐标系和图像坐标系)
    Ubuntu和Windows共享目录设置
  • 原文地址:https://blog.csdn.net/l848168/article/details/127897773