Scala面向对象—类详解2(继承相关)
1、单例类
package com.zzzy class AAA {//单例 /*//java 思路--私有化构造方法,提供公开的getAAA 行不通 private def this(){ this() } def getAAA():AAA={ val aaa = new AAA() return aaa } */ }
package com.zzzy //单例类 //伴生类 class BBB private(){//1私有化构造方法 } //伴生对象 object BBB{ //不写apply private val bbb=new BBB()//2创建一个私有对象 def getBBB:BBB={//3提供了一个公开的get方法 bbb } }
package com.zzzy object test { def main(args: Array[String]): Unit = { val b1 = BBB.getBBB val b2=BBB.getBBB println(b1==b2)//true } }
2、object的继承和App
package com.zzzzy abstract class Register {//定义一个抽象类 //抽象方法(没有方法体,只有方法定义) def regist(name:String) def unregist(name:String) }
package com.zzzzy //实现用extends object User1 extends Register { override def regist(name: String): Unit = { println(name+"注册了") } override def unregist(name: String): Unit = { println(name+"注销了") } }
package com.zzzzy class User2(n:String) extends Register {//主构造方法 override def regist(name: String): Unit = { println(name+"注册"+n) } override def unregist(name: String): Unit ={ println(name+"注销"+n) } }
package com.zzzzy object test extends App {//1如果一个对象继承App可以不需要main方法直接运行 /*def main(args: Array[String]): Unit = { println("aaa") }*/ println("bbb") //2让一个object实现一个抽象类用关键字extends 重写未实现的方法 User1.regist("小敏") User1.unregist("笑笑") //3让一个class实现一个抽象类用关键字extends 重写未实现的方法可以有构造方法 new User2("白白").regist("lili") new User2("白白").unregist("jack") }
3、类的继承
package com.zzzzzy class Person { var name:String=_//必须给类型,无法推断 var age:Int=_ private var num=99 def show(): Unit ={ print("父类的方法") } }
package com.zzzzzy class Student extends Person { //不能重写被final修饰的方法 var sex:Char='男' override def show(): Unit = { println("重写父类的方法show") } def speak(): Unit ={ //调用了父类的属性 实测在运行中无法使用 /*println(super.age) print(super.name)*/ //私有属性num无法通过super找到 super.show()//父类的方法 show()//子类重写的 } }
package com.zzzzzy object test extends App { val stu = new Student stu.speak() //多态的向上转型 var s:Person=new Student() //还能得到子类特有的方法和属性吗?不能 s.show()//调用的为子类重写的方法 println(s.name)//null println(s.age) }
4、类型检查和类型转换
package com.zzzzzzy class Person(name:String,age:Int){ var name1="小明" var age1=50 def show(): Unit ={ println(name+"\t"+age) } }
package com.zzzzzzy //在一个scala文件中可以定义n个类 写在一行必须写; 大括号可以省略 class Emp extends Person("李四",40) class Student extends Person("张三",30)
package com.zzzzzzy object test extends App { val em = new Emp em.show() val stu = new Student stu.show() println("---------------------") //判断某个对象是否是某个类型 val ss= new Student() //继承关系上 is a println(ss.isInstanceOf[Person]) //转换--向上转型 val pp: Person = ss.asInstanceOf[Person] pp.show() }
5、protected关键字
package com.yz.extendz class Animal {//父类 A和B都不是Animal的子类。那么属性的可使用情况如下 val a=100 //A类可用 //B类可用 protected val b=200 protected [this] val c=300 protected [extendz] val d=400//yz为包名 //A类可用 //这里四个属性,只要是Animal的子类都可以使用,无论在不在同一个包中 }
package com.yz.extendz class Cat extends Animal{ val y=888 def show: Unit ={ println(s"$a-------$b------$c---------$d") } }
package com.yz.extendz class Dog extends Animal { val x=999 def show: Unit ={ println(s"$a-------$b------$c---------$d") } }
package com.yz.extendz class A { def show: Unit ={ val animal = new Animal println(animal.a) println(animal.d) } }
package com.yz2 import com.yz.extendz.Animal class B { def show: Unit ={ val animal = new Animal println(animal.a) } }
6、匿名子类
package com.yz3 class Person { def aaa="中国" }
package com.yz3 object test extends App { val pp= new Person { override def aaa: String = "新中国" } //这个过程中产生了一个匿名子类【发生重写,子类重写父类方法但是又没有显示的定义处理----匿名】 val result = pp.aaa println(result) //定义方法 println("-------------------") def show(p:Person): Unit ={ println(p.aaa) } //调用 show(new Person) }
7、抽象
package com.yz4 abstract class Animal {//可以用于抽象或非抽象方法 拥有抽象字段/非抽象字段 //抽象字段(没有初始值) val count:Int //非抽象字段 val num=100 //抽象方法 def aaa:String //非抽象方法 def bbb: Int ={ 10 } }
package com.yz4 class Cat extends Animal { //重写抽象方法 override def aaa: String = {"你好"} override val count: Int = 666 }
package com.yz4 object test extends App { val cat = new Cat val aaa: String = cat.aaa val bbb: Int = cat.bbb println(aaa+bbb) }
8、特质(java接口)
package com.yz5 trait Log { //非抽象方法 抽象时super调用时会出错 def showa:String={ "原始的" } }
package com.yz5 trait ALog extends Log { override def showa: String = { super.showa println("ALog重写的方法") "ALog" } }
package com.yz5 trait BLog extends Log { override def showa: String = { println("BLog重写的方法") super.showa "BLog" } }
package com.yz5 class CCC extends ALog with BLog {//继承两个特质 //showa()//默认应该调用最右边的特质中的同名方法【发生同名,以右边为主】 override def showa: String = { super.showa } }
package com.yz5 object test extends App { val ccc = new CCC //条件:ALog和BLog重写方法中调用了super.showa ccc.showa//默认把所有的都运行出来(ALog和BLog中的都运行了)没办法只运行左边的 }