[scala-spark]6. 继承与特质trait
1. 继承
- 定义抽象类
abstract class Element{def contents:Array[String]
}
抽象类的方法没有实现,抽象类的类本身必须被abstract
修饰。而方法只要没有实现,它就是抽象的,不需要加abstract
。
- 定义无参方法
abstract class Element{def contents:Array[String]def height:Int = contents.lenghtdef width:Int = if(height==0) 0 else contents(0).length
}
无参数方法在Scala里十分常见。相对的如果带有空括号的方法,比如def height():Int ,被称为空括号方法。推荐使用的方式是:只要方法中没有参数且方法仅能够通过读取所包含对象的属性去访问可变状态(特指方法不能改变可变状态),就使用无参数方法。这个惯例支持统一访问原则。简单来说,就是说客户代码不应该由属性是通过字段实现还是方法实现而受到影响。例如我们可以把上述代码中的def 换成 val,这种转换会使运行更快。在Scala中调用空括号方法,省略括号是合法的,在无参数方法和空括号方法之间有着极大的自由程度。
abstract class Element{def contents:Array[String]val height:Int = contents.lenghtval width:Int = if(height==0) 0 else contents(0).length
}
总之,Scala鼓励定义将不带参数且没有副作用的方法定义成为无参数方法的风格。
- 定义子类
class ArrayElement(conts:Array[String]) extends Elements{def contents:Array[String] = conts
}
ArrayElement类用extends 继承Elements,ArrayElement获得了Elements的所有非私有属性成员,ArrayElement是Elements的子类,Elements是ArrayElement的超类。如果一个类没有extends,编译器会将该类隐式地继承scala.AnyRef,如同Java的Object类一样。
Scala中,子类可以重写父类属性,可以实现父类抽象属性,继承父类非私有属性。这几点都和Java相同。
- 重写方法和属性
Scala中的字段和方法属于相同的命名空间,这让字段可以重写无参数方法。比如下面:
class ArrayElement(conts:Array[String]) extends Elements{//实现父类的无参数方法(def contents:Array[String])val contents:Array[String] = conts
}
- 调用超类构造器和override关键词
class LineElement(s:String) extends ArrayElement(Array(s)){override def width = s.lengthoverride def height = 1
}
由于LineElement扩展了ArrayElement。并且ArrayElement的构造器带了一个参数Array[String],因此LineElement需要传给超类的主构造器一个参数。调用父类构造器,只要简单地把参数放在超类后面的括号里即可。
Scala要求,若子类成员重写了父类的具体成员则必须带有这个修饰符。但若子类实现的是父类的抽象成员时,则该修饰符也可以省略。若子类并未重写或实现其他基类的成员则禁用这个修饰符。
Scala中的多态和Java中的相同。
- 定义final成员
final def a : Int = {...}
final class b(a:Int){
...
}
- 定义工厂方法
定义一个工厂方法来生产Element的各个子类实例,隐藏了实现细节。
object Element {/*** 私有的类,隐藏实现细节** @param cons*/private class ArrayElment(cons: Array[String]) extends Elment {val contents = cons}private class UniformElement(ch: Char, override val height: Int, override val width: Int) extends Elment {private val line = ch.toString * widthdef contents = new Array[String](3);}private class LineElment(s: String) extends ArrayElment(Array(s)) {override val height: Int = 1override val width: Int = s.length}/*** 通过公有的方法,提供私有类的实例** @param contents* @return*/def elem(contents: Array[String]): Elment = new ArrayElment(contents)def elem(chr: Char, width: Int, height: Int): Elment = new UniformElement(chr, width, height)def elem(line: String): Elment = new LineElment(line)
}
2. 特质trait
特质是Scala中代码复用的基本单元。特质中封装了方法和字段的定义。特质功能非常强大。类可以混入任意多个特质,其主要的运用方式是:拓宽瘦接口为胖接口和实现可堆叠的改变。
trait A{val tyl : Stringdef method : Int {...}
}trait C{def method : Int {...}
}class D {...
}class B with A {override def toString = "B with A"
}class B extends D with A with C{...
}
一旦特质被定义,就可以用extends
或with
关键字,把它混入类中。特质就像带有具体方法的Java接口,它可以有正常的变量、方法,即类可以做到的事情,特质都可以除了没有构造器。还有一点类的super调用是静态绑定的,而特质则是动态绑定的,这也决定了特质可以实现堆叠式改变。
拓宽瘦接口为胖接口
瘦接口和胖接口的对阵体现了面向对象设计常会面临的实现者和接口用户之间的权衡。胖接口有更多方法,对于调用者来说更为方便,客户可以选择一个完全符合他们功能需要的方法。瘦接口有较少的方法,对于实现者来说简单,但是调用者却要为此写更多的代码,由于没有更多可选的方法,他们或许不得不选一个不太完美匹配的或是重写额外代码。 Java中的接口常常是过瘦而非过胖。Java中的CharSequence接口定义了4个方法。如果CharSequence包含全部的String接口,那实现者将为CharSequence定义一堆可能自己不需要定义的方法。 试想一下,一个特质拥有几个抽象方法,剩余的是大量具有具体方法的方法。接口用户只需要混入该特质,简单地实现抽象方法,就可以拥有所有的具体方法。这是Java中不能做到的。
[scala-spark]6. 继承与特质trait相关推荐
- Scala特质trait
Scala特质 章节目标 能够使用trait独立完成适配器, 模板方法, 职责链设计模式 能够独立叙述trait的构造机制 能够了解trait继承class的写法 能够独立完成程序员案例 1. 特质入 ...
- 2021年大数据常用语言Scala(三十一):scala面向对象 特质(trait)
目录 特质(trait) 作为接口使用 定义具体的方法 定义具体方法和抽象方法 定义具体的字段和抽象的字段 实例对象混入trait trait调用链 trait的构造机制 trait继承class 特 ...
- Scala之特质特质Trait
Scala之特质特质Trait 一.概述 Scala语言中,采用特质trait(特征)来代替接口的概念,也就是说,多个类具有相同的特征(特征)时,就可以将这个特质(特征)独立出来,采用关键字trait ...
- 大数据必学语言Scala(三十一):scala面向对象 特质(trait)
文章目录 特质(trait) 作为接口使用 定义具体的方法 定义具体方法和抽象方法 定义具体的字段和抽象的字段 实例对象混入trait trait调用链 trait的构造机制 trait继承class ...
- Scala 中的 特质(trait)
文章目录 特质(trait) 概念 语法 继承特质 继承单个trait 代码示例 继承多个特质 代码示例 定义具体的方法 代码示例 trait中定义具体的字段和抽象的字段 定义 代码示例 模板模式 代 ...
- Scala学习之路 (六)Scala的类、对象、继承、特质
一.类 1.类的定义 scala语言中没有static成员存在,但是scala允许以某种方式去使用static成员 这个就是伴生机制,所谓伴生,就是在语言层面上,把static成员和非static成员 ...
- scala基础之特质trait
Scala中,trait相当于Java中的接口,遇到需要使用Java接口的场景时,你就在Scala中可以使用trait了. 我们知道Java中你可以实现多个接口,那么Scala中,你也可以继承多个tr ...
- Scala 继承和特质
一.继承 1.1 Scala中的继承结构 Scala 中继承关系如下图: Any 是整个继承关系的根节点: AnyRef 包含 Scala Classes 和 Java Classes,等价于 Jav ...
- Scala 034 特质trait
文章目录 Scala 特质trait trait作为接口使用 trait中还可以定义具体的方法 trait中定义具体的字段和抽象的字段 使用trait实现模板模式 对象混入trait trait实现调 ...
最新文章
- 遮挡也能识别?地平线提出时序信息提升行人检测准确度|​CVPR 2020
- 实际上module(data) 等价于module.forward(data)的原因分析
- 安卓AsyncTack详解
- python入门语句_Python 快速入门笔记(5):语句
- 201521123111《Java程序设计》第14周学习总结
- Android中Activity总结
- 科大星云诗社动态20210808
- c语言ascii码表_新手小白整理C语言笔记备忘,带你十分钟理解C语言
- 【开源工程】之YUVPlayer1.6
- oracle vm 加大存储,Oracle VM VirtualBox下ubuntu虚拟机存储空间不够解决方案
- 转:Ajax与CustomErrors的尴尬
- Hibernate框架
- word转化为pdf android,如何将Word转化为PDF?
- 1000瓶药水和10只老鼠的问题及其扩展
- Matlab分析系统的动态性能
- nyist 第二次招新赛 I 董学姐与朱学姐的爱恨情仇
- ARMv8/GICv3中断路由
- 配置Druid数据源监控
- 【13】变分自编码器(VAE)的原理介绍与pytorch实现
- 免费刷会员和六钻工具?小心通过QQ传播的灰鸽子Backdoor.Win32.Gpigeon.gem
热门文章
- Jsch ssh登陆
- 升级到win10,安装visualstudio ,80端口被系统服务占用的解决
- iOS 动画总结----UIView动画
- 微软启用全新域名邮箱平台 Outlook.com
- puts(char *) gets(char *)
- 【ABAP】Cross client master/business data transfer guide(ALE I Doc)
- Oracle应用开发手记
- ORACLE相关的SHELL编程
- Application,Session和Cookies的区别
- K8s之ControllerRateLimiter简单理解