Scala面向对象和模式匹配

Posted areyouready

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scala面向对象和模式匹配相关的知识,希望对你有一定的参考价值。

我们要封装数据,定义模板等操作,所以我们需要面向对象。

一、scala中的单例对象

    在scala当中,是没有static的,scala给我们提供了单例模式的实现方法。就是使用关键字object。
    static在java中修饰属性和方法,目的是直接类名.进行调用。
在scala中object是一个单例对象 在scala中object定义的成员变量和方法都是静态的 可以通过 类名. 来进行调用

1、ScalaTest

object ScalaTest {
  //定义成员变量
  val name: String = "tom"
  //定义方法public static
  def sleep(str: String): Unit = {
    println(str)
  }
}

2、ScalaMain

/**
  * 在scala中object是一个单例对象
  * 在scala中object定义的成员变量和方法都是静态的
  * 可以通过 类名. 来进行调用
  */
object ScalaMain {
  def main(args: Array[String]): Unit = {
    println(ScalaTest.name)
    ScalaTest.sleep("Tom睡得很香!")
  }
}

结果:

技术分享图片

二、scala类与构造器的使用

    scala中主构造器:
    定义在类名后面的构造器叫主构造器
    scala辅助构造器:
    定义在class类中,可以有多个辅助构造器
    
    如果主构造器中成员变量属性没有被val var修饰的话,该属性不能被访问
    相当于java中没有对外提供get方法

    如果成员属性使用var修饰的话,相当于java中对外提供了get方法和set方法
    如果成员属性使用val修饰的话,相当于java中对外只提供了get方法

1、Person1

//定义类
class Person1 {
  //定义姓名 年龄
  var name: String = _
  var age: Int = _
}

//继承App特质 可以不写main
object Test extends App{
  val p = new Person1
  p.name = "tom"
  p.age = 18
  println(p.name)
}

2、Person2

//定义主构造器
class Person2(name:String,age:Int) {

}

object Test2 extends App{
  val p = new Person2("john",19)
  println(p)
}

结果:

技术分享图片

3、Person3

class Person3(var name:String,age:Int) {
  var high:Int = _
  var weight:Int = _

  //定义辅助构造器
  def this(name:String,age:Int,high:Int){
    //注意:在辅助构造器中必须先调用主构造器
    this(name,age)
    this.high = high
  }

  //辅助构造器可以是多个
  def this(name:String,age:Int,high:Int,weight:Int){
    /*
      如果主构造器中成员变量属性没有被val var修饰的话,该属性不能被访问
      相当于java中没有对外提供get方法

      如果成员属性使用var修饰的话,相当于java中对外提供了get方法和set方法
      如果成员属性使用val修饰的话,相当于java中对外只提供了get方法
     */
    this(name,age)
    this.weight = weight
  }
}

object Test3 extends App{
  val p1 = new Person3("tom",18)
  println(p1.name)
}

结果:

技术分享图片

三、构造器的访问权限

在主构造器或者辅助构造器前加上private修饰符即可

1、Person4

/*
  类的构造器访问权限:
  private 私有
 */
//主构造器设置为私有
class Person4 private (var name:String,age:Int) {

  var high: Int = _
  private def this(name:String,age:Int,high:Int){
    this(name,age)
    this.high = high
  }
}

2、ScalaDemo

object ScalaDemo {
  def main(args: Array[String]): Unit = {
    //被private 修饰的主构造器 对外访问权限
    val p = new Person4("hh",88)
    val p2 = new Person4("ff",33,190)
    println(p.name)
    println(p2.name)
  }
}

结果:

技术分享图片

四、类的访问权限

1、Person5

/**
  * 类的前面如果加上包名,表示当前类在当前包及其子包可见,可以访问
  * [this}默认是它,表示当前包都有访问权限
  */
private[this] class Person5(var name:String,age:Int) {
  var high:Int = _

  def this(name:String,age:Int,high:Int){
    this(name,age)
    this.high = high
  }
}

2、Test

object Test {
  def main(args: Array[String]): Unit = {
    val p = new Person5("dd",18,188)
    println(p.name)
  }
}

五、伴生对象

1、Person6

class Person6(private var name:String,age:Int) {
  var high:Int = _

  def this(name:String,age:Int,high:Int){
    this(name,age)
    this.high = high
  }
}

//注意:在伴生对象中可以访问类的私有成员方法和属性
//什么是伴生对象? 单例类名和类名相同
object Person6 extends App{
  val p = new Person6("tom",18,180)
  println(p.name)
}

六、特质

相当于java中Interface接口。

1、Animal

trait Animal {
  //定义未实现的方法
  def eat(name:String)

  //定义实现的方法
  def sleep(name:String): Unit = {
    println(s"$name -> 在睡觉")
  }
}

2、Pig

object Pig extends Animal {
  override def eat(name: String): Unit = {
    println(s"$name -> 在吃饭")
  }

  override def sleep(name: String): Unit = {
    println(s"$name -> 做梦吃鸡")
  }

  def main(args: Array[String]): Unit = {
    Pig.eat("john")
    Pig.sleep("tom")
  }
}

结果:

技术分享图片

七、混入特质

1、Animal

trait Animal {
  //定义未实现的方法
  def eat(name:String)

  //定义实现的方法
  def sleep(name:String): Unit = {
    println(s"$name -> 在睡觉")
  }
}

2、Running

trait Running {
  def how(str:String): Unit = {
    println(s"$str -> 在奔跑")
  }
}

3、Dog

//混入特质
object Dog extends Animal with Running {
  override def eat(name: String): Unit = {
    println(s"$name -> 吃骨头")
  }

  override def sleep(name: String): Unit = {
    println(s"$name -> 长膘")
  }

  def main(args: Array[String]): Unit = {
    Dog.eat("小狗")
    Dog.how("金毛")
  }
}

结果:

技术分享图片

八、抽象类

1、AbstractDemo

//定义抽象类
abstract class AbstractDemo {
  def eat(food:String)

  def sleep(how:String): Unit = {
    println(s"$how -> 睡得很香")
  }
}

2、AbstractImpl

//继承抽象类可以再继承特质 但是抽象类写在前 用with连接
object AbstractImpl extends AbstractDemo with Running {
  override def eat(food: String): Unit = {
    //ctrl + i
    println(s"$food -> 吃火锅")
  }

  def main(args: Array[String]): Unit = {
    AbstractImpl.eat("tom")
    AbstractImpl.how("john")
  }
}

结果:

技术分享图片

九、模式匹配

1、MatchTest

//模式匹配
object MatchTest {
  def main(args: Array[String]): Unit = {
    def strMatch(str:String) = str match {
      case "john" => println("很帅")
      case "mary" => println("很美")
      case _ => println("你是谁?")
    }
    strMatch("john")

    def arrayMatch(arr:Any) = arr match {
      case Array(1) => println("只有一个元素的数组")
      case Array(1,2) => println("有两个元素的数组")
    }
    arrayMatch(Array(1,2))

    def tuple(tuple:Any) = tuple match {
      case (1,_) => println("元组的第一个元素为1,第二个元素任意")
      case ("tom",18) => println("这是个帅小伙")
    }
    tuple("tom",18)
  }
}

结果:

技术分享图片

十、final关键字

    如果方法不想被重写可以使用final关键字进行修饰
    用final修饰的:
    类:类不能被继承
    方法:不能被重写
    val

1、Animal

trait Animal {
  //定义姓名
  final var name:String = "tom"
  var age:Int = 18

  def eat(name: String)

  final def sleep(name: String): Unit = {
    println(s"$name -> 睡得天花乱坠")
  }
}

2、Pig

object Pig extends Animal {
  //重写eat方法
  override def eat(name: String): Unit = {
    println(s"$name -> 吃吃吃")
  }

  //这里编译报错,final修饰方法不能被重写
  override def sleep(name: String): Unit = {
    println(s"$name -> 做梦吃鸡")
  }

  def main(args: Array[String]): Unit = {
    Pig.eat("猪")
    Pig.sleep("john")
    Pig.name = "john tom"
    println(Pig.name)
  }
}

十一、type关键字

    别名设置
    使我们的程序变得更灵活
    T

1、Anl

trait Anl {
  //定义特质时可以不指定类型
  type T

  def sleep(str: T): Unit = {
    println(str)
  }
}

2、AnlTest

object AnlTest extends Anl {
  override type T = String

  def main(args: Array[String]): Unit = {
    AnlTest.sleep("睡得很香")
  }
}

结果:

技术分享图片

十二、样例类和样例对象

    1)样例类
    样例类支持模式匹配
    写法:case class 类名(属性...)
    2)样例对象
    写法:case object 类名(属性...)
    不能封装数据
    支持模式匹配
    case object Check
    match{
        case "Check" => println(Check)
    }

1、TestEat

//样例类支持模式匹配
case class Eat(food:String,drink:String)

object TestEat {
  def main(args: Array[String]): Unit = {
    val eat = new Eat("麻辣香锅","北冰洋")
    println(eat)
  }
}

2、TestEat1

//样例类支持模式匹配
case class Boy(high:Int,weight:Int)
case class Girl(high:Int,weight:Int)

object TestEat1 extends App {
  def objMatch(obj:Any) = obj match {
    case Boy(x,y) => println(s"$x $y 的男孩")
    case Girl(x,y) => println(s"$x $y 的女孩")
  }

  objMatch(Boy(180,120))
  objMatch(Girl(160,90))
}

结果:

技术分享图片

 


以上是关于Scala面向对象和模式匹配的主要内容,如果未能解决你的问题,请参考以下文章

Scala 学习 面向对象

详解 Scala 模式匹配

Scala的面向对象与函数编程

Scala学习——基础语法

Scala 学习 -- 样例类和模式匹配

Scala 学习 -- 样例类和模式匹配