1.扩展类
class Fu { var name: String = _ var age: Int = _ def func() = { println("fu func....") } } //scala扩展类的方式与java一样,使用extends关键字 class Zi extends Fu { //在定义中给出子类需要而超类没有的字段和方法,也可以重写超类的方法 override def func(): Unit = { println("zi func ---") } def ziFun() = { println("zi other func ....") } }
final class Fu { //final修饰的类不能被扩展 var name: String = _ var age: Int = _ def func() = { println("fu func....") } }
class Fu { var name: String = _ var age: Int = _ final def func() = { //final修饰的方法,不能被重写 println("fu func....") } }
2.重写方法
class Fu { var name: String = _ var age: Int = _ def func1() = { println("fu func1....") } def func2() = { println("fu func2....") } } //scala重写一个非抽象方法,必须使用override修饰符 class Zi extends Fu { override def func1() = { println("zi func ....") } //调用超类方法,使用super关键字 super.func2() }
3.类型检查和转换
class Fu { var name: String = _ var age: Int = _ def func1() = { println("fu func1....") } } class Zi extends Fu { } object Zi extends App { //测试对象是否是给定类 isInstanceOf //测试成功使用asInstanceOf将引用转换为子类的引用 val p = new Zi if (p.isInstanceOf[Fu]) { val z: Fu = p.asInstanceOf[Fu] //转为父类型 /* p执行Fu类或者其子类,则p.isInstanceOf[Fu]为true p为null,p.isInstanceOf[Fu]为false, p.asInstanceOf[Fu]为null p不是一个Fu,p.asInstanceOf[Fu]抛出异常 */ //测试p指向的是Fu,而不是子类, if (p.getClass == classOf[Fu]) { } //类型检查和转换,使用模式匹配更好 p match { case s: Fu => println("fu") case _ => println("not fu") } } }
4.超类的构造
/* scala中,类有一个主构造器和任意多辅助构造器 每个辅助构造器必须以先前定义的辅助构造器或者主构造器调用开始 辅助构造器永远不可能直接调用超类的构造器 子类的辅助构造器最终都会调用主构造器,只有主构造器才能调用超类的构造器 */ class Fu(name: String, age: Int) { } class Zi(name: String, age: Int, val salary: Double) extends Fu(name, age) {//相当于子类将name age传递给父类 } object Zi extends App { }
5.重写字段
class Fu(val name: String) { override def toString: String = getClass.getName + " name= " + name } class Zi(codename: String) extends Fu(codename) { override val name = "abc" override val toString: String = "abc" } object Zi extends App { val p = new Zi("zhangsan") println(p.toString) } /* def只能重写另外一个def val只能重写另一个val或者不带参数的def var只能重写另一个抽象的var */
6.抽象类
//某个或某几个方法没有被完整定义 abstract class Person(val name: String) { def id: Int //没有方法体 抽象方法 } class Student(name:String) extends Person(name){ def id: Int = name.hashCode //不需要override }
7.抽象字段
//某个或某几个方法没有被完整定义 abstract class Person { val id: Int //没有初始化 带有抽象getter方法的抽象字段 var name: String //抽象字段 带有抽象的getter setter方法 } class Student(name: String) extends Person { override val id: Int = _ override var name: String = _ }
8.构造顺序和提前定义
class Creature { val range: Int = 10 val env: Array[Int] = new Array[Int](range) } class Ant1 extends Creature { override val range: Int = 2 } class Ant2 extends { //提前定义:超类的执行器执行之前,初始化子类的val字段 override val range: Int = 2 //Ant2的数组为长度为2的数组 } with Creature
9.对象相等性
class Person { } object Person extends App { /* AnyRef的eq方法 检查两个引用是否指向同一对象 equals方法调用eq */ val p1 = new Person val p2 = new Person val p3 = p1 println(p1.eq(p2)) // false println(p1.equals(p2)) //false println(p1.eq(p3)) //true println(p1==p2) //false
println(p1==p3) //true }
class Person(val name: String, val age: Int) { override def equals(obj: scala.Any): Boolean = { val that = obj.asInstanceOf[Person] if (that == null) { false } else { this.name == that.name && this.age == that.age } } override def hashCode(): Int = super.hashCode() } object Person extends App { /* AnyRef的eq方法 检查两个引用是否指向同一对象 equals方法调用eq */ val p1 = new Person("zhangsan",10) val p2 = new Person("zhangsan",10) println(p1.equals(p2)) // true println(p1==p2) //true 做完null检查后调用equals方法 }