scala笔记第四天 (类)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/TylerPY/article/details/102613963

革命尚未完成,同志仍需努力!!!1

定义简单类

package com.scala3.clas

class HelloWord_10_1_1 {
  private var name = "len"
  def sayHello(): Unit ={
    println("Hello " + name)
  }
  def getName = name
}

实现类

object TextClas extends App {
  //--------10 -----1---定义一个简单的类
   val a = new HelloWord_10_1_1
  a.sayHello
  print(a.getName)  //如果定义方法时不带括号,则调用方法时也不能带括号

  //错误写法
  print(a.getName())
  //Error:(7, 12) not enough arguments for method apply: (index: Int)Char in class StringOps.
//Unspecified value parameter index.
  //a.getName()
}

注:
函数:类外边定义的def
方法:类内定义的def
注意:如果定时的def后的方法名没加(),在调用的时候就不能加();定义def的方法名加了()调用时,可以加()也可以不加()

getter与setter

  1. 定义不带private的var field,此时scala生成的面向JVM的类时,会定义为private的name字段,并提供public的getter和setter方法
  2. 而如果使用private修饰field,则生成的getter和setter也是private的
  3. 如果定义val field,则只会生成getter方法
  4. 如果不希望生成setter和getter方法,则将field声明为private[this]
class Student_10_3_1 {
  var name = "leo"
  //private var name = "leo"  //
}

object TextClas extends App {
  //--------10 -----3---getter与setter
  val a = new Student_10_3_1
  println(a.name)   //leo
  a.name = "leao"    //类中定义是val,则会报错
  print(a.name)    //leao

自定义getter与setter

  1. 如果只是希望拥有简单的getter和setter方法,那么就按照scala提供的语法规则,根据需求为field选择合适的修饰符就好:var、val、private、private[this]
  2. 但是如果希望能够自己对getter与setter进行控制,则可以自定义getter与setter方法
  3. 自定义setter方法的时候一定要注意scala的语法限制,签名、=、参数间不能有空格
class Student_10_3_2 {
  private var myName = "leo"
  def name = "you name is  " + myName

  //setter方法
  def name_=(newValue : String): Unit ={  //注意:name_与=之间没有空格
    println("you cannot edit your name!")
  }
}

object TextClas extends App {

  //--------10 -----3---2----自定义getter与setter
  val a = new Student_10_3_2
  println(a.name)    //you name is  leo
  a.name = "leo2"
  println(a.name)  //you cannot edit your name!
                  //you name is  leo
}

如果你不希望field有setter方法,则可以定义为val,但是此时就再也不能更改field的值了。但是如果希望能够仅仅暴露出一个getter方法,并且还能通过某些方法更改field的值,那么需要综合使用private以及自定义getter方法。 此时,由于field是private的,所以setter和getter都是private,对外界没有暴露;自己可以实现修改field值的方法;自己可以覆盖getter方法

仅暴露field的getter方法

如果你不希望field有setter方法,则可以定义为val,但是此时就再也不能更改field的值了。但是如果希望能够仅仅暴露出一个getter方法,并且还能通过某些方法更改field的值,那么需要综合使用private以及自定义getter方法。 此时,由于field是private的,所以setter和getter都是private,对外界没有暴露;自己可以实现修改field值的方法;自己可以覆盖getter方法

class Student_10_5_1 {
  private var myName = "tyler"

  def updateName(newName:String): Unit ={
    if (newName == "tyler1"){
      myName=newName
    }else{
      println("not accept this new name")
    }
  }
  def name = "you name is " + myName
}

object TextClas extends App {
  //--------10 -----5---1---- 仅暴露field的getter方法
  val a = new Student_10_5_1

  println(a.name)  //you name is tyler
  a.updateName("tyler1")
  println(a.name)   //you name is tyler1

}

private[this]的使用

如果将field使用private来修饰,那么代表这个field是类私有的,在类的方法中,可以直接访问类的其他对象的private field。这种情况下,如果不希望field被其他对象访问到,那么可以使用private[this],意味着对象私有的field,只有本对象内可以访问到

class Student_10_6_1 {
  private var myAge = 0
  def age_=(newAge:Int): Unit ={
    if(newAge > 0){
      myAge = newAge
    }else{
      println("illehal age!")
    }
  }
  def age = myAge
  def olders(s:Student_10_6_1): Unit ={
    myAge > s.myAge
  }
}

class Student_10_6_2 {
  private[this] var myAge = 0
  def age_=(newValue:Int): Unit ={
    if(newValue > 0) {
      myAge = newValue
    }else{
      println("Student_10_6_2   age  ")
    }
  }
  def age = myAge
  def older(s:Student_10_6_2)={
    myAge > s.myAge
    //Error:(14, 15) value myAge is not a member of com.scala3.clas.Student_10_6_2
   // myAge > s.myAge
  // 因为在olders方法中,调用了s.myage,但是,之前定义个字段是private[this],只有当前类可用
  }
}

object TextClas extends App {
  //--------10 -----5---1----private[this]的使用
  val a1 = new Student_10_6_1
  println(a1.age)  //0
  a1.age = 16
  println(a1.age)   //16
  a1.age_=(23)
  println(a1.age)   //23
  val a2 = new Student_10_6_2
  a2.age = 45
  println(a2.age)   //45
  //a1.older(a2)
}

getter和setter方法

Scalagettersetter方法的命名与java是不同的,是fieldfield_=的方式。如果要让scala自动生成java风格的gettersetter方法,只要给field添加@BeanProperty注解即可。此时会生成4个方法,name: Stringname_=(newValue: String): UnitgetName(): StringsetName(newValue: String): Unit

例:

package com.scala3.clas

import scala.beans.BeanProperty


class Student_10_7_1 {
  @BeanProperty var name :String = _
}

object TextClas extends App {
  //--------10 -----7--- Java风格的getter和setter方法
  val s = new Student_10_7_1
  s.setName("leo")
  println(s.getName())  //leo
}

也可以在构造函数处加这个注解

import scala.beans.BeanProperty

class Student_10_7_2(@BeanProperty var name:String) {

}

object TextClas extends App {
//--------10 -----7---2
  val a = new Student_10_7_2("len")
  println(a.getName)   //len
  a.setName("hah")     //hah
  print((a.getName))
}

辅助constructor (构造函数)

Scala中,可以给类定义多个辅助constructor,类似于java中的构造函数重载。辅助constructor之间可以互相调用,而且必须第一行调用主constructor

class Student_10_8 {
  private var name = ""
  private var age = 0
  def this(name: String){
    this()   //调用主构造函数
    this.name = name
    print(name)
  }
  def this(name:String,age:Int){
    this(name)   //调用辅助构造函数
    this.age = age
  }
}
object TextClas extends App {
  //--------10 -----8---辅助构造函数 constructor
  val c = new Student_10_8()
  val a = new Student_10_8("leo")  //leo
  println()
  val b = new Student_10_8("tom",13)//tom
}

主constructor (构造函数)

Scala中,主constructor是与类名放在一起的,与java不同。而且类中,没有定义在任何方法或者是代码块之中的代码,就是主constructor的代码,这点感觉没有java那么清晰

class Student_10_9_1(val name:String,val age:Int) {
  println("you name is  " + name + "  you age is " + age)
}

class Student_10_9_2(val name:String ="leo",val age:Int=13) {
  println("you name is " + name + "  you age is " + age)
}


object TextClas extends App {
  //--------10 -----9---主constructor
  val a = new Student_10_9_1("ttm",34)
  //you name is  ttm  you age is 34

  // 主constructor中还可以通过使用默认参数,来给参数默认的值
  val b = new Student_10_9_2()
  //you name is leo  you age is 13
}

如果主constrcutor传入的参数什么修饰都没有,比如name: String,那么如果类内部的方法使用到了,则会声明为private[this] name;否则没有该field,就只能被constructor代码使用而已.

内部类

Scala中,同样可以在类中定义内部类;但是与java不同的是,每个外部类的对象的内部类,都是不同的类。

import scala.collection.mutable.ArrayBuffer

class Class {
  class Student(val name: String) {}
  val students = new ArrayBuffer[Student]
  def getStudent(name: String) =  {
    new Student(name)
  }
}


object TextClas extends App {

  //--------10 -----10---内部类
  val c1 = new Class
  val s1 = c1.getStudent("leo")
  c1.students += s1

  val c2 = new Class
  val s2 = c2.getStudent("leo")
  c1.students += s2
  //Error:(70, 18) type mismatch;
  // found   : com.scala3.clas.TextClas.c2.Student
  // required: com.scala3.clas.TextClas.c1.Student
  //  c1.students += s2
}

猜你喜欢

转载自blog.csdn.net/TylerPY/article/details/102613963