1.类和对象
类:可以看成一个模板
对象:表示具体的事物
定义类 回顾:Java中的类 如果类是public的,则必须和文件名一致。
一般,一个.java有一个public类
注意:Scala中没有public,一个.scala中可以写多个类。
基本语法
说明: (1)Scala语法中,类并不声明为public,所有这些类都具有公有可见性(即默认就是public)
(2)一个Scala源文件可以包含多个类
注:Bean属性(@BeanPropetry),可以自动生成规范的setXxx/getXxx方法
package com.bigdata.scalaimport scala.beans.BeanPropertyclass DemoScalaClass{//如果在属性前加上private,则同名的object仍可以访问该属性var id:String="001"val name:String="鸡排饭"//默认获得get,set方法,val只有get方法,var二者都有@BeanProperty var age:Int=10def 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.scalaclass DemoScalaClassConstruct(id: String, name: String, age: String) { //主构造器println("调用主构造器")//在scala中,一般以下划线开头来命名防止重名//定义即赋值,定义的时候必须赋值val _id: String = idval _name: String = nameval _age: String = agevar _gender: String = "男"var _clazz:String=_ //定义下划线,表示稍后使用//辅助构造器def this(id: String, name: String, age: String,gender:String) {//第一行调用必须调用默认构造器this(id,name,age)_gender=genderprintln("调用辅助构造器1")}def this(id: String, name: String, age: String, gender: String,clazz:String) {//辅助构造器可以有多个this(id, name, age,gender)_clazz=clazzprintln("调用辅助构造器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.scalaclass DemoApply(id:String){var _id:String=iddef printId(): Unit = {println(_id)}
}//伴生对象
object DemoApply{//apply方法会返回伴生类的对象,并返回该对象def apply(id: String): DemoApply = new DemoApply(id)
}
注:相同的包下不能有同样的类名
4.继承和多态
package com.bigdata.scalaclass Person(id:String,name:String,age:Int){val _id: String = idval _name: String = nameval _age: Int = agedef 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=sidoverride 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=tidoverride 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)}}