类:可以看成一个模板
对象:表示具体的事物
定义类 回顾: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可以改变值,来修改对象的属性
}
}
构造器: 和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)构造器调用其他另外的构造器,要求被调用构造器必须提前声明。
封装就是把抽象出的数据和对数据的操作封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作(成员方法),才能对数据进行操作。
Scala中的public属性,底层实际为private,并通过get方法(obj.field())和set方法(obj.field_=(value))对其进行操作。所以Scala并不推荐将属性设为private,再为其设置public的get和set方法的做法。但由于很多Java框架都利用反射调用getXXX和setXXX方法,有时候为了和这些框架兼容,也会为Scala的属性设置getXXX和setXXX方法(通过@BeanProperty注解实现)。
(1)Scala 中属性和方法的默认访问权限为public,但Scala中无public关键字。
(2)private为私有权限,只在类的内部和伴生对象(同名的object)中可用。
(3)protected为受保护权限,Scala中受保护权限比Java中更严格,同类、子类可以访问,同包无法访问。
(4)private[包名]增加包访问权限,包名下的其他类也可以使用
(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)
}
注:相同的包下不能有同样的类名
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) //打印两遍老师会睡觉
}
}
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)
}
}