写点什么

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

  • 2022 年 7 月 06 日
  • 本文字数:3397 字

    阅读完需:约 11 分钟

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

一、Scala 中的包管理

基本语法


package + 包名
复制代码


包管理的作用


  • 区分相同名字的类

  • 当类很多时,可以很好的管理类

  • 控制访问范围


<hr>


包的命名


  • 命名规则:只能包含数字、字母、下划线、小圆点.,但不能用数字开头,也不要使用关键字。

  • 命名规范:按照如下规则命名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) } } } }}
复制代码


嵌套风格的好处:


  • 一个源文件中可以声明多个 package

  • 子包中的类可以直接访问父包中的内容,而无需导包


包对象


定义包对象:


package object 包名{  // 代码块}
复制代码


  • 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 = {            }} 
复制代码


  • 在 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 类型()
复制代码


  • val 修饰对象,不能改变对象的引用(内存地址),可以改变对象属性的值。

  • var 修饰对象,可以修改对象的引用和修改对象的属性值


构造器


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


class 类名(形参列表) { // 主构造器   // 类体   def this(形参列表) { // 辅助构造器      }   def this(形参列表) { //辅助构造器可以有多个...      }}
复制代码


举个栗子:


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("一般方法被调用,不是构造方法!!") }}
复制代码


特点说明:


  • 主构造器在类定义上,创建对象最先调用的构造器。

  • 辅助构造器用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") }}
复制代码

三、面向对象三大特性

封装

  • 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 = _}
复制代码

继承

如何定义?


class 子类名 extends 父类名 { 类体 }
复制代码


  • 子类继承父类的属性和方法。

  • 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") }}
复制代码

多态

  • 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()   }}
复制代码


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


发布于: 刚刚阅读数: 3
用户头像

该来的总会来,或迟或早。🎈 2022.06.13 加入

有JAVA方面3年学习经验,csdn/51cto等平台优质作者,华为云云享专家、阿里云受邀专家博主,擅长JAVA,大数据等方面的技术等。

评论

发布
暂无评论
Scala 基础 (五):面向对象(上篇)_scala_百思不得小赵_InfoQ写作社区