(Scala10) 继承

/**
  * 第10章 继承
  */


//########################### 10.1 继承类和继承方法重写 #################################
/**
  * 使用extends关键字继承
  * 用final关键字修饰的类不能被继承
  * 用final关键字修饰的方法不能被重写
  */
class Person {
  var name = ""

  def myName() = name

  //方法重写
  override def toString = name
}

//继承
class Employee extends Person {
  var salary = 0.0

  def descriptio = "An employee with name " + name + " and salary " + salary

  //方法重写
  override def myName(): String = "xxx"
}

//########################### 10.2 类型检查和转换 #################################

val em = new Employee()
em.isInstanceOf[Person] //判断类型
em.asInstanceOf[Person] //转为子类的引用
val p = classOf[Person] //获取对象的类名

//########################### 10.3 受保护的字段和方法 #################################
/**
  * 用关键字protected修饰的字段和方法,子类可见,所属包的其他类不可见
  */


//########################### 10.4 超类的构造 #################################
/**
  * 只有主构造器才能调用超类的构造器
  * Scala不能通过super(a)方式来调用超类的构造函数
  */
class Person2(val name: String, val age: Int) {
  override def toString = getClass.getName + "[name = " + name + ",age = " + age + "]"
}

//构造参数传入了超类构造函数的参数name2、age2
class Employee2(name2: String, age2: Int, val salary: Double) extends Person2(name2, age2) {
  override def toString = super.toString + "[salary = " + salary + "]"
}

//########################### 10.5 重写字段 #################################

/**
  * 子类改写父类或者抽象父类的字段,通过以下2种方式
  */
abstract class Person3 {
  def id: Int //抽象的方法,没有方法体
}

class Student3(override val id: Int) extends Person3 {
  println(id)
}

class SecreAgent extends Person3 {
  override val id = scala.util.Random.nextInt
  println(id)
}

/**
  * 注意如下限制
  * def 只能重写另一个def
  * val只能重写另一个val或者不带参数的def
  * var只能重写另一个抽象的var(即未被赋值的var)
  */

//########################### 10.6 匿名子类 #################################


class Person4(val name: String) {
  override def toString = getClass.getName + "[name=" + name + "]"
}

/**
  * 匿名类的变量类型为:Person4{def greeting: String; val greetin2: String} 这是一个结构类型
  */
val alien = new Person4("Fred") {
  def greeting = "Greeting,Earthling ! My name is Fred"

  val greetin2 = "Greeting,Earthling ! My name is Fred"
}

//########################### 10.7 抽象类 #################################
/**
  * 抽象类:可以通过abstract关键字标记不能被实例化的类.
  * 抽象方法:不用标记abstract,只要省掉方法体即可
  * 抽象字段:类可以拥有抽象字段,抽象字段就是没有初始值的字段
  */


abstract class Person5(val pname: String) {
  //No initializer--this is an abstract field with an abstract getter method
  val id: Int
  //Another abstract field,with abstract getter and setter methods
  var name: String

  //No method body -- this is an abstract method
  def idString: Int
}

class Employee5(pname: String) extends Person5(pname) {
  val id = 5
  var name = ">>>"

  def idString: Int = pname.hashCode() //ovveride keyword not required
}


//########################### 10.8 构造顺序和提前定义 #################################


/**
  * 当子类重写了父类的方法或者字段后,父类又依赖这些字段或者方法初始化,这个时候就会出现问题,比如:
  */

class Creature {
  val range: Int = 10
  val env: Array[Int] = new Array[Int](range)
}

class Ant extends Creature {
  override val range = 2
}

val Ant = new Ant
Ant.env.size //0
Ant.range //2

/**
  * 解决3种方法:
  * 1.将val生命为final,这样子子类不可改写(range=10,env.size=10)
  * 2.将超类和子类中的val生命为lazy,这样安全但并不高效(range=2,env.size=2)
  * 3.可以使用提前定义语法,可以在超类的构造器执行之前初始化子类的val字段
  */
class Bug extends {
  override val range = 3
} with Creature

val bug = new Bug
bug.env.size //3
bug.range //3

//########################### 10.9 Scala继承层级 #################################

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值