Scala学习:调用超类构造器和override修饰符的使用
创始人
2024-04-19 02:40:56
0

调用超类构造器

现在你有了两个类组成的完整系统:抽象类Element,和扩展它的具体类ArrayElement。或许你还在设想其它表达元素的方式。比方说,客户或许想要创造由给定单行字串构成的布局元素。面向对象编程让使用新数据变体扩展系统变得容易。只要加入子类即可。例如,代码10.6展示了扩展ArrayElement的LineElement类:

  1. class LineElement(s: String) extends ArrayElement(Array(s)) {  
  2.  override def width = s.length  
  3.  override def height = 1 
  4. }  

代码 10.6 调用超类构造器

51CTO编辑推荐:Scala编程语言专题

由于LineElement扩展了ArrayElement,并且ArrayElement的构造器带一个参数(Array[String]),LineElement需要传递一个参数到它的超类的主构造器。要调用超类构造器,只要把你要传递的参数或参数列表放在超类名之后的括号里即可。例如,类LineElement传递了Array(s)到ArrayElement的主构造器,把它放在超类ArrayElement的名称后面的括号里:

  1. ... extends ArrayElement(Array(s)) ...  
有了新的子类,布局元素的继承级别现在看起来就像展示在图释10.2中的那样了。

 LineElement的类关系图

图释 10.2 LineElement的类关系图

使用override修饰符

请注意LineElement里width和height的定义带着override修饰符。你在6.3节中的 toString方法中看到过。Scala里所有重载了父类具体成员的成员都需要这样的修饰符。如果成员实现的是同名的抽象成员则这个修饰符是可选的。而如果成员并未重载或实现什么其它基类里的成员则禁用这个修饰符。由于类LineElement的height和width重载了类Element的具体成员定义,override是需要的。

这条规则给编译器提供了有用的信息来帮助避免某些难以捕捉的错误并使得系统的改进更加安全。例如,如果你碰巧拼错了方法名或偶尔传递给它不同的参数列表,编译器会回应错误信息:

  1. $ scalac LineElement.scala  
  2. .../LineElement.scala:50:  
  3. error: method hight overrides nothing  
  4. override def hight = 1 
  5. ˆ  
系统改进的时候,override公约显得更重要。假设你定义了一个2D画图方法库。你把它公开,并广泛使用。库的下一个版本里你想在你的基类Shape里增加一个使用以下签名的新方法:

  1. def hidden(): Boolean 
你的新方法将被用在许多画图方法中去决定是否需要把形状画出来。这或许会产生显著的提速,但你不可以冒着破坏客户代码的风险做这件事。毕竟客户说不定已经使用不同的hidden实现定义了Shape的子类。或许客户的方法实际上是让对象消失而不是检测是否对象是隐藏的。因为这两个版本的hidden互相重载,你的画图方法将停止对象的消失,这可真不是你想要的!这些“意外的重载”就是被称为“脆基类”问题的最通常的表现。这个问题是指如果你添加了新的成员到类层级的基类中(通常我们称为超类),你会有破坏客户代码的风险。

Scala不能完全解决脆基类问题,不过它与Java相比有所改善。Java1.5中,@Override标注被引入并与Scala的override修饰符起相同的工作,不过不像Scala的override,它不是必需的。如果画图库和它的客户是用Scala写的,那么客户的hidden原始实现就不会有override修饰符,因为这时候还没有另外一个使用那个名字的方法。一旦你添加了hidden方法到你Shape类的第二个版本,客户的重编译将给出像下列这样的错误:

  1. .../Shapes.scala:6: error: error overriding method  
  2. hidden in class Shape of type ()Boolean;  
  3. method hidden needs 'override' modifier  
  4. def hidden(): Boolean =  
  5. ˆ  

也就是说,代之以错误的执行,你的客户将得到一个编译期错误,这常常是更可取的。

【相关阅读】

  1. Scala:重载方法和字段及定义参数化字段
  2. Scala程序中的扩展类
  3. 在Scala中定义无参数方法
  4. 学习Scala的二维布局库和抽象类
  5. Scala学习:叫名参数by-name parameter

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
Windows恶意软件20年“... 在Windows的早期年代,病毒游走于系统之间,偶尔删除文件(但被删除的文件几乎都是可恢复的),并弹...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...