scala中object和class的理解---apply方法是初始化方法

本文深入探讨Scala中的类定义、构造器使用、统一访问原则等核心概念,并解析如何利用object实现静态成员及单例模式。

1.class

Scala的类和C#中的类有点不一样,诸如: 声明一个未用priavate修饰的字段 var age,scala编译器会字段帮我们生产一个私有字段和2个公有方法get和set ,这和C#的简易属性类似;若使用了private修饰,则它的方法也将会是私有的。这就是所谓的统一访问原则。

细节的东西太多,还是上代码在注释里面细讲吧

 

[java]  view plain  copy
 
  1. //类默认是public级别的  
  2. class Person{  
  3.   var age=18  //字段必须得初始化()  
  4.   def Age=age //这个是方法,没有参数可以省略()  
  5.   def incremen(){this.age+=1}  
  6. }  
  7.   
  8.   
  9. class Student{  
  10.   var age=20     //底层编译器会自动为私有的age添加get和set的公有方法,可以理解为伪public类型  
  11.   private[this] var gender="male" //private[this] 只有该类的this可以使用  
  12.   private var name="clow" //声明了private,底层编译器会自动为私有的name添加get和set的私有方法  
  13.   //但是可以自己定义属性方法  
  14.   def getName=this.name  
  15.   def setName(value:String){this.name=value}  
  16. }  
  17.   
  18. //构造器的使用  
  19. class Teacher {  
  20.   var age: Int = _  
  21.   var name: String = _  //可以预留  
  22.   
  23.   //重载的构造器和C#里面的public Teacher(){}类似  
  24.   def this(age: Int, name: String){  
  25.     this() //必须得调用一次主构造器  
  26.     this.age=age  
  27.     this.name=name  
  28.   }  
  29. }  

 

类的构造器细节

 

[java]  view plain  copy
 
  1. //1.主构造器在类名后,参数会被声明字段,若参数没有使用var或者val声明,则会被声明称私有字段  
  2. //2.实例化类的时候,类中的语句会被执行:println("person")  
  3. class Person(name:String,var age:Int) {  
  4.   println("person")  
  5.   
  6.   def show(): Unit = {  
  7.     println("show.."+name)  
  8.   }  
  9.   
  10.   var gender:String=_  
  11.   
  12.   //次构造器必须调用主构造器,参数不能使用var  
  13.   def this(name:String,age:Int, gender:String){  
  14.     this(name,age)  
  15.     this.gender=gender  
  16.   }  
  17. }  
 

 

 

2.scala没有静态的修饰符,但object下的成员都是静态的 ,若有同名的class,这其作为它的伴生类。在object中一般可以为伴生类做一些初始化等操作,如我们常常使用的val array=Array(1,2,3)  (ps:其使用了apply方法)

 

[java]  view plain  copy
 
  1. object Dog{  
  2.   private var age=0  
  3.   def Age={  
  4.     age+=1  
  5.     age  
  6.   }  
  7. }  
  8.   
  9. class Dog{  
  10.   var age1=Dog.age //Dog.age是object Dog的私有字段。这不禁让我回想起了C++的友元类  
  11. }  

 

3.Apply的使用

 

[java]  view plain  copy
 
  1. class ApplyTest{  
  2.   
  3.   val name="clow";  
  4.   def apply()  {  
  5.     println("class ApplyTest--apply()...");  
  6.   }  
  7.   
  8. }  
  9.   
  10. //object下的成员默认都是静态的  
  11. object ApplyTest{  
  12.   def apply() = {  
  13.     println("object ApplyTest--apply()...");  
  14.     new ApplyTest()  
  15.   }  
  16. }  
  17.   
  18.   
  19. object Basic4 {  
  20.   
  21.   def main(args: Array[String]) {  
  22.     //类名()->调用了对应object下的apply方法  
  23.     var a1=ApplyTest()  
  24.     println(a1.name)  
  25.     //对象名()->调用了对应class的apply方法  
  26.     a1() //输出:class ApplyTest--apply()...  
  27.   }  
  28. }  

 

 

Apply怎么用它来实现单例模式

 

[java]  view plain  copy
 
    1. class ApplyTest private{  //添加private隐藏构造器  
    2.   def sayHello(){  
    3.     println("hello jop")  
    4.   }  
    5. }  
    6.   
    7. object ApplyTest{  
    8.   var instant:ApplyTest=null  
    9.   def apply() ={  
    10.     if(instant==null) instant=new ApplyTest  
    11.     instant  
    12.   
    13.   }  
    14. }  
    15.   
    16. object ApplyDemo {  
    17.   def main(args:Array[String]){  
    18.       val t=ApplyTest()  
    19.       t.sayHello()  
    20.   }  
    21. }  

转载于:https://www.cnblogs.com/loveItLoveFaimly/p/7391285.html

<think>嗯,用户问的是Scala中init方法的作用用法,还有功能、使用场景初始化过程。首先,我需要确定Scala中是否有直接叫做init的方法。根据我所了解的,Scala的标准库中并没有一个普遍存在的init方法,但可能存在一些特定数据结构中的init方法,比如List或者集合类。比如,List的init方法返回除最后一个元素外的所有元素,这Haskell中的init类似。不过,用户可能误解了,或者是指初始化方法,比如构造函数或者对象初始化相关的。 首先,我需要区分用户的问题。如果用户指的是集合的init方法,那么需要解释List等集合中的init的作用。如果是关于类的初始化过程,比如构造函数,那么在Scala中,主构造函数辅助构造函数的用法可能才是重点。另外,Scala中的对象初始化还可能涉及到val变量的初始化顺序,或者伴生对象中的apply方法等。 接下来,我需要检查用户提供的引用内容,是否有相关的信息。引用[1]提到了柯里化函数,引用[2]是关于集合转换的,引用[3]是事务注解的应用场景。这些似乎init方法没有直接关联,但可能需要考虑用户是否在上下文中混淆了init与其他概念,比如构造函数或者初始化代码块。 例如,在Scala中,类的构造函数是类体本身,主构造函数包含类参数类体中执行的语句。辅助构造函数则用def this(...)来定义。初始化代码块可以直接写在类体中。例如: class MyClass(param: Int) { val someVal = param + 1 // 初始化代码 // 其他初始化语句 } 可能用户提到的init方法指的是这种初始化过程,或者是伴生对象中的工厂方法,比如apply方法用来初始化实例。 另外,可能需要提到case类的自动生成的apply方法,或者对象在单例初始化时的行为。不过这些可能用户的问题有些偏差。 此外,用户可能在使用某些框架时遇到了init方法,比如Play Framework或Akka中的生命周期方法,比如preStart等,但这也属于特定框架的内容,不是Scala语言本身的标准。 综上,我应该首先说明Scala标准库中的init方法(如在List中的使用),然后讨论类初始化的过程,包括主构造函数、初始化代码块、val变量的顺序等。如果用户的问题是关于如何自定义初始化逻辑,可能需要提到辅助构造函数或者在类体中编写代码。 另外,需要注意用户是否将构造函数或初始化块称为init方法,这在Scala中并不常见,但可能需要解释清楚。 现在需要组织回答的结构,先说明可能的两种情况:集合的init方法类的初始化过程。然后分别解释其功能、使用场景初始化过程。 同时,根据用户提供的引用,可能没有直接相关的信息,但引用[1]中的柯里化函数可能与构造函数无关,引用[2]的集合转换也不相关,引用[3]的事务注解可能在初始化时使用,但不确定。所以可能不需要引用这些内容。 最后,生成相关问题,比如如何自定义初始化代码,集合的inittail的区别,构造函数的使用等。</think>### Scala初始化方法与init解析 #### 一、集合操作中的`init`方法 Scala标准库中集合类型(如List、Vector等)提供`init`方法,其功能与`tail`形成互补操作: $$ \text{List.init} : \forall list \neq Nil,\ list = list.init :+ list.last $$ ```scala val numbers = List(1,2,3,4) numbers.init // 返回List(1,2,3) numbers.last // 返回4 ``` **使用场景**:需要获取除最后一个元素外的所有元素时使用,时间复杂度为$O(n)$[^1]。 #### 二、类初始化过程 Scala没有显式的`init`方法命名约定,但通过构造机制实现初始化: 1. **主构造函数**:与类定义直接融合 ```scala class Person(name: String) { // 主构造函数参数 private val id = UUID.randomUUID() // 直接初始化字段 println(s"初始化对象$id") // 类体代码即构造逻辑 } ``` 2. **辅助构造函数**:通过`def this(...)`定义,必须最终调用主构造函数 ```scala class Student(name: String, age: Int) { def this(name: String) = this(name, 18) // 辅助构造函数 } ``` #### 三、初始化顺序规则 1. 父类构造函数优先执行 2. 按声明顺序初始化成员变量 3. 伴生对象`apply`方法常用于构造模式: ```scala object Circle { def apply(radius: Double) = new Circle(radius) } class Circle(r: Double) ``` #### 四、自定义初始化模式 可通过组合特征实现初始化逻辑: ```scala trait Initializable { def init(): Unit // 抽象初始化方法 } class Service extends Initializable { override def init(): Unit = { println("建立数据库连接") } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值