• Scala 基础 (五):面向对象(上篇)


    大家好,我是百思不得小赵。

    创作时间:2022 年 7 月 1 日
    博客主页: 🔍点此进入博客主页
    —— 新时代的农民工 🙊
    —— 换一种思维逻辑去看待这个世界 👀
    今天是加入CSDN的第1217天。觉得有帮助麻烦👏点赞、🍀评论、❤️收藏



    Scala 的面向对象思想和 Java 的面向对象思想和概念是一致的,但是对应的语法有所不同。

    一、Scala中的包管理

    基本语法

    package + 包名
    
    • 1

    包管理的作用

    • 区分相同名字的类
    • 当类很多时,可以很好的管理类
    • 控制访问范围

    包的命名

    • 命名规则:只能包含数字、字母、下划线、小圆点.,但不能用数字开头,也不要使用关键字。
    • 命名规范:按照如下规则命名com.公司名.项目名.业务模块名

    Scala中的两种包管理方式

    • 第一种:和 Java 的包管理风格相同,每个源文件一个包,包名用.进行分隔以表示包的层级关系,包名和源文件所在路径不要求必须一致。
    • 第二种:嵌套的风格表示层级关系{}

    举个栗子:

    package com{
      // 外层包定义单例对象
      object Outer{
        var out: String="out"
        def main(args: Array[String]): Unit = {
          println(Inner.in)
        }
      }
    
      package zhao{
        package scala{
          // 内层包中的对象
          object Inner{
            val in: String="Inner"
    
            def main(args: Array[String]): Unit = {
              println(Outer.out)
              Outer.out="ourter"
              println(Outer.out)
            }
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    嵌套风格的好处:

    • 一个源文件中可以声明多个 package
    • 子包中的类可以直接访问父包中的内容,而无需导包

    包对象

    定义包对象:

    package object 包名{
    	// 代码块
    }
    
    • 1
    • 2
    • 3
    • Scala 中可以为每个包定义一个同名的包对象,定义在包对象中的成员,作为其对应包下所有 class 和 object 的共享变量,可以被直接访问。
    • 定义当前包共享的属性和方法。
    • 必须为同一个包下面的单例对象或者类才能访问到

    导入包

    • import java.util._ 导入包 util中的所有成员
    • import java.util.{ArrayList=>JL} 引入util下的ArrayList类起别名为JL
    • import java.util.{HashSet, ArrayList} 导入util中的多个类
    • import java.util.{ArrayList =>_,_} 屏蔽类
    • new _root_.java.util.HashMap 导入包的绝对路径

    Scala中导入了三个默认的包:

    • import java.lang._
    • import scala._
    • import scala.Predef._

    二、类和对象

    定义:

    [修饰符] class 类名 {
    	// 定义属性
      [修饰符] var/val name: 类型名= _
      	// 定义方法
       [修饰符] 方法名(args: ArgsType): RetType = {
            
        }
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 在Java里面,声明类需要使用public进行修饰,类名和文件名必须保持一致。一个.java文件 有一个 public 类。
    • Scala中没有 public关键字,默认就是公共的,一个.scala 中可以写多个类。声明类时不能加public,会报错。类名不要求和文件名一致。
    • 成员需要Java Bean规范的gettersetter方法的话可以加@BeanProperty相当于自动创建,不需要显式写出。
    • 给成员属性赋初始值使用_,值类型的值0,引用则是null。定义常量的话不能用_

    访问权限

    • Java 中,访问权限分为:publicprivateprotected默认
    • Scala 中属性和方法的默认访问权限为 public,但 Scala 中无 public 关键字,不用显式声明。
    • private 为私有权限,只在类的内部和伴生对象中可用。
    • protected 为受保护权限,同类、子类可以访问,同包无法访问。
    • private[包名] 增加包访问权限,包名下的其他类也可以使用

    创建对象

    val 或者 var 对象名 [: 类型] = new 类型()
    
    • 1
    • val 修饰对象,不能改变对象的引用(内存地址),可以改变对象属性的值。
    • var 修饰对象,可以修改对象的引用和修改对象的属性值

    构造器

    Scala 构造对象也需要调用构造方法,构造器包括主构造器辅助构造器

    class 类名(形参列表) { // 主构造器
    	 // 类体
    	 def this(形参列表) { // 辅助构造器
    	 
    	 }
    	 def this(形参列表) { //辅助构造器可以有多个...
    	 
    	 }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    举个栗子:

    object Test05_Constructor {
      def main(args: Array[String]): Unit = {
        val student = new Student1()
        student.Student1()
    
        val student1 = new Student1("王五")
        val student3 = new Student1("李四",21)
    
      }
    }
    
    // 无参的主构造器
    class Student1(){
      var name: String= _
      var age: Int = _
      println("1.主构造方法被调用 ")
    
      // 声明辅助构造方法  必须直接或间接的调用主构造器
      def this(name: String){
        // 调用主构造器
        this()
        println("2.辅助构造方法 一 ")
        this.name = name
        println(s"name: $name age: $age")
      }
      def this(name: String,age: Int){
        // 间接调用主构造器
        this(name)
        println("3.辅助构造方法 二 ")
        this.age = age
        println(s"name: $name age: $age")
      }
    
      def Student1(): Unit = {
        println("一般方法被调用,不是构造方法!!")
      }
    }
    
    
    • 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

    特点说明:

    • 主构造器在类定义上,创建对象最先调用的构造器。
    • 辅助构造器用this定义,可以有多个。
    • 辅助构造方法不能直接构建对象,必须直接或者间接调用主构造方法
    • 构造器调用其他另外的构造器,要求被调用构造器必须提前声明。
    • 定义和类同名的方法,就是一个普通方法。

    主构造器参数说明

    • 主构造器函数的形参包括三种类型:未用任何修饰var 修饰、val 修饰
    • 不加参数列表相当于为空,()可以省略。
    • 未用任何修饰符修饰,这个参数就是一个局部变量
    • var 修饰参数,作为类的成员属性使用,可以修改,val 修饰参数,作为类只读属性使用,不能修改

    举个栗子:

    class Student2(var name: String,var age: Int)
    
    //主构造器 无修饰
    class Student3( name: String, age: Int){
      def printInfo(): Unit ={
        println(s"student3: name = $name, age = ${age}")
      }
    }
    
    class Student4(val name: String,val age: Int)
    
    class Student5(var name: String,var age: Int){
      var school: String = _
      def this( name: String, age: Int,school: String){
        this(name,age)
        this.school = school
      }
      
      def printInfo(): Unit ={
        println(s"student5: name = $name, age = $age,school = $school")
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    三、面向对象三大特性

    封装

    • Java中的封装:将属性私有化,提供gettersetter,用于赋值和获取值。
    • Scala中的公有属性,底层实际为private,并通过get方法obj.field()和set方法obj.field_=(value)对其进行操作。所以scala不推荐设置为private。如果需要和其他框架互操作,必须提供Java Bean规范的getter和setter的话可以加@scala.beans.BeanProperty注解。
    class Student {
      // 定义属性
      private val name: String = "lisi"
      // 把对应的符合JavaBean规范的getter和setter创建出来
      @BeanProperty 
      var age: Int = _
      var sex: String = _
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    继承

    如何定义?

    class 子类名 extends 父类名 { 类体 }
    
    • 1
    • 子类继承父类的属性和方法。
    • Scala和Java一样都是单继承的。
    • 继承的调用顺序,父类为先,子类在后。

    举个栗子:

    class Person(){
      var name: String = _
      var age: Int = _
      println("1.父类的主构造器调用")
    
      def this(name: String,age: Int){
        this()
        println("2.父类的辅助构造器被调用")
        this.name = name
        this.age = age
      }
    
      def printInfo(): Unit ={
        println(s"Person: $name  $age")
      }
    }
    
    // 默认调用Person的无参主构造器
    class Student(name: String,age: Int) extends Person(name ,age ){
      var stuNo: String = _
      println("3.子类的主构造器调用")
    
      def this(name: String,age: Int,stuNo: String){
        this(name,age)
        this.stuNo = stuNo
        println("4.子类的辅助构造器调用")
      }
    
      // 重写父类的方法
      override def printInfo(): Unit = {
        println(s"Student: $name  $age $stuNo")
      }
    }
    
    
    • 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

    多态

    • Java中的属性是静态绑定的,方法是在运行时动态绑定的。
    • Scala 中的属性和方法都是动态绑定的。
    • Scala中属性也可以被重写,使用override关键字。

    举个栗子:

    class Person {
    	 val name: String = "person"
    	 def hello(): Unit = {
    		 println("hello person")
    	 }
    }
    class Teacher extends Person {
    	 override val name: String = "teacher"
    	 override def hello(): Unit = {
    		 println("hello teacher")
    	 }
    }
    object Test {
    	 def main(args: Array[String]): Unit = {
    		 val teacher: Teacher = new Teacher()
    		 println(teacher.name)
    		 teacher.hello()
    		 
    		 val teacher1:Person = new Teacher
    		 println(teacher1.name)
    		 teacher1.hello()
    	 }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    本次分享的内容到这里就结束了,希望对大家学习Scala语言有所帮助!!!

    在这里插入图片描述

  • 相关阅读:
    什么是SSL/TLS/HTTPS,对称非对称加密+证书+CA
    电力电子转战数字IC20220728day58——uvm入门实验5
    【实用工具】frp实现内网穿透
    Nodejs基于Vue的音乐播放器的设计与实现7z140
    RabbitMQ 学习(一)-- 概念和安装
    2000-2021年三批“智慧城市”试点名单匹配数据
    HTTP状态码及其描述
    PostgreSQL 16 发布,更可靠更稳健
    JavaScript-Object.defineProperty函数
    java-php-python-ssm家电售后管理系统 演示录像 2021计算机毕业设计
  • 原文地址:https://blog.csdn.net/Zp_insist/article/details/125552750