Scala 类和对象

1.类和对象

类:可以看成一个模板

对象:表示具体的事物

定义类 回顾:Java中的类 如果类是public的,则必须和文件名一致。

一般,一个.java有一个public类

注意:Scala中没有public,一个.scala中可以写多个类。

基本语法  

说明: (1)Scala语法中,类并不声明为public,所有这些类都具有公有可见性(即默认就是public)

(2)一个Scala源文件可以包含多个类 

注:Bean属性(@BeanPropetry),可以自动生成规范的setXxx/getXxx方法

package com.bigdata.scala

import scala.beans.BeanProperty

class DemoScalaClass{
  //如果在属性前加上private,则同名的object仍可以访问该属性
  var id:String="001"
  val name:String="鸡排饭"
  //默认获得get,set方法,val只有get方法,var二者都有
  @BeanProperty var age:Int=10

  def showInfo():Unit={
    println(s"$id,$name,$age")
  }
}

object DemoScalaClass{
  def main(args: Array[String]): Unit = {
    //对象实例化
    val c1 = new DemoScalaClass()
    println(c1.name)
    c1.showInfo()

    c1.id="002" //var可以改变值,来修改对象的属性
  }

}

2.构造方法

构造器: 和Java一样,Scala构造对象也需要调用构造方法,并且可以有任意多个构造方法。 Scala类的构造器包括:主构造器和辅助构造器

package com.bigdata.scala

class DemoScalaClassConstruct(id: String, name: String, age: String) { //主构造器
  println("调用主构造器")
  //在scala中,一般以下划线开头来命名防止重名
  //定义即赋值,定义的时候必须赋值
  val _id: String = id
  val _name: String = name
  val _age: String = age
  var _gender: String = "男"
  var _clazz:String=_ //定义下划线,表示稍后使用

  //辅助构造器
  def this(id: String, name: String, age: String,gender:String) {
    //第一行调用必须调用默认构造器
    this(id,name,age)
    _gender=gender
    println("调用辅助构造器1")
  }

  def this(id: String, name: String, age: String, gender: String,clazz:String) {
    //辅助构造器可以有多个
    this(id, name, age,gender)
    _clazz=clazz
    println("调用辅助构造器2")
  }


}

object DemoScalaClassConstruct {
  def main(args: Array[String]): Unit = {
    val p1 = new DemoScalaClassConstruct("001", "1号", "20")
    val p2 = new DemoScalaClassConstruct("002", "2号", "20", "女")
    val p3 = new DemoScalaClassConstruct("003", "3号", "20", "男","clazz1")
  }
}

说明:

(1)辅助构造器,函数的名称this,可以有多个,编译器通过参数的个数及类型来区分。

(2)辅助构造方法不能直接构建对象,必须直接或者间接调用主构造方法。

(3)构造器调用其他另外的构造器,要求被调用构造器必须提前声明。

3.封装

封装就是把抽象出的数据和对数据的操作封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作(成员方法),才能对数据进行操作。

Scala中的public属性,底层实际为private,并通过get方法(obj.field())和set方法(obj.field_=(value))对其进行操作。所以Scala并不推荐将属性设为private,再为其设置public的get和set方法的做法。但由于很多Java框架都利用反射调用getXXX和setXXX方法,有时候为了和这些框架兼容,也会为Scala的属性设置getXXX和setXXX方法(通过@BeanProperty注解实现)。

3.1 访问权限 

(1)Scala 中属性和方法的默认访问权限为public,但Scala中无public关键字。

(2)private为私有权限,只在类的内部和伴生对象(同名的object)中可用。

(3)protected为受保护权限,Scala中受保护权限比Java中更严格,同类、子类可以访问,同包无法访问。

(4)private[包名]增加包访问权限,包名下的其他类也可以使用

3.2 Apply方法 

(1)通过伴生对象的apply方法,实现不使用new方法创建对象。

(2)如果想让主构造器变成私有的,可以在()之前加上private。

(3)apply方法可以重载。

(4)Scala中obj(arg)的语句实际是在调用该对象的apply方法,即obj.apply(arg)。用以统一面向对象编程和函数式编程的风格。

(5)当使用new关键字构建对象时,调用的其实是类的构造方法,当直接使用类名构建对象时,调用的其实时伴生对象的apply方法。

package com.bigdata.scala

class DemoApply(id:String){
  var _id:String=id

  def printId(): Unit = {
    println(_id)
  }
}

//伴生对象
object DemoApply{
  
  //apply方法会返回伴生类的对象,并返回该对象
  def apply(id: String): DemoApply = new DemoApply(id)
}

 注:相同的包下不能有同样的类名

 4.继承和多态

package com.bigdata.scala

class Person(id:String,name:String,age:Int){
  val _id: String = id
  val _name: String = name
  val _age: Int = age

  def sleep(): Unit = {
    println("人会睡觉")
  }

  def printInfo(): Unit = {
    println(s"$id,$name,$age")
  }
}

//extends继承,可以继承属性和方法
//scala继承需要调用父类中默认的构造方法
class Student(id:String,sid:String,name:String,age:Int) extends Person(id,name,age){
  val _sid:String=sid

  override def sleep(): Unit = {
    println("学生会睡觉")
  }

  override def printInfo(): Unit = {  //重写方法
    println(s"$id,$sid,$name,$age")
  }
}

class Teacher(id:String,tid:String,name:String,age:Int) extends Person(id,name,age){
  val _tid:String=tid

  override def sleep(): Unit = {
    println("老师会睡觉")
  }

  def teach(): Unit = {
    println("老师会上课")
  }
}

object DemoScalaClassExtends {
  def sleepTwice(person: Person):Unit={
    person.sleep()
    person.sleep()
  }

  def main(args: Array[String]): Unit = {
    val p1 = new Person("001", "p1", 20)
    p1.sleep()
    p1.printInfo()

    println("*"*50)
    val s1 = new Student("002", "s001", "s1", 12)
    s1.sleep()
    println(s1._sid)
    s1.printInfo()

    println("*"*50)
    val t1 = new Teacher("003", "t001", "t1", 24)
    t1.sleep()
    t1.printInfo()
    t1.teach()

    println("*"*50)
    // 多态:父类引用指向子类对象
    // 对同一类的对象(同一父类下的子类对象)调用相同的方法时,所表现出来的形态各不相同
    // 如果要形成多态,必须建立在继承的基础之上,并且在子类中要“重写”父类的方法
    sleepTwice(p1) //打印两遍人会睡觉
    sleepTwice(s1) //打印两遍学生会睡觉
    sleepTwice(t1) //打印两遍老师会睡觉
  }
}

5.样例类

package com.bigdata.scala

//样例类
//属性默认为val
//可以在任意位置定义
case class CaseStudent(id:String,sid:String,var name:String,age:Int)

/**
 * 1、样例类中定义的属性默认由val修饰,无法修改,可以手动指定为var
 * 2、样例类默认实现了序列化接口,样例类对象可以直接在网络中传输
 * 3、样例类默认给所有的属性都加上了类似Java中的get方法,如果属性由var修饰,则还会由类似set的方法
 * 4、样例类在创建对象的时候,不需要使用new关键字
 * 5、样例类默认会重写toString方法,打印样例类对象时会将所有的属性值进行输出
 */
//创建样例类
object DemoCaseClass {
  def main(args: Array[String]): Unit = {
    val s1: CaseStudent = CaseStudent("001", "s001", "s1", 20) //包含Apply方法
    println(s1.name)

    s1.name="修"
    println(s1.name)
  }

}

 

你可能感兴趣的:(java,开发语言)