Scala语⾔学习三——类和对象
Scala 类和对象
类是对象的抽象,⽽对象是类的具体实例。类是抽象的,不占⽤内存,⽽对象是具体的,占⽤存储空间。类是⽤于创建对象的蓝图,它是⼀个定义包括在特定类型的对象中的⽅法和变量的软件模板。
scala 单例对象
在 Scala 中, 是没有 static 这个东西的, 但是它也为我们提供了单例模式的实现⽅法, 那
就是使⽤关键字 object, object 对象不能带参数。就是说每次调⽤这个单例对象的时候,不需要new,直接
ScalaSingleton.saySomething(“滚犊⼦…”)就完事,参数也是。
/**
* 单例对象
*/
object ScalaSingleton {
def saySomething(msg: String)={
println(msg)
anglababy}
}o
bject test{
def main(args: Array[String]): Unit ={
ScalaSingleton.saySomething("滚犊⼦....")
println(ScalaSingleton)
println(ScalaSingleton)
// 输出结果:
/
/ 滚犊⼦....
// cn.demo.ScalaSingleton$@28f67ac7
// cn.demo.ScalaSingleton$@28f67ac7
}
}
类的定义和实例化
在 Scala 中, 类并不⽤声明为 public,⽽是⽤class。
我们可以使⽤class定义类,然后⽤ new 关键字来创建类的对象,
Scala 的类定义可以有参数,称为类参数。
如果你没有定义构造器, 类会有⼀个默认的空参构造器
关于类中变量的定义
var 修饰的变量, 这个变量对外提供 getter setter ⽅法
val 修饰的变量, 对外提供了 getter ⽅法,没有 setter
如果主构造器中成员变量属性没有val var修饰的话,该属性不能被访问,相当于没有对外提供get
实例如下:
import java.io._
//没传⼊构造器,默认空参构造器
class Student {
// _ 表⽰⼀个占位符, 编译器会根据你变量的具体类型赋予相应初始值
// 注意: 使⽤_ 占位符是, 变量类型必须指定
var name: String = _          //⽤var定义了⼀个参数,可以getter setter
// val age: Int = _错误代码, val 修饰的变量不能使⽤占位符
val age: Int = 10        //⽤val定义了⼀个参数,可以getter,不可setter,所以不可变
}
def birthday(age1: Int){  //编写⼀个⽅法birthday
age=age+1
println ("我已经" + age1+"岁了");
}
}
object Test{
val name: String ="zhangsan"        //使⽤setter功能中,设⽴参数
def main(args: Array[String]): Unit ={
// 调⽤空参构造器,可以加()也可以不加
val student = new Student()            //new 来实例化类
student.name ="laoYang"          //使⽤setter功能中,设⽴参数,可改变参数值
// 类中使⽤ val 修饰的变量不能更改
// student.age = 20
println(s"student.name ====== ${student.name}${student.age}")      //⽤getter功能中,即调出该对象的函数
student.birthday(student.age)          //调⽤birthday该⽅法
}
以上实例的类定义了两个变量age和name,⼀个⽅法:birthday,⽅法没有返回值。
我们可以使⽤ new 来实例化类,并访问类中的⽅法和变量:
主构造器/辅助构造器
主构造器
定义在类后⾯的为类主构造器, ⼀个类可以有多个辅助构造器
定义个 2 个参数的主构造器
Student1(val name: String, var age: Int)
如果有了主构造器,之前的构造⽅法就可以不要了(下⾯的不要了)
//var name:String= _  //初始值是⼀个null
//var age:Int= _
辅助构造器
辅助构造器, 使⽤ def this
在辅助构造器中必须先调⽤类的主构造器
def this(name: String, age:Int, gender: String){
this(name, age)  //在辅助构造器中必须先调⽤类的主构造器
}
实例
class Student1 (val name: String, var age: Int){    //主构造器
var gender: String = _
def this(name: String, age:Int, gender: String){        //辅助构造器
object Test1{
def main(args: Array[String]): Unit ={
val s = new Student1("laoduan", 38)          //调⽤主构造器
println(s"${s.name}${s.age}")
val s1 = new Student1("laoYang", 18, "male")        //调⽤辅助构造器
println(s"${s1.gender}")
}
}
}
}
访问权限问题
构造器的访问权限
在构造器前⾯加修饰权限
说明主构造器是私有的,外部类或外部对象不能访问
class Teacher  private (name:String,age:Int){`
同样也适⽤于辅助构造器
private def this(name: String, age:Int, gender: String){
成员变量访问权限
成员变量前⾯如果加上了 private 修饰, 也就意味着, age 只能在这个类的内部以及其伴⽣类对象中可以访问修改, 其他外部类不能访问class Student3 private(val name: String,private var age: Int){
类的访问权限
类的前⾯加上private[this]标识这个类在当前包下都可见,当前包下的⼦包及其其他包不可见,伴⽣对象不能访问
类的前⾯加上private[包名]标识这个类在该包下及其⼦包可见
伴⽣对象/伴⽣类
在 Scala 中,是没有 static 这个东西的,但是它也为我们提供了单例模式的实现⽅法,那就是使⽤关键字 object。
Scala 中使⽤单例模式时,除了定义的类之外,还要定义⼀个同名的 object 对象,它和类的区别是,object对象不能带参数。可以不⽤new。
当单例对象与某个类共享同⼀个名称时,他被称作是这个类的伴⽣对象:companion object。你必须在同⼀个源⽂件⾥定义类和它的伴⽣对象。类被称为是这个单例对象的伴⽣类:companion class。类和它的伴⽣对象可以互相访问其私有成员。
伴⽣对象实例
/* ⽂件名:Marker.scala
author:菜鸟教程
url:www.runoob
*/
class Student3 private(val name: String,private var age: Int){
var gender: String = _
def this(name: String, age:Int, gender: String){
this(name, age)
}
def getAge =18
}
// 类的伴⽣对象
object Student3 {
def main(args: Array[String]): Unit ={
// 伴⽣对象可以访问类的私有⽅法和属性
val s3 =new Student3("Angelababy",30)
s3.age =29
println(s"${s3.age}")
// println(s"${s3.province}") 伴⽣类不能访问
}
}
apply ⽅法在伴⽣对象中的应⽤
class Student3 private(val name: String,private var age: Int){
var gender: String = _
def this(name: String, age:Int, gender: String){
this(name, age)
}
def getAge =18
}
伴⽣对象
object Student3 {
def apply(name:String,age:Int):Student3 ={
//apply⽅法中,可以对类进⾏初始化的⼯作,到时别⼈调⽤时候就可以直接调⽤不⽤new
new Student3 (name,age)
}
def main(args: Array[String]): Unit ={
val Student =Student3 ("林",12)//不⽤new
}
}
特质
Scala Trait(特质) 相当于 Java 的接⼝, 实际上它⽐接⼝还功能强⼤。
与接⼝不同的是, 它还可以定义属性和⽅法的实现。
⼀般情况下 Scala 的类只能够继承单⼀⽗类, 但是如果是 Trait(特质) 的话就可以继承多个,实现了多重继承。 使⽤的关键字是 trait .
trait T2 {
// 定义⼀个属性
val className: String ="NB ⼤神班"
// 定义⼀个没有实现的⽅法
def teacherSay(name: String)
// 定义个带有具体的实现的⽅法
def doSomething()={
println("改吃中午饭了...")
以上Trait(特征)由两个⽅法组成:isEqual 和 isNotEqual。isEqual ⽅法没有定义⽅法的实现,isNotEqual定义了⽅法的实现。⼦类继承特征可以实现未被实现的⽅法。
⽗类已经实现了的功能, ⼦类必须使⽤ override 关键字重写
⽗类没有实现的⽅法, ⼦类必须实现
抽象类
在 Scala 中, 使⽤ abstract 修饰的类称为抽象类. 在抽象类中可以定义属性、 未实现的⽅法和
具体实现的⽅法。
使⽤关键字abstract 定义⼀个抽象类
可以没有具体实现的⽅法
也可以有具体实现的⽅法
/*
* abstract 修饰的类是⼀个抽象类
* */
abstract class Animal {
println("Animal's constructor ....")
// 定义⼀个 name 属性
val name: String ="animal"
// 没有任何实现的⽅法
def sleep()
// 带有具体的实现的⽅法
def eat(f: String): Unit ={
println(s"$f")
}
}
混⼊特质
混⼊特质的两种⽅式
⽅式⼀,在创建该类的实例的时候混⼊特质
val student =new Student with Fly with ScalaTrait
//student.hello("⽼⽺")
student.fly("gaoxing")
student.small("丁丁")
⽅式⼆,在定义该类的时候混⼊特质
object ScalaTraitImpl extends ScalaTrait with Fly{
// 如果特质中某个⽅法有具体的实现,在⼦类继承重写的时候,必须使⽤override关键字
override def small(name: String): Unit ={
println(s"丁丁对 $name 哈哈⼤笑")
}}
继承