[Scala] Scala 学习笔记 (10) - 面向对象 (待补充)
程序员文章站
2022-06-14 22:35:49
...
Scala面向对象
1. 类 class
类的定义
// 定义一个类
class People {
// 定义属性
// var name:String = ""
var name:String = _ // name这里也可以直接使用占位符占位
val age = 10
private[this] val gender = "M" // gender是类People的一个私有属性,在外面是不能直接被调用的
def printInfo(): Unit = {
println(gender)
}
// 定义方法
def eat() = {
name + " eat banana."
}
}
类的调用:如果要调用一个class类,要先new一个class出来
object SimpleClassApp {
def main(args: Array[String]): Unit = {
// 类的调用
// new 一个类出来
val people = new People
people.name = "scala"
// println(people.gender) // gender是私有属性,不能直接调用
people.printInfo() // 但是gender在这里是被class本身调用,可以合法使用
val a = people.eat()
println(a)
}
}
2. 构造函数
主构造函数:构造函数的入参都可以作为class的属性来使用。
附属构造函数:第一行必须调用主构造器或者其他附属构造器;附属构造函数可以写一个或者多个。
object ConstructApp {
def main(args: Array[String]): Unit = {
// 创建一个对象
val girl = new Girl("Cindy", 18,"13000000000","somewhere")
println(girl.name + " : " + girl.age + " : " + girl.phone + " : " + girl.address)
girl.like()
println(girl.city)
}
}
// 构造函数中的参数以及类中的属性(非private的)都能直接能够当做对象的属性来使用
class Girl(val name:String, val age:Int) {
println("girl enter")
def like(): Unit = {
println(name + " like something.")
}
val city = "Shenzhen"
// 附属构造函数:第一行必须调用主构造器或者其他的附属构造器
var phone = ""
def this(name:String, age:Int, phone:String) {
this(name,age) // 第一行,调用主构造器
this.phone
}
// 再定义一个附属构造函数
var address = ""
def this(name:String, age:Int, phone:String, address:String) {
this(name,age,phone) // 这里的phone在前面的附属构造函数里面已经定义了,可以直接使用
this.address
}
println("girl exit")
}
3. 类的继承
3.1 发生继承时,当外面创建子对象的时候,首先会调用父类的构造方法,然后才是调用子类的构造方法;
如果子类里面的属性不是父类里面已经有的,前面要加val修饰符,否则外面是访问不到的
创建一个子类,继承上面的Girl类
// 类的继承
/**
*
* 类的继承
* littleGirl的前半部分littleGirl(name:String, age:Int)是一个主构造器,
* 继承了Girl这个class
* 并且littleGirl还加入了自己的参数major
*
* 发生继承时,当我们创建子对象的时候,首先会调用父类的构造方法,然后才是调用子类的构造方法
* 如果子类里面的属性不是父类里面已经有的,前面要加val修饰符,否则外面是访问不到的
*/
class littleGirl(name:String, age:Int, val major :String) extends Girl(name,age) {
println("littleGirl enter")
println("littleGirl exit")
}
调用这个子类
val littlegirl = new littleGirl("girl", 10, "computer")
println(littlegirl.name + " : " + littlegirl.age + " : " + littlegirl.major)
3.2 继承是发生在子类和父类之间的
如果想重写弗雷中已有的方法时,一定要添加override修饰符。
class littleGirl(name:String, age:Int, val major :String) extends Girl(name,age) {
println("littleGirl enter")
// toString是scala内置的一个object类的方法,如果想重写父类中已有的方法时,一定需要添加override修饰符
override def toString = "littleGirl toString"
println("littleGirl exit")
3.3 抽象类
类中有一个或者多个方法没有实现,换句话说:只有定义,没有实现。
这个抽象类是不能直接使用的,必须要通过实现了该抽象类的属性或者方法来使用。
子类重写父类中的属性或者方法,override可以不写。
定义一个抽象类
/**
* 抽象类的定义 abstract
* 抽象类可以有属性,有方法
* 属性和方法都只是定义,没有实现
* 这样的抽象类是不能直接被使用的
*/
abstract class Animal {
// 属性或方法只有定义没有实现
var name:String
var age:Int
def speak
}
因为这个抽象类不能直接使用,再定义一个子类继承上面的抽象类
/**
* 定义一个字类继承上面的抽象类,这个子类要么再被定义成抽象类,或者实现父类的spark方法
* 在Dog上面按住ctrl+回车,选择实现这个方法(Implement methods),选中所有的方法点OK
* 再给属性赋值,方法重写
* 子类重写父类中的方法或者属性,override可以省略不写
*/
class Dog extends Animal {
// 重写父类的属性
override var name: String = "Rich"
override var age: Int = 1
// 重写父类的方法
override def speak: Unit = {
println("wang wang wang")
}
}
最后再调用这个子类,此时子类的属性和方法都可以被调用。
object AbstractApp {
def main(args: Array[String]): Unit = {
// 因为抽象类Animal是不能直接被使用的,所以new一个它的子类,再调用它的方法
val dog = new Dog
dog.speak
}
}
思考:
抽象类的用途是什么?
上一篇: java实现集合对象排序(多个字段)