scala学习笔记9 继承

本章要点:

  • extends,final关键字
  • 重写方法用override
  • 只有主构造器可以调用超类的主构造器
  • 可以重写字段
1、扩展类
可以给出子类需要而超类没有的字段和方法,或者重写超类的方法
2、重写方法

(1)重写方法必须和被重写方法具有相同的参数列表,返回类型必须和被重写方法的返回类型相同或者是返回类型的子类型。


 (2)重写方法的访问控制修饰符不能比被重写方法更严格(比如一个在父类中声明为public的方法重写成一个protected的方法)。


 (3)只有实例方法才能被重写,超类中的final方法不能被重写。


 (4)重写方法不能抛出新的检查异常,或者是抛出比被重写方法声明的检查异常更广泛的检查异常。


 (5)注意一种特殊情况:如果超类的方法版本中声明了检查异常,但重写的子类方法中没有声明,这时如果使用多态的方式进行调用,那么编译器认为你调用的是声明了异常的方法。


 (6)尽管多态是在编译时确定对象的类型,但在编译时,还是根据父类的方法声明进行程序检查。因此,如果子类中定义的方法,在父类中没有定义,则会出项编译错误。


3、类型检查和转换

要检测某个对象是否属于某个给定的类,可以用isInstanceOf方法。如果测试成功,可以用asInstanceOf方法将引用转换为子类的引用:

如果想要测试p是指向一个Employee对象,但又不是其子类的话,可以用:

if(p.getClass==classOf[Employee] )

4、受保护字段和方法

字段和方法声明为protected后可以被任何子类访问,但不能从其它位置看到。与java不同,protected的成员对于类所属的包而言是不可见的,如果需要可见,使用包修饰符。

protected[this]将访问权限限定在当前的对象,类似第5章的private[this]

访问修饰符的介绍:http://www.runoob.com/scala/scala-access-modifiers.html

5、超类的构造


6、重写字段

看不懂

7、匿名子类

匿名内部类也就是没有名字的内部类,正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码的编写。

但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口。

abstract  class  Person {
     public  abstract  void  eat();
}
 
class  Child  extends  Person {
     public  void  eat() {
         System.out.println( "eat something" );
     }
}
 
public  class  Demo {
     public  static  void  main(String[] args) {
         Person p =  new  Child();
         p.eat();
     }
}

运行结果:eat something

可以看到,我们用Child继承了Person类,然后实现了Child的一个实例,将其向上转型为Person类的引用

但是,如果此处的Child类只使用一次,那么将其编写为独立的一个类岂不是很麻烦?这个时候就引入了匿名内部类。

abstract  class  Person {
     public  abstract  void  eat();
}
 
public  class  Demo {
     public  static  void  main(String[] args) {
         Person p =  new  Person() {
             public  void  eat() {
                 System.out.println( "eat something" );
             }
         };
         p.eat();
     }
}

可以看到,我们直接将抽象类Person中的方法在大括号中实现了,这样便可以省略一个类的书写而且匿名内部类还能用于接口上。

interface  Person {
     public  void  eat();
}
 
public  class  Demo {
     public  static  void  main(String[] args) {
         Person p = new  Person() {
             public  void  eat() {
                 System.out.println( "eat something" );
             }
         };
         p.eat();
     }
}

由上面的例子可以看出,只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现

最常用的情况就是在多线程的实现上,因为要实现多线程必须继承Thread类或是继承Runnable接口。

8、抽象类
利用abstract来标记不能被实例化的类,通常是因为它的某些方法没有被完整定义。
abstract class Person(val name:String) {
 def id:Int
}
在scala中,不像java,你不需要对抽象方法使用abstract关键字,省去方法体就可以了。但是和java一样,含有抽象方法的
抽象类必须声明为abstract。
在重写超类的抽象方法时,不需要使用override
9、抽象字段
和抽象方法类似
10、构造顺序和提前定义
看的不是很懂(L3级别)
在超类的构造方法中调用方法时,被调用的方法可能被子类重写,因此它可能并不会按照你的预期行事。
有下列几种解决方法:
  • 将val声明为final,安全但并不灵活
  • 在超类中将val声明为lazy,安全但并不高效
  • 在子类中使用提前定义语法
所谓的提前定义语法可以让你在超类的构造器执行之前初始化子类的val字段。
class Ant extends {
override val range=2
} with Creature
11、scala继承层级
null,nothing等四种:http://www.fengfly.com/plus/view-171628-1.html
java的四种引用类型:http://blog.csdn.net/xiaobaiooo/article/details/43765195

编译器允许任何值被替换成()
12、对象相等性
当定义类class Item(val description:String,val price:Double)后,比较不同对象
final override def equals(other:Any)={
val that=other.asInstanceOf[Item]
if(that==null) false
else if (description==that.description && price==that.description) {
print("true")  }
else {
print("false") }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值