4. Scala对象 构造器,继承,抽象类,伴生类,特征
面向对象概述
封装:属性、方法封装到类中
继承:父类和子类之间的关系,子类的方法可以重写
多态:父类引用指向子类对象
类的定义和使用
package com.yy.scala
/**
* 类的定义和使用
*/
object SimpleObjectApp {
def main(args: Array[String]): Unit = {
val people = new People()
people.name = "Tom"
println(people.name+" " + people.age)
println(people.eat())
people.wachFootball("Barcelona")
people.printInfo()
}
}
class People {
//定义属性
var name:String = _
val age = 10
//private [this] 修饰的类只能在class中使用 不能被类外部调用
private [this] val gender = "male"
def printInfo() : Unit = {
println("gentder: "+gender)
}
//定义方法
def eat():String = {
name + " eat ..."
}
def wachFootball(teamName: String) : Unit = {
println(name + " is wtching match of " + teamName)
}
}
构造器
构造器分为主构造器和附属构造器,附属构造函数的名称是this, 可以有多个,编译器通过不同参数来区分
package com.yy.scala
object ConstructorApp {
def main(args: Array[String]): Unit = {
val person = new Person("Tim", 20)
println(person.name + " " + person.age + " " + person.school)
val person2 = new Person("Tome", 18, "male")
println(person2.name + " " + person2.age + " " + person2.school + " " + person2.gender)
}
}
//主构造器
class Person(var name:String, val age:Int) {
val school = "ustc"
var gender:String = _
//附属构造器
def this(name:String, age:Int, gender:String) {
//附属构造器的第一行代码必须要调用主构造器或其他附属构造器
this(name, age)
this.gender = gender
}
}
继承和重写
继承
Scala 使用 extends 关键字来继承一个类。继承会继承父类的所有属性和方法,Scala只允许继承一个父类。
重写
涉及到继承,使用overside关键字对父类有的属性和父类有的方法进行重写
package com.yy.scala
object ConstructorApp {
def main(args: Array[String]): Unit = {
val student = new Student("Lily", 17, "Math")
println(student.name + " " + student.age + " " + student.major + " " +student.school)
println(student.toString)
}
}
class Person(var name:String, val age:Int) {
val school = "ustc"
var gender:String = _
}
/**
* 继承
* new一个子类的时候会先调用父类的构造方法
* 子类继承父类的时候,父类有的属性不用写val或var,子类特有父类没有的一定要写val或var
*
* 重写
* 涉及到继承,可以通过overside关键字对父类有的属性和父类有的方法进行重写
*/
class Student(name:String, age:Int, var major:String) extends Person(name, age){
override val school: String = "Beijing University"
override def toString: String = "Person: override def toString: "+ school
}
抽象类
类的一个或多个方法没有完整的实现(只有定义没有实现),抽象类不能被实例化(new 一个对象)。
可以通过继承的方式使用,写一个实现类继承抽象类,对抽象类中属性和方法重写。
package com.yy.scala
/**
* 抽象类
*/
object Abstract {
def main(args: Array[String]): Unit = {
val apple = new Apple()
apple.eat
}
}
/**
* 类的一个或多个方法没有完整的实现(只有定义没有实现)
* 抽象类不能被实例化(new 一个对象)
* 可以通过继承的方式使用
* 写一个实现类继承抽象类,对抽象类中属性和方法重写
*/
abstract class Fruit {
def eat
val color: String
val shape: String
}
class Apple extends Fruit{
override def eat: Unit = {
println("eat apple")
}
override val color: String = "red"
override val shape: String = "sphere"
}
伴生类和伴生对象
如果有一个class,还有一个与class同名的object,那么就称这个object是class的伴生对象,class是object的伴生类。
最佳时实践:在Object的apply方法中去new Class
package com.yy.scala
/**
* 伴生类
*/
object ApplyApp {
def main(args: Array[String]): Unit = {
// for(i<-1 to 10){
// ApplyTest.incr
// }
// println(ApplyTest.count)//object本身就是一个单例对象
val a = ApplyTest() // 调用的是Object.apply方法
val b = new ApplyTest() // 调用的是Class.apply方法
b()
}
}
/**
* 伴生类和伴生对象
* 如果有一个class,还有一个与class同名的object
* 那么就称这个object是class的伴生对象,class是object的伴生类
* 最佳时实践:在Object的apply方法中去new Class
*/
class ApplyTest{
println("Class ApplyTest enter")
def apply() = {
println("Class ApplyTest apply")
}
println("Class ApplyTest leave")
}
object ApplyTest{
println("Object ApplyTest enter")
var count = 0
def incr = {
count = count+1
}
def apply() = {
println("Object ApplyTest apply")
new ApplyTest()
}
println("Object ApplyTest leave")
}
case class
case修饰的类调用的时候不用new创建对象,通常用在模式匹配。
package com.yy.scala
/**
* case修饰的类调用的时候不用new创建对象
* 通常用在模式匹配
*/
object CaseClassApp {
def main(args: Array[String]): Unit = {
println(Orange("orange").color)
}
}
case class Orange(color: String){
}
Trait 特征
Trait(特征) 相当于Java的接口。与接口不同的是,它还可以定义属性和方法的实现。Scala的类只能够继承单一父类,但是Trait可以继承多个。
trait定义的方式与类类似,但它使用关键字trait修饰。
package com.yy.scala
/**
* Trait(特征)
* 相当于Java的接口,与接口不同的是,它还可以定义属性和方法的实现
* 可以继承多个
*/
object TraitApp {
def main(args: Array[String]): Unit = {
val ps = new PrimaryStudent()
ps.run()
ps.eat("eggs")
ps.study("English")
}
}
trait Person2{
def eat(food: String)
def run(): Unit ={
println("person can run")
}
}
trait Student2{
def study(book: String)
}
/**
* 子类继承特征重写特征中的方法,特征中实现的方法可以不重写
*/
class PrimaryStudent extends Person2 with Student2{
override def eat(food: String) = {
println("primary student eat "+food)
}
override def study(book: String): Unit = {
println("primary student study "+book)
}
}