Scala基本语法(2)

Scala基本语法(2)

1、Scala基础语法

定义一个类
类中可以定义属性,方法,构造函数,还可以继承父类,实现接口
Scala类中默认无参构造函数就是类名后面的
//在Scala中的类中,函数如果没有参数,括号()可以省略不写
class Student{
   println("默认构造函数")
}

//定义一个Scala类(相当于测试类)
object Demo6 {
  def main(args: Array[String]): Unit = {
    //在main方法中创建对象的时候(默认调用了构造函数)
    val student = new Student
  }
}

//执行结果
默认构造函数

Process finished with exit code 0
默认构造方法是无参的,我们可以手动加入参数
//给默认构造函数加上参数(加在类名后面,放在括号里)
class Student(id:String,name:String){
   println("默认构造函数")
}

//定义一个Scala类(相当于测试类)
object Demo6 {
  def main(args: Array[String]): Unit = {
    //当默认构造函数有参数,创建对象的时候必须指定参数(否则报错)
    val student = new Student("001","李玉伟")
  }
}
scala类中方法的重载
class Student(id:String,name:String){
   println("默认构造函数")

   // Scala中的构造函数重载,定义在类中
   // 重载使用this(this相当于Student),参数可以不一致
  def this(id:String,name:String,age:Int){
    // 在重载构造函数的第一行需要调用默认构造函数
    this(id,name)//使用this,参数要和默认构造函数一致
  }

}
定义属性来接收
object Demo6 {
  def main(args: Array[String]): Unit = {
    //默认构造函数有参数,在创建对象的时候也要加上参数(此时的参数是实参)
    val student = new Student("001","李玉伟",18)
  }
}

/**
 * 定义一个类
 *类中可以定义属性,方法,构造函数,还可以继承父类,实现接口
 */
class Student(id:String,name:String){
  println("默认构造函数")

  //定义类的属性,来接收id、name
  val _id:String = id
  val _name:String = name
  /**
   * 在默认构造函数中,是没有变量age的,我们可以使用下划线来表示
   * 下划线 _ 表示“占位符”,默认表示为值null
   */
  var _age:Int = _

   // Scala中的构造函数重载,定义在类中
   // 使用this,参数可以不一致
  def this(id:String,name:String,age:Int){
    // 在重载构造函数的第一行需要调用默认构造函数
    this(id,name)//使用this,参数要和默认构造函数一致
    println("重载构造函数")
     //给_age赋值要在重载的方法中
     this._age = age
  }

}

/**
 * 执行顺序:
 * 先进入main方法,对象的参数是三个,重载构造函数参数也是三个
 * 那么先走重载构造函数,开始给id、name、age赋值;
 * 当走到this(id,name),调用的默认构造函数,则开始走默认构造函数
 * 被赋值过的id、name开始进入默认构造函数中,接着执行 println("默认构造函数")
 * 接着id、name的值分别赋给_id、_name,空值赋给_age
 * 按照顺序继续往下执行,执行 println("重载构造函数")
 * 最后将age的值赋给_age
 * 执行完毕
 */

//如果在main方法中,对象的参数是前两个,则不会走重载构造函数
重写toString()方法
object Demo6 {
  def main(args: Array[String]): Unit = {
    //默认构造函数有参数,在创建对象的时候也要加上参数(此时的参数是实参)
    val student = new Student("001","李玉伟",18)
    //直接打印对象名,调用的是toString方法
    println(student)  //Student(001, 李玉伟, 18)
  }
}

/**
 * 定义一个类
 *类中可以定义属性,方法,构造函数,还可以继承父类,实现接口
 */
class Student(id:String,name:String){
  println("默认构造函数")

  //定义类的属性,来接收id、name
  val _id:String = id
  val _name:String = name
  /**
   * 在默认构造函数中,是没有变量age的,我们可以使用下划线来表示
   * 下划线 _ 表示“占位符”,默认表示为值null
   */
  var _age:Int = _

   // Scala中的构造函数重载,定义在类中
   // 使用this,参数可以不一致
  def this(id:String,name:String,age:Int){
    // 在重载构造函数的第一行需要调用默认构造函数
    this(id,name)//使用this,参数要和默认构造函数一致
    println("重载构造函数")
     //给_age赋值要在重载的方法中
     this._age = age
  }

  //Scala中没有set()和get()方法,但可以重写方法,Ait+Insert选择toString()
  //快捷键生成的返回值$后面是没有{}的,如果调用toString()方法的时候,我们要手动加上{}
  override def toString = s"Student(${_id}, ${_name}, ${_age})"
  /*
    重写方法的全称:
    override def toString():String = {
    return s"Student($_id, $_name, $_age)"
    }
    在Scala中,重写方法没有参数,toString()的括号可以省略不写;
    在Scala中的返回值类型会自动推断,所以:String可以省略不写;
    在Scala中默认最后一行就是返回值,return可以省略不写;
    在Scala中,因为大括号里代码就一行,那么大括号也可以省略不写;
    最终代码简化为:
      override def toString = s"Student($_id, $_name, $_age)"
   */
}
可以通过对象名调用,来获取学生信息
object Demo6 {
  def main(args: Array[String]): Unit = {
    //默认构造函数有参数,在创建对象的时候也要加上参数(此时的参数是实参)
    val student = new Student("001","李玉伟",18)
    //可以通过对象名调用获取信息
    println(student._id)  //001
    println(student._name)  //李玉伟
    println(student._age) //18
  }
}

/**
 * 定义一个类
 *类中可以定义属性,方法,构造函数,还可以继承父类,实现接口
 */
class Student(id:String,name:String){
  println("默认构造函数")

  //定义类的属性,来接收id、name
  val _id:String = id
  val _name:String = name
  /**
   * 在默认构造函数中,是没有变量age的,我们可以使用下划线来表示
   * 下划线 _ 表示“占位符”,默认表示为值null
   */
  var _age:Int = _

   // Scala中的构造函数重载,定义在类中
   // 使用this,参数可以不一致
  def this(id:String,name:String,age:Int){
    // 在重载构造函数的第一行需要调用默认构造函数
    this(id,name)//使用this,参数要和默认构造函数一致
    println("重载构造函数")
     //给_age赋值要在重载的方法中
     this._age = age
  }
}
定义公共的set()和get()方法

如果属性被私有化,将无法通过对象名直接获取,必须使用公共的set()和get()方法获取,

由于在Scala中,不提供公共的set()和get()方法,那么就需要我们手动添加公共的set()和get()方法

//我们给学生id私有化为例
package com.shujia.scala

object Demo6 {
  def main(args: Array[String]): Unit = {
    //默认构造函数有参数,在创建对象的时候也要加上参数(此时的参数是实参)
    val student = new Student("001","李玉伟",18)

    //直接打印对象名,调用的是toString方法
    println(student)  //Student(001, 李玉伟, 18)

    //没有私有化的,可以通过对象名调用获取信息
    //println(student._id)  私有化的不能这样调用
    println(student._name)  //李玉伟
    println(student._age) //18

    //被私有化的属性,必须通过set()和get()方法来操作
    student.setId("008")  //将id设置为001
    println(student.getId)  //008
    //set设置之后再打印对象名
    println(student)   //Student(008, 李玉伟, 18)
  }
}

/**
 * 定义一个类
 *类中可以定义属性,方法,构造函数,还可以继承父类,实现接口
 */
class Student(id:String,name:String){
  println("默认构造函数")

  //定义类的属性,来接收id、name
  private var _id:String = id
  val _name:String = name
  /**
   * 在默认构造函数中,是没有变量age的,我们可以使用下划线来表示
   * 下划线 _ 表示“占位符”,默认表示为值null
   */
  var _age:Int = _

   // Scala中的构造函数重载,定义在类中
   // 使用this,参数可以不一致
  def this(id:String,name:String,age:Int){
    // 在重载构造函数的第一行需要调用默认构造函数
    this(id,name)//使用this,参数要和默认构造函数一致
    println("重载构造函数")
     //给_age赋值要在重载的方法中
     this._age = age
  }

  //Scala中没有set()和get()方法,但可以重写方法,Ait+Insert选择toString()
  //快捷键生成的返回值$后面是没有{}的,如果调用toString()方法的时候,我们要手动加上{}
  override def toString = s"Student(${_id}, ${_name}, ${_age})"

 //手动添加set()和get()方法,以学生id为例
  //定义set()和get()方法的时候,前面id的属性要更改为变量:var
 def setId(id: String): Unit = {
   this._id = id
  }
  def getId: String = this._id

}

2、Scala中的样例类(Scala独有的)

样例类是Scala中独有的

scala 在编译的过程中会动态给样例类增加方法(toString,hashCode,equals...)

将参数变成类的属性,不需要我们再去手动定义属性和方法

关键字:case

package com.shujia.scala

object Demo7 {
  def main(args: Array[String]): Unit = {

    //创建样例类对象
    val user = new User("001","伟爷")
    println(user) //User(001,伟爷)
    //获取属性的值
    println(user.id)  //001
    println(user.name)  //伟爷
  }
}

//创建样例类,关键词case
case class User(id:String,name:String)
样例类修改属性的值
package com.shujia.scala

object Demo7 {
  def main(args: Array[String]): Unit = {

    //创建样例类对象
    val user = new User("001","伟爷")
    println(user) //User(001,伟爷)

    // 修改属性的值
    // 样例类默认属性是常量,在修改属性的值的时候,需要将常量改为变量var
    user.name = "李玉伟"
    println(user)//User(001,李玉伟)

  }
}

//创建样例类,关键词case
case class User(id:String,var name:String) //修改属性的值的时候,需要将常量改为变量var

样例类创建对象的另一种方式

package com.shujia.scala

object Demo7 {
  def main(args: Array[String]): Unit = {

    //创建样例类对象
    val user = new User("001","伟爷")
    println(user) //User(001,伟爷)

    //创建样例类对象的另一种方式
    val use2: User = User("002", "李玉伟")
    println(use2) //User(002,李玉伟)
  }
}

//创建样例类,关键词case
case class User(id:String,name:String)

3、Scala中类的继承

类的继承:会继承父类的属性和方法

如果父类属性被私有化,将无法继承

package com.shujia.scala

object Demo8 {
  def main(args: Array[String]): Unit = {

    //创建子类的对象
    val b = new B("001", "李玉伟", 18)
    //调用父类中的属性
    println(b._id)  //001
    println(b._name)//李玉伟
  }
}

//创建一个父类
class A(id:String,name:String){
      val _id:String = id
      val _name:String = name
}

//创建一个子类继承父类
class B(id:String,name:String,age:Int) extends A(id,name){
}
打印子类对象的对象名,会调用toString方法,如果子类没有就会调父类中的toString方法
package com.shujia.scala

object Demo8 {
  def main(args: Array[String]): Unit = {

    //创建子类的对象
    val b = new B("001", "李玉伟", 18)
    //打印对象的对象名,会调用toString方法,如果子类没有就会调父类中的toString方法
    println(b)  //A(001, 李玉伟)
  }
}

//创建一个父类
class A(id:String,name:String){
      val _id:String = id
      val _name:String = name

  //重写toString方法
  override def toString = s"A(${_id}, ${_name})"
}

//创建一个子类继承父类
class B(id:String,name:String,age:Int) extends A(id,name){
}
继承父类的toString()方法
package com.shujia.scala

object Demo8 {
  def main(args: Array[String]): Unit = {

    //创建子类的对象
    val b = new B("001", "李玉伟", 18)
    //打印对象的变量名,会调用子类的toString方法,如果子类没有就会调父类中的toString方法
    println(b)  //B(001, 李玉伟,18)
  }
}

//创建一个父类
class A(id:String,name:String){
      val _id:String = id
      val _name:String = name

  //重写toString方法
  override def toString = s"A(${_id}, ${_name})"
}

//创建一个子类继承父类
class B(id:String,name:String,age:Int) extends A(id,name){
    //定义子类自己的属性
  val _age:Int = age
  //重写父类的toString方法(需要我们手动编写)
  override def toString = s"B(${_id}, ${_name},${_age})"

}

4、Scala中的特征

在Java中叫做接口,在Scala中叫做特征

Scala中的特征类似于Java中的接口

关键字:trait

package com.shujia.scala

object Demo9 {
  def main(args: Array[String]): Unit = {
    //创建具体的狗类的对象
    val dog = new Dog()
    dog.print()//狗叫     调用自身的方法
    dog.cry() //动物叫    也可以调用特征中的方法

    //父类的引用指向子类的对象,只能调用父类中的方法
    val cat:Cry = new Cat()
    cat.cry()//动物叫
    cat.print()//猫叫
    //cat.grab 自身的方法无法调取
  }
}

//猫和狗都有同样的特征:叫
trait Cry{
  //定义叫的抽象方法
  def print()
  //定义一个普通方法
  def cry():Unit = {
    println("动物叫")
  }
}

/**
 * 在Scala中,特征内可以写抽象方法,还可以写普通方法
 * 在Scala中没有实现接口这一说,只能使用继承
 */
//定义一个类,继承特征
class Dog() extends Cry {
  //实现特征中的抽象方法
  override def print(): Unit = {
    println("狗叫")
  }
  //定义一个方法
  def eat():Unit = {
    println("狗吃屎")
  }
}

//定义一个类,继承特征
class Cat() extends Cry {
  //实现特征中的抽象方法
  override def print(): Unit = {
    println("猫叫")
  }
  //定义一个方法
  def grab():Unit = {
    println("猫抓老鼠")
  }
}

5、Scala中的对象:object

package com.shujia.scala

object Demo10 {
  def main(args: Array[String]): Unit = {
    //Test是一个对象,不需要new,内部的方法可以直接调用
    Test.print()//test
  }
}
/**
 * object:是Scala的对象,是这个类的一个单例对象
 * 如下:
 * 如果Test是一个类,需要在main方法中创建类的对象才能调用内部的方法
 * 如果Test是一个对象,main方法中,内部的方法可以直接调用
 * object 相当于java中的 static
 */

//创建一个对象
object Test{
  def print():Unit = {
    println("test")
  }
}
object的一个特殊的方法:apply()

通过对象名加()就表示调用了apply()方法

package com.shujia.scala

object Demo10 {
  def main(args: Array[String]): Unit = {
    //Test是一个对象,不需要new,内部的方法可以直接调用
    Test.print()//test

    //调用apply()方法
    Test.apply()  //apply
    Test()  //apply

    //调用有参数的apply()方法
    Test("伟爷")//伟爷
  }
}

//创建一个对象
object Test{
  def print():Unit = {
    println("test")
  }
  //object对象中的一个特殊的方法:apply()
  def apply():Unit = {
    println("apply")
  }
  //定义一个有参数的apply()方法
  def apply(name:String):Unit = {
    println(name)
  }
}

6、伴生对象(证明样例类的原理,无实际意义)

package com.shujia.scala

object Demo11 {
  def main(args: Array[String]): Unit = {
    //创建类的对象
    val s1 = new Score("001", 98)
    println(s1._id)//001
    println(s1._sco)//98
  }
}

//创建一个类
class Score(id:String,sco:Int){
  //初始化属性
  val _id:String =id
  val _sco:Int = sco
  //重写toString方法
  override def toString = s"Score(${_id}, ${_sco})"
}

在main方法中,如果想要像样例类那样,直接根据类名传参创建对象,该怎么做?

使用伴生对象

package com.shujia.scala

object Demo11 {
  def main(args: Array[String]): Unit = {
    //创建类的对象
    val s1 = new Score("001", 98)
    println(s1) //Score(001, 98)
    println(s1._id)//001
    println(s1._sco)//98
    /**
     * 在main方法中,如果想要像样例类那样,直接根据类名传参创建对象(省略了new),该怎么做?
     * 这时候就引用了 伴生对象,使用 伴生对象和 apply()方法 结合,可以实现
     */
    val s2: Unit = Score("002", 100)
    println(s2) //打印的是 ()
    //println(s2.)
  }
}

//创建一个类
class Score(id:String,sco:Int){
  //初始化属性
  val _id:String =id
  val _sco:Int = sco
  //重写toString方法
  override def toString = s"Score(${_id}, ${_sco})"
}

//创建伴生对象
object Score{
  //创建上面类的对象,并作为返回值,放在apply方法中
  def apply(id:String,sco:Int):Unit = new Score(id,sco)
}

伴生对象无实际意义,无法调取类中的方法和属性,

只是为了证明样例类的底层调用的是apply()方法

7、Scala中的类型转换

package com.shujia.scala

object Demo12 {
  def main(args: Array[String]): Unit = {
    //定义一个字符串常量
    val s :String = "666"

    //String类型转换为Int类型
    //1、利用Java的方式
    val i1: Int = Integer.parseInt(s)
    println(i1)//666
    //2、Scala中的方式
    val i2: Int = s.toInt
    println(i2)//666

    //若类型不匹配,会报错:类型转换异常
    //val i3: Int = "李玉伟".toInt

    val j: Int = 1000
    //Int类型转换为Double类型
    println(j.toDouble)//1000.0
  }
}

8、异常处理

scala中的异常会自动抛出,可以不处理

package com.shujia.scala

object Demo13 {
  def main(args: Array[String]): Unit = {
    //异常处理
    try {
      val i: Int = "李玉伟".toInt
      println(i)
    } catch {
      case e:Exception => {
        println("这是Exception异常")  //case匹配,如果是Exception异常,打印大括号内的东西
      }
      case e:RuntimeException => {
        println("这是RuntimeException异常")
      }
    }

  }
}
posted @ 2022-03-05 14:47  阿伟宝座  阅读(102)  评论(0)    收藏  举报