Scala—— 7.抽象

1.重写方法

class Person {
  var name: String = "tom"
 
  def printName() { //输出名字
    println("Person printName() " + name)
  }
 
  def sayHi(): Unit = {
    println("sayHi...")
  }
}
 
//这里继承Person
class Emp extends Person {
  //这里需要显式的使用override
  override def printName() {
    println("Emp printName() " + name)
    //在子类中需要去调用父类的方法,使用super
    super.printName()
    sayHi()
  }

2.类型检查和转换

要测试某个对象是否属于某个给定的类,可以用isInstanceOf方法。用asInstanceOf方法将引用转换为子类的引用。classOf获取对象名。
classOf[String]就如同Java的String.class。
obj.isInstanceOf[T]就如同Java的 obj instanceofT 判断obj是不是T类型。
obj.asInstanceOf[T] 就如同Java的(T)obj 将obj强转成T类型。

println(classOf[String]) // 输出
val s = "king"
println(s.getClass.getName) //使用反射机制
 
//isInstanceOf asInstanceOf
var p1 = new Person
var emp = new Emp
//将子类引用给父类(向上转型,自动)
p1 = emp
//将父类的引用重新转成子类引用(多态),即向下转型
var emp2 = p1.asInstanceOf[Emp]
emp2.sayHello()

3.超类的构造

类有一个主构造器和任意数量的辅助构造器,而每个辅助构造器都必须先调用主构造器(也可以是间接调用)。只有主构造器可以调用父类的构造器,辅助构造器不能直接调用父类的构造器,在Scala的构造器中,不能调用super(params)。

//父类Person
class Person(pName: String) {
  var name = pName
  println("Person...")
 
  def this() {
    this("默认的名字")
    println("默认的名字")
 
  }
}
 
//子类Emp继承Person
class Emp(eName: String, eAge: Int) extends Person(eName) {
 
  println("Emp ....")
 
  //辅助构造器
  def this(name: String) {
 
    this(name, 100) // 必须调用主构造器
    this.name = name
    println("Emp 辅助构造器~")
  }
 
  def showInfo(): Unit = {
    println("雇员的名字 ", name)
  }

4.覆写字段

子类改写父类的字段,称之为覆写/重写字段。覆写字段需要使用override修饰 .在Java中只有方法的重写,没有属性/字段的重写,准确的讲,是隐藏字段代替了重写。

object ScalaFiledOverride {
 
  def main(args: Array[String]): Unit = {
    val obj1: AAA = new AAA
    val obj2: BBB = new BBB
    //obj1.age => obj1.age() //动态绑定机制
    //obj2.age => obj2.age()
    println("obj1.age=" + obj1.age + "\t obj2.age=" + obj2.age)
  }
}
 
class AAA {
  val age: Int = 10 // 会生成 public age()
}
 
class BBB extends AAA {
  override val age: Int = 20 // 会生成 public age()
}

def只能重写另一个def(即:方法只能重写另一个方法)
val只能重写另一个val属性 或 重写不带参数的def
var只能重写另一个抽象的var属性

5.抽象属性

抽象属性:声明未初始化的变量就是抽象的属性,抽象属性在抽象类中
一个属性没有初始化,那么这个属性就是抽象属性。抽象属性在编译成字节码文件时,属性并不会声明,但是会自动生成抽象方法,所以类必须声明为抽象类。如果是覆写一个父类的抽象,那么override关键字可以省略[原因:父类的抽象属性,生成的是抽象方法,因此不涉及到方法重写的概念,override可以省略]

6.抽象类

在Scala中,通过abstract关键字标记不能被实力化的类。方法不用标记abstract,只要省掉方法体即可,抽象类可以拥有抽象字段,抽象字段/属性就是没有初始值的字段。

abstract class Animal {
  var name: String //抽象的字段
  var age: Int // 抽象的字段
  var color: String = "black" //普通属性
  def cry() //抽象方法,不需要标记 abstract
}

抽象类不能被实例。
抽象类不一定要包含abstract方法。抽象类中可以有实现的方法。
一旦类包含了抽象方法或者抽象属性,则这个类必须声明为abstract。
抽象方法不能有主体,不允许使用abstract修饰(与java不同)。
如果一个类继承了抽象类,则它必须实现抽象类中所有的抽象方法和抽象属性,除非它自己也声明为abstract类。
抽象方法和抽象属性不能使用private、final来修饰,因为这些关键字都是和重写/实现相违背的。
子类重写抽象方法不需要override,写上也不会错。

7.匿名子类

object boke_demo01 {
   
  def main(args: Array[String]): Unit = {
    val monster = new Monster {
      override def cry(): Unit = {
        println("...:)")
      }
 
      override var name: String = _
    }
    monster.cry()
  }
}
 
abstract class Monster {
  var name: String
 
  def cry()
}

————Blueicex 2020/2/17 12:06 blueice1980@126.com

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值