Scala 继承 访问修饰符 (六)

Scala 继承

面向对象的三大特征,封装继承多态,Scala作为一款面向对象编程语言,自然不会缺少继承

继承:子类继承父类,关键字extends , 单继承

基本使用

package hierarchy

class Animal {
  var name: String = _
  def run:String = name +"  running..."
}

class Dog extends Animal

class Cat extends Animal

object AnimalTest{
  def main(args: Array[String]): Unit = {
    val dog = new Dog
    val cat = new Cat

    dog.name = "小黑狗"
    cat.name = "小花猫"

    println(dog.run)
    println(cat.run)
  }
}

方法覆盖

父类定义的公共方法无法满足子类需求时,在子类中定义相同的方法,调用时以子类优先;

package hierarchy

class Person {

  def sleep: String = {
    "sleeping..."
  }
}

class SmallStudent extends Person{
  // 方法覆盖 关键字override

  override def sleep: String = "小学生在睡觉..."
}

class MiddleStudent extends Person


object PersonTest{
  def main(args: Array[String]): Unit = {
    val s1 = new SmallStudent
    println(s1.sleep)  // 小学生在睡觉...
    val s2 = new MiddleStudent
    println(s2.sleep)  // sleeping...
  }
}

类型检查和转换

类型检查使用:子类型.isInstanceOf[父类型]

println(s1.isInstanceOf[Person])  // true
println(s1.isInstanceOf[SmallStudent]) // true
println(s1.isInstanceOf[MiddleStudent]) // false

类型转换使用类型1.asInstanceOf[类型2]

// 父类型指向子类对象
val p: Person = s1.asInstanceOf[Person]
// val ms: MiddleStudent = s1.asInstanceOf[MiddleStudent]

// 将父类型强制转换为子类型
val ss = p.asInstanceOf[SmallStudent]

调用父类有参构造

结论:

  • 如果调用父类的有参构造方法,需要在extends 父类(父类的有参构造)
  • 子类的主构造器中,必须有父类的成员,并且不需要声明为val或者var
package hierarchy

class Color(var name: String) { // 父类没有无参的主构造器,只有一个接受单个参数的主构造器

}

// 子类必须提供一个有参的主构造器,形参必须出现父类主构造器中的参数
// 只能由子类的主构造器才能调用父类的主构造器

class Red(name: String) extends Color(name: String) {

  var level: String = _

  def this(name: String,level:String){
    this(name)
    this.level = level
  }
}

覆盖字段

结论:

  • 如果子类需要覆盖父类中的变量(var),子类中不需要var关键字和变量的类型
  • 如果子类需要覆盖父类中的常量(val),子类必须在父类常量的基础之上加上override关键字
  • 如果父类中的私有成员(private),子类是无法覆盖,原因是:父类中属性和getter/setter方法都是私有的
package hierarchy

class Product {

  // 可以覆盖
  var name: String = ""

  // 可以覆盖
      val price: Double = 0.0

  // 子类无法覆盖 属性私有  getter/setter私有
  private var address: String = "made in china"
}

// 覆盖父类中的公共属性
class Telphone extends Product {
  // name = "xxx"

  // 父类中var变量,子类覆盖时,无需override和类型信息
  name = "手机"

  // 父类中val常量,子类覆盖时,必须override
  override val price: Double = 10.5
}


object ProductTest {
  def main(args: Array[String]): Unit = {
    val telphone = new Telphone
    println(telphone.name)
    println(telphone.price)
  }
}

抽象类

类似于java的抽象类,使用的关键字依然是abstract

  • 抽象类,可能有抽象成员和普通成员
  • 子类继承抽象类,必须得实现抽象类的声明方法,如果未实现,子类依然是一个抽象类
  • 抽象类只能声明引用而不能创建对象
  • 在实现抽象类的抽象方式或者属性时,依然使用的是关键字override
package hierarchy

abstract class Fruit {
  // 抽象字段
  var name: String

  // 抽象方法
  def eat(): String
}


abstract class Apple extends Fruit {

}

class Banana extends Fruit {

  // 抽象属性和方法必须加override关键字
  override var name: String = _

  override def eat(): String = {
    "eat banana ..."
  }
}

object Fruit {
  def main(args: Array[String]): Unit = {
    val f1: Fruit = new Banana
    val f2: Banana = new Banana
    val f3: Fruit = new Fruit {
      override var name: String = _

      override def eat(): String = {
        ".........."
      }
    }

    println(f1.eat()) // eat banana ..
    println(f2.eat()) // eat banana ..
    println(f3.eat()) // ....
  }
}

访问修饰符

注意:

  • java中有四种访问修饰符:public、default、protected、private
  • scala中只有三种访问修饰符:default(public)、protected、private

访问权限修饰符

default 访问权限最大
protected 有关系的才可以访问(伴生类,伴生对象,子类)
private 伴生类 伴生对象可以访问

package hierarchy

class A {

  // 私有: 伴生类和伴生对象中方法
  private var name: String = _

  // 受保护限定:伴生类和伴生对象 以及子类
  protected var age: Int = _

  // 默认 public 所有
  var sex: Boolean = _
}

class C extends A {

}

object A {
  def main(args: Array[String]): Unit = {
    val a = new A()
    a.name
    a.age
    a.sex
  }
}

object B {
  def main(args: Array[String]): Unit = {
    val a = new A
    // a.name  // error
    a.sex
  }
}
private[this]

访问修饰符的限定,限定只能在伴生类中使用,去除伴生对象的可见性

// 伴生类限定
private[this] var address: String = _
protected[this]

访问修饰符的限定,限定只能在伴生类及其子类中使用,去除伴生对象的可见性

// 伴生类和子类限定
protected[this] var phone: Long = _
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值