Scala——(类和无参构造器,自定义getter和setter方法,Bean属性,构造器,对象)

类和无参构造器

  1. 在Scala中,类并不用声明为public;

  2. Scala源文件中可以包含多个类,所有这些类都具有公有可见性;

  3. val修饰的变量(常量),值不能改变,只提供getter方法,没有setter方法;

  4. var修饰的变量,值可以改变,对外提供getter、setter方法;

  5. 如果没有定义构造器,类会有一个默认的无参构造器;

      class Person{
        // Scala中声明一个字段,必须显示的初始化,然后根据初始化的数据类型自动推断其类型,字段类型可以省略
        var name = "jacky"
    
        // _ 表示一个占位符,编译器会根据变量的数据类型赋予相应的初始值
        // 使用占位符,变量类型必须指定
        // _ 对应的默认值:整型默认值0;浮点型默认值0.0;String与引用类型,默认值null; Boolean默认值false
        var nickName: String = _
        var age = 20
        // 如果赋值为null,则一定要加数据类型,因为不加类型, 该字段的数据类型就是Null类型
        // var address = null
        // 改为:
        var address:String = null;
    
        // val修饰的变量不能使用占位符
        val num = 30
    
        // 类私有字段,有私有的getter方法和setter方法,
        // 在类的内部可以访问,其伴生对象也可以访问
        private var hobby: String = "旅游"
    
        // 对象私有字段,访问权限更加严格,只能在当前类中访问
        private[this] val cardInfo = "123456"
    
        //自定义方法
        def hello(message: String): Unit = {
          //只能在当前类中访问cardInfo
          println(s"$message,$cardInfo")
        }
        //定义一个方法实现两数相加求和
        def addNum(num1: Int, num2: Int): Int = {
          num1 + num2
        }
    
    }
    
  6. 类的实例化以及使用:

      def main(args: Array[String]): Unit = {
        //创建对象两种方式,这里都是使用的无参构造器来进行创建对象的
        val person = new Person()
        //创建类的对象时,小括号()可以省略
        val person1 = new Person
        //给类的属性赋值
        person.age = 50
        //注意:如果使用对象的属性加上 _= 给var修饰的属性进行重新赋值,其实就是调用age_=这个 setter方法
        person.age_=(20)
        //直接调用类的属性,其实就是调用getter方法
        println(person.age)
        //调用类中的方法
        person.hello("hello")
        val result = person.addNum(10, 20)
        println(result)
      }
    

自定义getter和setter方法

  1. 对于 Scala 类中的每一个属性,编译后会有一个私有的字段和相应的getter、setter方法生成。

    //getter方法
    println(person age)
    
    //setter方法
    person age_= (18)
    
    //getter方法
    println(person.age)
    
  2. 不使用自动生成的方式,自己定义getter和setter方法,自定义变量的getter和setter方法需要遵循以下原则:

    1. 字段属性名以“_”作为前缀,如: _leg
    2. getter方法定义为:def leg = _leg
    3. setter方法定义为:def leg_=(newLeg: Int)
      class Dog{
        private var _leg = 0
        // 自定义getter方法
        def leg = _leg
        //自定义setter方法
        def leg_=(newLeg: Int) {
          _leg = newLeg
        }
        // 使用自定义getter和setter方法
        val dog = new Dog
        dog.leg_=(4)
        println(dog.leg)
      }
    

Bean属性

  1. JavaBean规范把Java属性定义为一堆getter和setter方法。

  2. 当将Scala字段标注为 @BeanProperty时,getFoo和setFoo方法会自动生成。

  3. 使用@BeanProperty并不会影响Scala自己自动生成的getter和setter方法。

  4. 在使用时需要导入包scala.beans.BeanProperty

    object TeacherScala {
      class Teacher {
        @BeanProperty var name:String = _
      }
    
      def main(args: Array[String]): Unit = {
        val tea: Teacher = new Teacher
        tea.name = "zhagnsan"
        tea.setName("lisi") //BeanProperty生成的setName方法
        println(tea.getName) //BeanProperty生成的getName方法
    
        // Teacher类中共生成了四个方法:
        //    1. name: String
        //    2. name_= (newValue: String): Unit
        //    3. getName(): String
        //    4. setName (newValue: String): Unit
      }
    

构造器

  1. 如果没有定义构造器,Scala类中会有一个默认的无参构造器;

  2. Scala当中类的构造器分为两种:主构造器和辅助构造器;

  3. 主构造器的定义与类的定义交织在一起,将主构造器的参数直接放在类名之后。

  4. 当主构造器的参数不用var或val修饰时,参数会生成类的私有val成员。

  5. Scala中,所有的辅助构造器都必须调用另外一个构造器,另外一个构造器可以是辅助构造器,也可以是主构造器。

    object Animal {
      def main(args: Array[String]): Unit = {
        val dog1=new Dog("狗蛋",4)
        val dog2=new Dog("旺才",3,"雄性")
        val dog3=new Dog("小六",5,"雄性","黑色")
      }
    }
    //主构造器直接定义在类中,其代码不包含在任何方法中
    //Scala中的主构造器与类名交织在一起,类名后面的参数即为主构造器的参数
    class Dog(name: String, age: Int) {
      //类中不在任何方法中的代码,都属于主构造器的代码。
      //创建类的对象时会去执行主构造器的代码。下面的println代码就是主构造器的一部分
      println(name)
      println(age)
      var gender: String = ""
    
      def this(name: String, age: Int, gender: String) {
        //每个辅助构造器,都必须以其他辅助构造器,或者主构造器的调用作为第一句代码
        this(name, age)
        this.gender = gender
      }
    
      var color = ""
    
      def this(name: String, age: Int, gender: String, color: String) {
        //调用上面的辅助构造器
        this(name, age, gender)
        this.color = color
      }
    }
    

对象

单例对象

  1. Scala并没有提供Java那样的静态方法或静态字段;可以采用object关键字实现单例对象,具备和Java静态方法同样的功能;

  2. 使用object语法结构【object是Scala中的一个关键字】达到静态方法和静态字段的目的;对象本质上可以拥有类的所有特性,除了不能提供构造器参数;

  3. 对于任何在Java中用单例对象的地方,在Scala中都可以用object实现:

    1. 作为存放工具函数或常量的地方
    2. 高效地共享单个不可变实例
    object SessionFactory {
    
      val session = new Session
      def getSession(): Session = {
        session
      }
      def main(args: Array[String]): Unit = {
        for (x <- 1 to 10) {
          //通过直接调用,产生的对象都是单例的
          val session = SessionFactory.getSession()
          println(session)
        }
      }
    
      class Session {
        def hello(first: Int): Int = {
          println(first)
          first
        }
      }
    }
    
  4. Scala中的单例对象具有如下特点:

    1. 创建单例对象不需要使用new关键字
    2. object中只有无参构造器
    3. 主构造代码块只能执行一次,因为它是单例的
object ObjectDemo {
	println("这是单例对象的代码!")
	
	def main(args: Array[String]): Unit = {
		val object1=ObjectDemo
		val object2=ObjectDemo
	}
}

伴生类与伴生对象

  1. 当单例对象与某个类具有相同的名称时,它被称为这个类的“伴生对象”;

  2. 类和它的伴生对象必须存在于同一个文件中,而且可以相互访问私有成员(字段和方法);

    package com.scala.code
    
    class ClassObject {
      val id = 1
      private var name = "lagou"
      def printName(): Unit ={
        //在ClassObject类中可以访问伴生对象ClassObject的私有字段
        println(ClassObject.CONSTANT + name )
      }
    }
    object ClassObject{
      //伴生对象中的私有字段
      private val CONSTANT = "汪汪汪"
      def main(args: Array[String]) {
        val p = new ClassObject
        //访问伴生类的私有字段name
        p.name = "123"
        p.printName()
      }
    }
    

应用程序对象

  1. 每个Scala应用程序都必须从一个对象的main方法开始,这个方法的类型为 Array[String] => Unit;
  2. main方法写在class中是没有意义的,在IDEA中这样的 class 连run的图标都不能显示,除了main方法以外,也可以扩展App特质(trait)
object Hello extends App {
  if (args.length > 0)
	println(s"Hello World; args.length = ${args.length}")
  else
	println("Hello World")
}

apply方法

  1. object 中有一个特殊方法 – apply方法;

    1. apply方法通常定义在伴生对象中,目的是通过伴生类的构造函数功能,来实现伴生对象的构造函数功能;
    2. 通常我们会在类的伴生对象中定义apply方法,当遇到类名(参数1,…参数n)时apply方法会被调用;
    3. 在创建伴生对象或伴生类的对象时,通常不会使用new class/class() 的方式,而是直接使用class()隐式的调用伴生对象的 apply 方法
    //class Student为伴生类
    class Student(name: String, age: Int) {
      private var gender: String = _
      def sayHi(): Unit ={
        println(s"大家好,我是$name,$gender 生")
      }
    }
    object Student {
    
      //apply方法定义在伴生对象中
      def apply(name: String, age: Int): Student = new Student(name, age)
      def main(args: Array[String]): Unit = {
        //直接利用类名进行对象的创建,这种方式实际上是调用伴生对象的apply方法实现的
        val student=Student("jacky",30)
        student.gender="男"
        student.sayHi()
      }
    }
    
  2. 在Scala中实现工厂方法,让子类声明哪种对象应该被创建,保持对象创建在同一位置。例如,假设要创建Animal工厂,让其返回Cat和Dog类的实例,基于这个需求,通过实现Animal伴生对象的apply方法,工厂的使用者可以像这样创建新的Cat和Dog实例。

    package com.scala.code
    
    object AnimalObject {
      def main(args: Array[String]): Unit = {
        val cat = Animal("cat")
        cat.speak
        val dog = Animal("dog")
        dog.speak
      }
      abstract class Animal {
        def speak
      }
      class Dog extends Animal {
        override def speak: Unit = {
          println("woof")
        }
      }
      class Cat extends Animal {
        override def speak: Unit = {
          println("meow")
        }
      }
      object Animal {
        def apply(str: String): Animal = {
          if (str == "dog")
            new Dog
          else
            new Cat
        }
      }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值