多态
scala中的多态同java
1.继承或者实现接口
2.重写父类方法
3.父类引用指向子类对象
4.接口指向实现类
//父类
abstract class Element {
def demo(): Unit ={
println("Element invoked")
}
}
//子类
class ArrayElement extends Element{
//重写demo方法
override def demo(): Unit = {
println("ArrayElement invoked")
}
}
class LineElement extends ArrayElement{
override def demo(): Unit = {
println("LineElement invoked")
}
}
//没有重写demo方法
class UniforElement extends Element
object ElementTest{
def invoked(e:Element): Unit ={
e.demo()
}
def main(args: Array[String]): Unit = {
invoked(new ArrayElement) //父类引用指向子类对象
invoked(new LineElement) //祖父类引用指向孙类对象
invoked(new UniforElement) //没有重写父类方法,所有调用输出祖宗类demo方法
}
}
/*
ArrayElement invoked
LineElement invoked
Element invoked
*/
模式匹配
//匹配字符串于java相似
//匹配数据类型
object CaseDemo {
def main(args: Array[String]): Unit = {
val arr = Array("hellow",1,-2.8,CaseDemo,3L)
val elem = arr(2)
println(elem)
elem match {
case x:Int => println("Int")
case x:Double if(x<=0) => println("Double")//优先匹配第一个
case x:Double => println("Double2")
case y:String => println(s"String:${y}")
case z:Long => println("Long")
case CaseDemo => {println("case demo")}
case _ =>{println("default")}
}
}
}
//数组,序列,元祖,映射
object CaseDemo2 {
def main(args: Array[String]): Unit = {
val arr = Array(1.0,1,7,0)
arr match {
case Array(1,2,x,y) => println(s"x:${x}, y:$y")
case Array(0,2,x,0) => println(s"x:${x}")
case Array(1,1,x,y) => println(s"----x:${x}, y:$y")//----x:7.0, y:0.0
case Array(1,1,7,y) => println("0")
case _ => println("default")
}
println("-----list----------")
val list = List(0,3,6,7)
println(list.head) //0
println(list.tail) //List(3, 6, 7)
list match {
case 0 :: Nil => println("0")
case x :: y :: Nil => println(s"x:${x},y$y")
case 0 :: f => println(s"f:${f}") //f:List(3, 6, 7)
case _ => println("default")
}
println("-----tuple----------")
val tup = (6,3,5)
tup match {
case (1,x,y) => println(s"x${x},y$y")
case (_,x,5) => println(s"x:${x}") //x:3
case _ => println("default")
}
println("------map------------")
val tupArr = Array(("a",1,1.0),("b",2,2.0))
val tuples: Array[(String, Int, Double)] = tupArr.map(x => (x._1,x._2,x._3))
val array = tuples.map {//注意这里map
case (a, b, 1) => (a, b + 10) //ArrayBuffer((a,11), (b,4.0))
case (a, b, c) => (a, b + c)
}
println(array.toBuffer) //ArrayBuffer((a,11), (b,4.0))
}
}
样例类
1.简单的说就是在class前面加个case
2.必须显示加上参数列表
3.可以做模式匹配
4.构造器中的参数如果不被声明var的话。默认是val类型,但是一般不推荐将构造器中的参数声明为var
5.自动创建伴生对象,同时在里面给我们实现了apply方法,使我们在使用的时候不需要new创建对象
6.实现自己的toString、hashCode、copy、equals等方法
//抽象类
abstract class Person
//样例类
case class Teacher(name:String, age:Int, teaNo:String ) extends Person
//样例类
case class Student(name:String, age:Int, stuNo:String ) extends Person
//样例类
case class NoBody(name:String) extends Person
object Person{
def main(args: Array[String]): Unit = {
//不需要new
//多态父类引用指向子类对象
val p: Person = Teacher("苍老师",18,"001")
val s: Person = Student("李同学",28,"0001")
//模式匹配
s match {
case Teacher(name,age,teaNo) => println(s"name:${name},age:${age},teaNo:$teaNo")
case Student(name,age,stuNo) => println(s"name:${name},age:${age},stuNo:$stuNo")
case NoBody(name) => println(s"name:${name}")
}
}
}
泛型
泛型类
通俗的讲,定义一个函数,函数参数可以接收任意类型,我们不可能一一列举所有参数类型重载函数
所有引入一个叫做泛型的东西,这个类型可以代表任意数据类型
例如List,在创建时可以传入不同的任意类型,那是因为List在定义时引用了泛型
class GenericClass {
private var context = 10
def setContext(value:Int)={
context = value
}
def getContext()={
context
}
}
class GenericClass2 {
private var context = "哈哈"
def setContext(value:String)={
context = value
}
def getContext()={
context
}
}
//泛型类
class GenericClass3[A]{
//声明一个泛型变量,程序运行时确定参数类型
private var context:A=_
def setContext(value:A) ={
context = value
}
def getContext()={
context
}
}
object GenericClassTest{
def main(args: Array[String]): Unit = {
//固定类型
val generic = new GenericClass
generic.setContext(1)
val generic2 = new GenericClass2
generic2.setContext("呵呵呵")
//可以自定义类型,确定类型
val generic3 = new GenericClass3[Int]
generic3.setContext(3)
val generic4 = new GenericClass3[String]
generic4.setContext("hello")
}
}
泛型函数
import scala.reflect.ClassTag
object GenericFunc{
//泛型函数
//注意ClassTag 导包
def mkArray[T:ClassTag](elem:T*) = Array[T](elem:_*)
def say[T1,T2,T3](a:T1,b:T2):T3={
(a,b).asInstanceOf[T3]
}
def main(args: Array[String]): Unit = {
//可以传任意相同类型
println(mkArray("呵呵呵","哈哈哈").toBuffer)
//可以传任意类型
println(say("张三",20))
println(mkArray(2,3,4).toBuffer)
println(say(1,"哈哈哈"))
}
}
泛型的上界和下界
即泛型的取值范围
定义几个具有继承关系的类:Class A->Class B->Class C-> Class D
定义泛型范围 D < T < B ->泛型T的范围是:B,C,D(从下往上)
1.上界 S <: T 泛型上界定义,也就是说S必须是泛型T的子类(或者本身)
UpperBound 类似于java中的T extends Comparable
2.下界 S >: T 泛型下届定义,也就是说S必须是泛型T的父类(或者本身)
LowerBound 类似于java中的T super Comparable
//上边界
class People
class Person extends People
class Teacher extends Person
class Student extends Person
class Animal
//上界 要么是Person类要么是其子类 不能是其父类
class UpperBound[S <: Person] {
def say(p:S)={
println(p.getClass)
}
}
object UpperBound{
def main(args: Array[String]): Unit = {
val p = new UpperBound[Person]
val t = new Teacher //子类
val s = new Student //子类
val p2 = new People //其父类不可以
p.say(t)
p.say(s)
//p.say(p2)
//Animal不属于Person及其子类
// val a = new Animal
// p.say(a)
}
}
//下边界
class Master
class Professor extends Master
class Teacher2 extends Professor
//下界 最低是Master的子类
class LowerBound[S >: Professor] {
def say(p : S)={
println(p.getClass)
}
}
object LowerBound{
def main(args: Array[String]): Unit = {
val m = new LowerBound[Master]
val p = new Professor //Master子类
val t = new Teacher2 //master子类
m.say(p)
m.say(t)
}
}