Scala定义一个类、构造器、单例对象、伴生对象

1、定义一个Student类:

package com.aura.scala.day03

/**
  * 在scala的一个代码文件中,可以同时定义多个类
  * 而且这多个类可以都是public的。那么其实如果没有使用任何的修饰,那么这个类其实就是pulbic的
  * java定义的这个public的必须和代码文件的名称一样,
  * 但是,scala中, scala的代码文件的名称可以不用和public的class的名称一致
  */
class Teacher{
}

// 伴生类
class Student {
  println("huangbo love java ")
  /**
    * 1、 在scala定义中的属性,都需要进行初始化
    * 2、 使用val修饰的属性,具备getter方法, 不具备setter方法
    * 3、 使用var修饰的属性,具备getter方法, 具备setter方法
    * 4、 private修饰的变量,表示私有。除了自己以外,其他的任何组件都不能访问
    *     但是有一个例外:
    *     和当前这个类同名的object组件(对应的伴生对象)中可以访问
    *     class Student     伴生类
    *     object Student   伴生对象
    *     private修饰的变量,除了自己和伴生对象之外, 其他的任何组件都不能访问
    * 5、 private          自己  +  伴生对象
    *     private[this]    自己, 伴生对象都不能访问
    * 6、补充:
    *   一个类中,除了属性之外,也可以定义方法
    *   那么方法的访问级别:private  private[this] 的效果和修饰属性一模一样
    *   如果在定义一个属性, 没有加任何其他修饰符的话,默认是public的
    *
    * 总结:
    *     var   val   决定是否有setter功能
    *     private   private[this]  决定是否可以伴生对象访问
    */

  val id = 9527
  var name = "唐伯虎"
  private var age = 18
  private[this] var salary = 400000

  def sum(x:Int, y:Int) :Int = {
    println("hello world")
    println(x, y)
    x + y
  }

  sum(2, 3)

  println("huangbo love scala ")
}

/**
  * 如果要执行某个代码测试,就需要编写一个main方法的obejct组件, 而且该main方法
  * 必须放在object中, 不能放在class中
  */

// 伴生对象
object Student{
  def main(args: Array[String]): Unit = {

    // 使用val修饰的属性,具备getter方法, 不具备setter方法
    // 如果你调用了new的方式去创建一个对象,那么这个类的定义中的{}中的所有能执行的代码都会执行
    // SparkContext {}中的代码有2100行左右  new SparkContext
    val student: Student = new Student()
    //student.id = 6379       //  ×××   不允许修改
    println(student.id)

    // 使用var修饰的属性,具备getter方法, 具备setter方法
    println(student.name)
    student.name = "祝枝山"
    println(student.name)

    // private修饰的变量,除了自己和伴生对象之外, 其他的任何组件都不能访问
    println(student.age)

    // 使用private[this]修饰的变量,除了自己能访问之外,链伴生对象都不能访问
    // println(student.salary)       //  ×××   不允许修改
  }
}

2、定义一个构造器:

package com.aura.scala.day03
/**
  * 在定义一个scala的类的构成中,如果这个类的类名后面没有跟 ()
  * 我们认为这个类:有一个主构造器    格式:类型()
  * 但是() 也可以省略(在没有参数的时候)
  *
  * 主构造器:直接跟在类名的后面的()就是
  *
  * scala中的主构造器   ===(类似,核心地位)  java中的无参构造器
  *
  * 如何定义无参构造:
  *     class Student11{}
  *     class Student11(){}
  *
  * 如何定义有参构造呢?
  *     class Student11(var id:Int, var name:String){}
  *
  * 1、如果在主构造器中,属性使用var或者val修饰时,默认是public的
  *    就相当于定义了一个成员变量:
  *    public var id:Int = 9527
  *    public var name:String = "唐伯虎"
  *
  * 2、如果属性不使用var或者val修饰,就相当于是:
  *    private[this] val age = 18
  *
  * 3、val或者var修饰的主构造器的参数自动成为成员属性
  *    不使用var、val修饰,就相当于: private[this] val 修饰
  *    使用private 或者 private[this]
  *
  * 4、有些时候,我们在定义类的构造器的时候需要禁止主构造器的使用。
  */

 /**
  *  主构造器也可以被私有。可以被private 和  private[this] 修饰
  *  如果一个类的主构造器被: private[this] 修饰了的话, 那么如何创建对象呢?
  *  使用辅助构造器
  */
class Student11 private (var id:Int, val name:String, age:Int, 
private var salary:Double,  private[this] val xx:Int) {

//  val id = 9527
//  var name = "tbh"

  println("hello scala")

  /**
    * 这句话代码的作用:
    * 相当于把主构造器中的一个不带var或者val修饰的属性在方法中使用了。
    * 如果没有使用一次的话, 那就相当于是普通的主构造器的参数
    */
  def myprint = println(age)

//  public Student11(){}   这是java的语法定义无参构造
}

object Student11{
  def main(args: Array[String]): Unit = {
    // 首先执行{}
    val student11: Student11 = new Student11(9527, "唐伯虎", 18, 500000, 44)
    println(student11.id)
    println(student11.name)
//  println(student11.age)     //不允许访问,private[this]
    println(student11.salary)

    // 私有了主构造器之后。这句代码就不能正常执行了。
    // val student22: Student22 = new Student22(9527, "唐伯虎")
    // 所以只能调用辅助构造器了。
    val student22: Student22 = new Student22(9527, "唐伯虎", 33)
  }
}

class Student22 private[this] (var id:Int, val name:String){
  /**
    * 定义辅助构造器有以下几个要点:
    *    1、使用def进行定义
    *    2、方法的名称必须是this
    *    3、辅助构造器中的参数列表一般来说,都要包括主构造器中的参数列表
    *    4、辅助构造器{}中的第一句代码,都要以为其他的构造器(其他的辅助构造器或者主构造器)开头
    */
  def this(id:Int, name:String, age: Int) = {
    // 第一句代码调用了主构造器
    this(id,name)
    println("helloworld")
  }
  def this(id:Int, name:String, age: Int, xx:String) = {
    // 第一句代码调用了辅助构造器
    this(id,name, age)
  }
}

/**
  * 两个问题:
  * 1、  主构造器  和  辅助构造器的区别?
  * 2、   Scala定义构造器,或者调用构造器为什么使用this ?   好处是什么?
  */

​

3、定义一个单例对象:

/**
  * 定义类的时候: 把半生类 和伴生对象 放在一个文件中
  * 其他的如果只是在当前这个文件中使用一次的类,那么可以定义在这个文件中
  * 如果被使用多次,最好定义到一个独立的scala文件中
  */

/**
  * 如果属性和方法定义在object组件中,就可以直接使用类名类访问
  * 其实这既是java中的static的语法
  */

object ObjectTest {
  def main(args: Array[String]): Unit = {
    // 实例对象
    val ot22: ObjectTest22 = new ObjectTest22("a", "b")
    println(ot22.id)
    println(ot22.m1(4))

    // 静态(属性和方法)
    println(ObjectTest11.id1)
    println(ObjectTest11.m11(4))

    // object修饰的一个类,就是一个单例对象。
    val ot11_1 = ObjectTest11
    val ot11_2 = ObjectTest11
    println(ot11_1 == ot11_2)           // true
    println(ot11_1 eq ot11_2)           // true
    println(ot11_1 ne ot11_2)           // false
    println(ot11_1.equals(ot11_2))     // true

    println("-------------------------------")
    // 为了测试:   ==   eq   ne    equals
    /**
      * == 在scala中,默认就是按照内容进行比较。前提是实现equals, 就是按照equals方法比较, 但是在java中, 就是比较引用
      * ne  eq   在scala中就是比较引用
      * equals    效果等同于java中的equals
      */
    val aa = new ObjectTest22("a", "b")
    val bb = new ObjectTest22("a", "b")
    println(aa == bb)                            // true
    println(aa eq bb)                            // false
    println(aa ne bb)                            // true
    println(aa.equals(bb))                       // true
    println(aa.toString.equals(bb.toString))   // true

    /**
      * java中的this
      * public void setName(String name){
      *   this.name =  name;
      * }
      */
  }
}

object ObjectTest11 {
  val id1:Int = 11
  def m11(x:Int) = x + 1
}

class ObjectTest22(var a:String, var b:String) {
  val id:Int = 11
  def m1(x:Int) = x + 1

  override def toString: String = a + "-" + b

  override def equals(obj: scala.Any): Boolean =
    this.toString.equals(obj.toString)
}

4、定义一个伴生对象:

// 伴生对象
object ObjectTestPrivate {

  private val name:String = "aa"

  def main(args: Array[String]): Unit = {
    val oo = new ObjectTestPrivate()
    val oo2  = ObjectTestPrivate

    // 伴生对象,能访问伴生类中的私有成员
    oo.myprint
    println(oo.id)
  }
}

// 伴生类
class ObjectTestPrivate{
  private val id:Int = 22
  // 伴生类能访问伴生对象的私有属性
  private def myprint{
    println(ObjectTestPrivate.name)
  }

  def  ab1 = println("a")
  def  abc():Unit = {println("hello worl"); id}
  val  aaa = id
}

总结:

伴生类 伴生对象 之间可以互相访问对方的私有属性

Scala中的main方法为什么要定义在object中?

Java中main方法的定义:主方法需要定义为static类型的;在Scala中,object里面的方法都是静态方法,故需要将主方法定义在Object中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值