Scala基础之类(伴生对象,半生类)

类基本语法:Scala中一个源文件中可以声明多个公共类

// 声明类:访问权限 class 类名 { 类主体内容 } 
class User {
    // 类的主体内容
}
// 对象:new 类名(参数列表)
new User()  

类的属性 :在编译时,编译器会将变量编译为类的(私有的)属性,同时提供了属性对应的set,get方法

class User {

    var name : String = _ // 类属性其实就是类变量

    var age : Int = _ // 下划线表示类的属性默认初始化

}

// 给类的属性赋值,等同于调用对象属性的set方法

  //user.name = "AsianHarden"

// 访问类的属性时,等同于调用对象属性的get方法

  //println(user.name)

//scala中给属性提供的set,get方法不遵循bean规范

  //@BeanProperty var email : String = _

访问权限:java&scala对比

java :
     1. private    => 本类
     2. (default)  => 本类,本包
     3  protected  => 本类,本包,子类
     4. public     => 任意
scala :
     1. private       => 同类
     2. private[包名]  => 同包,包私有
     3. protected     => 受保护的, 同类,子类,没有同包
     4. (default) => 什么都不写就是公共的。没有public关键字     

 
        private val name1:String = "AsianHarden"
        private[package_name] val name2:String = "AsianHarden"
        protected val name3:String = "AsianHarden"
        val name4:String = "AsianHarden" 

访问权限的疑问

public class Test{
    public static void main(String[] args) throws Exception {

        // 访问权限 ,调用者和方法的提供者之间的关系
        // 方法的提供者 =>AA
        // 方法的调用者 =>Test

        // 点不是调用的意思,点的含义就是"的",从属关系
        AA aa = new AA();
        aa.clone();

    }
}
class AA {
//1    @Override
//  2  protected Object clone() throws CloneNotSupportedException {
//    3    return super.clone();
    }
}
//123注释掉后,aa.clone()报错,Test的object没用权限访问到AA的object,Test,AA的Object是彼此独立的 

 类的对象

val | var 对象名 [:类型]  = new 类型()
var user : User = new User() 

类的构造方法

  • 1.主动构造函数
  • 2.辅助构造函数
class User() { // 主构造函数
    var username : String = _ 
    def this( name:String ) { // 辅助构造函数,使用this关键字声明
        this() // 辅助构造函数应该直接或间接调用主构造函数
        username = name
}
def this( name:String, password:String ) {
    this(name) // 构造器调用其他另外的构造器,要求被调用构造器必须提前声明
}
}
1)辅助构造方法在执行之前,应该首先调用主构造方法完成类的初始化
2)辅助构造方法可以重载的,并且可以互相调用,但是调用的辅助构造方法应该提前声明(位置关系)
  • 参数声明为val & var 区别
参数声明为val
如果构造函数参数声明为val,Scala只为它生成一个getter方法。

参数声明为var
如果构造函数参数声明为var,Scala将生成访问器和mutator方法。

//定义一个类,参数不可变
class Book( val title:String)
//调用只能调用getter 方法 无法调用setter方法
object Main {
  def main(args: Array[String]) {
    class Book( val title:String)
    val book = new Book("Scala")
    println(book)
    println(book.title )
    //book.title = "new title"  //Error
  }
}
//定义一个类,参数可变
class Book( var title:String)
//Scala将生成访问器和mutator方法。
object Main {
  def main(args: Array[String]) {
    class Book( var title:String)
    val book = new Book("Beginning Scala")
    book.title = "new title"
    println(book.title )
  }
} 
  • 构造方法私有化
构造方法私有化: 在参数列表前增加private关键字
    class Person private () {

    }

scala类java静态语法,私有化实现

1)scala中没有静态语法,但是可以直接使用java中的静态操作
2)scala采用了一种特殊的处理方式来代替静态语法 :object
3)object关键字可以用于创建对象,对象的名字就是声明的名字,object关键字声明的类和对象有关系的。
这个对象等同于伴随着这个类创建时所产生的,所以将这个对象称之为:伴生对象
这个类称之为伴生类
伴生对象就是一个对象,可以访问伴生类中的所有东西,包括私有的。
伴生对象其实就是马丁模拟静态语法所产生的。
一般写代码时,将静态语法操作的代码写在伴生对象中,将成员方法或属性写在伴生类中
//构造方法私有化导致new Person()报错,所以需要构建一个对象来创建Person类
//半生类  
  class Person private (){
    println("class Person")
  }
// 伴生对象,与半生类同名 类java的静态方法调用使用
  object Person{
    def getInstance(): Person ={
      new Person()
    }
  }
}

    Person.getInstance()
//  val person = new Person()  报错
TODO scala中伴生对象就是单例的
伴生对象只需要声明即可,无需构建,所以不需要构造参数列表
单例模式存在一个问题:创建的对象不会被回收,需要显示地回收(设置为null)
    
 // 如果伴生对象中构建对象的方法名成为apply,编译器可以自动识别的,所以这个方法名可以省略的
val test1: Test = Test.apply()
val test1 = new Test() // 调用类的构造方法
val test2 = Test()     // 调用的是伴生对象的apply方法
val test3 = Test       // 伴生对象本体

    class Test() {
        println("ttttt")
    }
    object Test {
        def apply() = {
            println("apply") //打印apply。证明走的是伴生对象的apply()
            //new Test()
        }
    }


posted @ 2021-05-21 19:52  亚洲哈登  阅读(282)  评论(0编辑  收藏  举报