07_Scala_OOP中_封装_继承_多态_超类
【摘要】 1 继承
2 Scala中类型检查和转换 isInstanceOf asInstanceOf
3 超类 只有主构造器可以调用父类的构造器。辅助构造器不能直接调用父类的构造器
1 继承(代码复用) 当多个类存在相同的属性(变量)和方法时, 可以从这些类中抽象出父类
Scala基本语法
class 子类名 extends 父类名 {
类体
}
Scala继承好处
1 提高代码的复用性
2 提高 代码的 扩展性 和 维护性 【当我们修改父类时,对应的子类就会继承相应的方法和属性,不想暴露可以做成私有的】
Scala重写方法
说明: 重写一个非抽象方法需要用 override修饰符,调用超类(父类/父类的父类)的方法使用super关键字
def main(args: Array[String]): Unit = {
val sub = new sub()
sub.sayHello()
//sub.test200() //编译器不让过. 同包也不能访问,子类中访问(编译器控制,编译后是public,但是编译前语法禁止)
println("******")
sub.test1()
}
}
class Base {
var n1: Int = 1 // public int n1() ; public void n1_$eq(int x$1)
protected var n2: Int = 2 // public int n2(); public void n2_$eq(int x$1)
private var n3: Int = 3 // private int n3() , private void n3_$eq(int x$1) 内部和伴生对象中可用
def test1(): Unit = { // 默认 public void test1()
println("base 100")
}
protected def test2(): Unit = { // public void test2()
println("base 200")
}
private def test3(): Unit = { // private void test3() //private为私有权限,只在类的内部和伴生对象中可用
println("base 300")
}
def sayHi(): Unit = {
println("sayHi...")
}
}
class sub extends Base{
def sayHello(): Unit = {
this.n1 = 10 //默认权限,ok这里访问本质this.n1_$eq() -> n1_$eq(10)
this. n2 = 20 // protected 子类访问ok -> n2_$eq(20)
//this.n3 = 30 // private 报错
println("n1: " + this.n1 + "\tn2: "+ this.n2)
test1() //默认权限,ok
test2() // protected 子类访问ok
//test3() // private NG 内部和伴生对象中可用
}
override def test1(): Unit = { //需要显式的使用override方法从写
println("this is sub test1()")
super.test1() ////在子类中需要去调用父类的方法,使用super
}
}
Scala中类型检查和转换 (意义:可以判断传入对象的类型,然后转成对应的子类对象,进行相关操作【多态的特点】)
1 classOf获取对象的类名
2 要测试某个对象是否属于某个给定的类,用isInstanceof方法
3 强转为子类的引用:用asInstanceOf
classOf[String] 如Java的 String.class
obj.isInstanceOf[T] 如Java的obj instanceof T 判断obj是不是T类型
obj.asInstanceOf[T] 如Java的(T)obj 将obj强转成T类型
def main(args: Array[String]): Unit = {
println(classOf[String]) //class java.lang.String //ClassOf的使用,可以得到类名
var alex = "alex"
println(alex.getClass.getName) //java.lang.String //使用反射机制
var aa = new AA
var bb = new BB
val cc = new CC
aa = bb //将子类引用给父类(向上转型,自动)
val bb1 = aa.asInstanceOf[BB] //将父类的引用重新转成子类引用(多态),即向下转型
// bb1.sayHello()
tesTypeConvert(cc) //输出 CC
}
//参数多态代码 oop中一个父类的引用可以接收所有子类的引用,多态(参数多态)
def tesTypeConvert(num: AA) : Unit ={
if ( num.isInstanceOf[BB]) { //使用Scala中类型检查和转换
num.asInstanceOf[BB].sayHello() //num.asInstanceOf[BB],对num的类型没有任何变化,而是返回的是 BB
}
else if (num.isInstanceOf[CC]) {
num.asInstanceOf[CC].sayCC()
}
else {println("啥也不是,完犊子艹")}
}
}
class AA {
var name: String = "alex"
def sayHi(): Unit = {
println("Hi...")
}
}
class BB extends AA {
def sayHello(): Unit = {
println("hello")
}
}
class CC extends AA {
def sayCC(): Unit= {
println("CC")
}
}
超类
- Java:创建子类对象时,子类的构造器总是去调用一个 父类的构造器(显式或者隐式调用)
- Scala:类有一个主构器和任意数量的辅助构造器,而每个辅助构造器都必须先调用主构造器(也可以是间接调用)
- Scala 只有主构造器可以调用父类的构造器。辅助构造器不能直接调用父类的构造器 (Scala中无 Super 调构造器用法)
object ScalaBaseConstrator {
def main(args: Array[String]): Unit = {
//输出AAA父类 1 调用父类主构造器 extends AAA()
//BBB 主构造 2 调用本类 主构造器
//BBB 辅助构造 3 调 本类 辅助构造器
val bbb = new BBB("alex")
println("*****************")
// CCC父类 1 调父类主构造器
// DDD 主构造 2 调自身主构造器
val alex_ddd = new DDD("ALEX", 35)
println("******************")
// CCC父类 1 调父类主构造器
// DDD 主构造 2 调自身主构造器
// DDD 辅助构造器 3 DDD 辅助构造
val bob_ddd = new DDD("bob")
println("******************")
//CCC父类 1 调父类主构造器
//主构造器默认名字 2 父类辅助构造器
//EEE 主构造 3 本类主构造器
//EEE 辅助构造 4 new EEE(参数)先找到 extend CCC => CCC (def this()) => this("默认名字") 主构造器
val e_EE = new EEE("EEE")
//CCC父类 1 调父类主构造器
//主构造器默认名字 2 父类辅助构造器
//EEE 主构造 3 直接走到了 父类的主构造器
val e_Empty = new EEE()
}
}
class AAA (){
var name: String = _
println("AAA父类")
}
class BBB extends AAA(){
println("BBB 主构造")
def this (name: String) {
this // 必须调用主构造器
this.name = name
println("BBB 辅助构造")
}
}
class CCC (cName: String){
var name: String = cName
println("CCC父类")
def this() {
this("默认名字")
println("主构造器默认名字")
}
}
class EEE () extends CCC(){
println("EEE 主构造")
def this (name: String) {
this() // 必须调用主构造器
this.name = name
println("EEE 辅助构造")
}
}
class DDD (dName: String, dInt: Int) extends CCC(dName){
println("DDD 主构造")
def this (name: String) {
this(name, 3) // 必须调用主构造器
this.name = name
println("DDD 辅助构造")
}
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)