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)
  }
}
posted @ 2019-11-28 11:29  YanceyY  阅读(569)  评论(0)    收藏  举报