Scala_OOP_01_方法_构造器_属性update

一 Scala中的方法其实就是函数,声明规则请参考函数式编程中的函数声明


基本语法
def 方法名(参数列表) [:返回值类型] = { 
    方法体
}

class Dog {
  private var sal: Double = _
  var food : String = _

  def cal(n1: Int, n2: Int): Int = {
    return n1 + n2
  }}
  def main(args: Array[String]): Unit = {
    val m = new MethodExec()
    m.width = 2.1
    m.len =2.4
    println(("面积=" + m.area()))
  }
}

class  MethodExec{
  var len = 0.0
  var width = 0.0
  def area(): Double = {
    val str = (this.len * this.width).formatted("%.2f")
    str.toDouble
  }

方法的调用机制原理
1) scala开始执行时,先在栈区开辟一个main栈。main栈是最后被销毁
2) 程序在执行到一个方法时,总会开一个新的栈。
3) 每个栈是独立的空间,变量(基本数据类型)是独立的,相互不影响(引用类型除外)
4) 方法执行完毕后,该方法开辟的栈就会被jvm机回收(指针移动,引用使用不到了)

函数栈.jpg

方法调用机制.png

二 构造
构造器(constructor)又叫构造方法,是类的一种特殊的方法,它的主要作用是完成对新对象的初始化
  1. Java中一个类可以定义多个不同的构造方法,构造方法重载
  2. 如没有定义构造方法,系统会自动给类生成一个默认无参构造方法(也叫默认构造器),比如 Person (){
  3. 一旦定义了自己的构造方法(构造器),默认的构造方法就覆盖了,就不能再使用默认的无参构造方法,除非显示的定义一下,即:  Person(){};

Scala构造器的介绍

  1. Scala构造对象也需要调用构造方法,并且可以有任意多个构造方法(即scala中构造器也支持重载)。
  2. Scala类的构造器包括: 主构造器 和 辅助构造器

Scala构造器的基本语法

class 类名(形参列表) {  // 主构造器 有且只有一个
   // 类体
   def  this(形参列表) {  // 辅助构造器
   }
   def  this(形参列表) {  //辅助构造器可以有多个, 通过参数来区分
   }
} 
object ConDemo2 {
  def main(args: Array[String]): Unit = {
    val b = new B()
    val b_alex = new B("ALEX")   // 先调 主构造器this (this is A)  再调 辅助构造器 def  this (this is b)
 
  }
}
/**输出
  * this is A
  * this is A
  * this is B
  */
class A {
  println( "this is A")
}

class B extends  A{

  def this(name: String){
    this
    println("this is B")
  }
}
def main(args: Array[String]): Unit = {
    val p1 = new Person2("Alex")
  }
}

//定义了一个Person类 Person 有4个构造器 
class Person2 private() {   // private 主构造器私有,想掉对象,必须通过辅助
  var name: String = _
  var age: Int = _

  def this(name : String) {
    //辅助构造器无论是直接或间接,最终都一定要调用主构造器,执行主构造器的逻辑
    //而且需要放在辅助构造器的第一行[这点和java一样,java中一个构造器要调用同类的其它构造器,也需要放在第一行]
    this()  //直接调用主构造器
    this.name = name
  }

  //辅助构造器
  def this(name : String, age : Int) {
    this() //直接调用主构造器
    this.name = name
    this.age = age
  }

  def this(age : Int) {
    this("匿名") //调用主构造器,因为 def this(name : String) 中调用了主构造器!
    this.age = age
  }
  }


Scala构造器注意事项和细节

  1. Scala构造器作用是对象的初始化,构造器没有返回值,主构造器的声明直接放置于类名之后
  2. 主构造器会执行类定义中的所有语句,即:构造器也是方法(函数),传递参数和使用方法和前面的函数部分内容没有区别
  3. 如果主构造器无参数,小括号可省略,构建对象时调用的构造方法的小括号也可以省略  [ class AA{ }   new AA;  new AA() ]
  4. 辅助构造器名称为this(这个和Java是不一样的),多个辅助构造器通过不同参数列表进行区分, 在底层就是f构造器重载
  5. 如果想让主构造器变成私有的,可以在()之前加上private,这样用户只能通过辅助构造器来构造对象了 
  6. 辅助构造器的声明不能和主构造器的声 明一致,会发生错误(即构造器名重复)



属性update

  1. 类的主构造器的形参未用任何修饰符修饰,那么这个参数是局部变量。
  2. 使用val关键字声明,那么参数作为类的私有的只读属性使用
  3. 使用var关键字声明,那么将参数作为类的成员属性使用,并会提供属性对应的xxx()[类似getter]/xxx_$eq()[类似setter]方法,即这时的成员属性是私有的,但是可读写
  4. 给某个属性加入@BeanPropetry注解后,getXXXsetXXX的方法 并且对原来底层自动生成类似xxx(),xxx_$eq()方法,没有冲突,二者可以共存


  def main(args: Array[String]): Unit = {
    val Engineer = new Engineer("alex")
    Engineer.name //不能访问 inName

    val Engineer2 = new Engineer2("alex2")
    Engineer2.inName //可以访问 inName //无法修改


    val Engineer3 = new Engineer3("bob")
    Engineer3.inName = "mary" // 可以修改

    Engineer3.name = "sumi"
    Engineer3.setName("sumi")  // //使用 @BeanProperty 自动生成 getXxx 和 setXxx
  }

}

class Engineer(inName: String) {
  var name = inName
}

//. 如果 主构造器是Engineer2(val inName: String) ,那么  inName就是Engineer2的一个private的只读属性
class Engineer2(val inName: String) {
  var name = inName
}

// 如果 主构造器是Engineer3(var inName: String) ,那么  inName就是Engineer3的一个
// 一个private 的可以读写属性
class Engineer3(var inName: String) {
  @BeanProperty var name = inName
}
(完)