Scala浅谈面向对象思想(OOP)
1、定义抽象类
在Scala中重写一个非抽象方法必须用override修饰,在子类中重写超类的抽象方法时,不需要使用override关键字,写了也可以,如下代码所示:
package org.apache.scala.day05
object ClazzDemo {
def main(args: Array[String]) {
val h = new Human
println(h.fight)
}
}
trait Flyable {
def fly(): Unit = {
println("I can fly")
}
def fight(): String
}
abstract class Animal1 {
def run(): Int
val name: String
}
class Human extends Animal1 with Flyable {
val name = "abc"
// 五个变量分别都赋值一次,那么{}也就相当于要执行五次
val t1, t2, (a, b, c), t3, t4 = {
println("ABC")
(1, 2, 3)
}
println(a)
println(t1._1)
println(t1.hashCode() + "\t" + t2.hashCode())
def fight(): String = {
"fight with 棒子"
}
//在Scala中重写一个非抽象方法必须用override修饰
override def fly(): Unit = {
println("Human fly ......")
}
//在子类中重写超类的抽象方法时,不需要使用override关键字,写了也可以
def run(): Int = {
1
}
}
打印输出:
当如果我们想定义一个抽象方法时,需要了解:不需要加abstract,若加了反而会报错,如示例图:
正确示例:
我们写一个抽象示例:
package org.apache.scala.day05
/**
* 描述: 定义抽象类
*/
trait MySQLDAO {
val id: Int
val name: String = "huangbo"
def add(o: Any): Boolean
def update(o: Any): Int
def query(id: String): List[Any]
def delete(id: Int) = {
println("delete one record")
}
}
//如果有多个trait的话,则使用with关键字即可
class DaoImpl extends MySQLDAO with Cloneable {
// 实现父类中的抽象方法,必须的
def add(o: Any): Boolean = true
def update(o: Any): Int = 1
def query(id: String): List[Any] = List(1, 2, 3)
// 给父类中的抽象字段赋值,必须的
override val id = 12
}
完整的抽象示例1:
package org.apache.scala.day05
trait MyLogger {
def log(msg: String) {}
}
trait Logger_A extends MyLogger {
override def log(msg: String): Unit = {
println("AAAAAA : " + msg)
}
}
trait Logger_B extends MyLogger {
override def log(msg: String): Unit = {
println("BBBBBB : " + msg)
}
}
class Person123(val name: String) extends Logger_A {
def sayHello(): Unit = {
println("Hi ,i'm name")
log("sayHello is invoked!")
}
}
/**
* 抽象类
*/
object MyLogger_Trait_Test {
def main(args: Array[String]) {
val p1 = new Person123("liudehua")
p1.sayHello()
val p2 = new Person123("zhangxueyou") with Logger_B
p2.sayHello()
}
}
打印输出:
完整的抽象示例2:
package org.apache.scala.day05
abstract class Programmer {
def getSkill(): String = "所有程序员都至少掌握一门编程语言。\n"
}
trait PHPer extends Programmer {
override def getSkill() = super.getSkill() + "我掌握PHP。"
}
trait Scalaist extends Programmer {
override def getSkill() = super.getSkill() + "我掌握Scala。"
}
trait Gopher extends Programmer {
override def getSkill() = super.getSkill() + "我掌握Golang。"
}
trait Rustacean extends Programmer {
override def getSkill() = super.getSkill() + "我掌握Rust。"
}
object TestTrait {
def main(args: Array[String]): Unit = {
val programmer1 = new Programmer with Scalaist with Gopher
val programmer2 = new Programmer with Scalaist with Gopher with PHPer
val programmer3 = new Programmer with Scalaist with Gopher with Rustacean
val programmer4 = new Programmer with Scalaist with Gopher with PHPer with Rustacean
println(programmer1.getSkill())
println(programmer2.getSkill())
println(programmer3.getSkill())
println(programmer4.getSkill())
}
}
打印输出:
完整抽象示例3:
package org.apache.scala.day05
trait Handler {
def handler(data: String) {}
}
trait Handler_A extends Handler {
override def handler(data: String): Unit = {
println("Handler_A :" + data)
super.handler(data)
}
}
trait Handler_B extends Handler {
override def handler(data: String): Unit = {
println("Handler_B :" + data)
super.handler(data)
}
}
trait Handler_C extends Handler {
override def handler(data: String): Unit = {
println("Handler_C :" + data)
super.handler(data)
}
}
class Person_TraitChain(val name: String) extends Handler_C with Handler_B with Handler_A {
def sayHello = {
println("Hello " + name)
handler(name)
}
}
object TraitChain_Test {
def main(args: Array[String]) {
val p = new Person_TraitChain("zhangxiaolong");
p.sayHello
}
}
打印输出:
2、模式匹配字符串
代码实现,示例1:
package org.apache.scala.day05
import scala.util.Random
/**
* 模式匹配字符串
*/
object Demo018_CaseDemo01 extends App {
val arr = Array("huangbo", "xuzheng", "wangbaoqiang", "xxxx")
val name = arr(Random.nextInt(arr.length))
// name模式匹配字符串
name match {
case "huangbo" => println("影帝来也...")
case "xuzheng" => println("喜剧笑星来了...")
case "wangbaoqiang" => println("实力干将来也...")
case _ => println("谁...???")
}
case class SS(x: Int)
val array = Array("huangbo", "xuzheng", "wangaboqiang", 5, SS(5))
val value = array(Random.nextInt(array.length))
println(value)
value match {
case "huangbo" => println("huangbo")
case "xuzheng" => println("xuzheng")
case z: Int if z > 6 => println(5)
case zz: Int => println(55)
case SS(xx) => println(xx)
case _ => println("else")
}
}
打印输出:
代码实现,示例2:
package org.apache.scala.day05
import scala.util.Random
/**
* 模式匹配
*/
object CaseDemo02 extends App {
//val v = if(x >= 5) 1 else if(x < 2) 2.0 else "hello"
val arr = Array("hello", 1, 2.0, CaseDemo)
val v = arr(Random.nextInt(4))
println(v)
// 模式匹配
v match {
case x: Int => println("Int " + x)
case y: Double if (y >= 0) => println("Double " + y)
case z: String => println("String " + z)
case _ => throw new Exception("not match exception")
}
}
case class CaseDemo()
打印输出:
3、匹配数组和元组
代码实现:
package org.apache.scala.day05
/**
* 描述: 匹配数组和元组
*/
object Demo018_CaseDemo03 extends App {
val arr = Array(1, 3, 5, 6)
arr match {
// case Array(1, x, y) => println(x + " " + y)
case Array(0) => println("only 0")
case Array(1, _*) => println("0 ...")
case _ => println("something else")
}
println("----------------------------------------------------------")
val lst = List(3, -1, 3)
lst match {
case 0 :: Nil => println("only 0")
case x :: y :: Nil => println(s"x: $x y: $y")
case 3 :: tail => println(tail)
case _ => println("something else")
}
println("----------------------------------------------------------")
val tup = (1, 2, 3, 7)
tup match {
// case (1, x, y, z) => println(s"1, $x , $y, $z")
case (_, z, 3, 7) => println(z)
case _ => println("else")
}
println("----------------------------------------------------------")
val ta = Array(Array(1, 2, 3), Array("a", "b", "c"))
ta match {
case Array(Array(x, y, z), _) => println(x, y, z)
case _ => println("else")
}
}
打印输出:
4、样例类的模式匹配
代码实现:
package org.apache.scala.day05
import scala.util.Random
/**
* 描述: 样例类的模式匹配
*/
object CaseDemo04 extends App {
val arr = Array(CheckTimeOutTask, HeartBeat(12333), SubmitTask("0001", "task-0001"))
arr(Random.nextInt(arr.length)) match {
case SubmitTask(id, name) => {
println(s"$id, $name")
}
case HeartBeat(time) => {
println(time)
}
case CheckTimeOutTask => {
println("check")
}
}
}
// case class是多例, 后面必须带参数
// case obejct是单例
case class SubmitTask(id: String, name: String)
case class HeartBeat(time: Long)
case object CheckTimeOutTask
打印输出:
5、测试unapply方法
代码实现:
package org.apache.scala.day05
/**
* 描述: 测试unapply方法
*/
object Demo019_Unapply extends App {
// 接收参数,返回对象, 一般用作工厂
def apply(value: Double, unit: String): Currency = new Currency(value, unit)
// 接收对象,返回参数, 一般用于模式匹配
def unapply(currency: Currency): Option[(Double, String)] = {
if (currency == null) {
None
}
else {
Some(currency.value, currency.unit)
}
}
}
class Currency(val value: Double, val unit: String) {}
无结果输出
6、访问方式
有3种
- 第1 种访问方式:如果key不存在会报错
- 第2 种访问方式:通过get方法获取, 如果key存在返回Some,如果key不存在返回None
- 第3 种方式: 更好的方式,可以指定当key不存在的时候返回一个默认值
在Scala中Option类型样例类用来表示可能存在或也可能不存在的值(Option的子类有Some和None),Some包装了某个值,None表示没有值
代码实现:
package org.apache.scala.day05
object Demo020_Option {
def main(args: Array[String]) {
val map = Map("a" -> 1, "b" -> 2)
// 第一种访问方式:如果key不存在会报错
var v1 = map("a")
println(v1) //打印输出结果:1
// 第二种访问方式:通过get方法获取, 如果key存在返回Some,如果key不存在返回None
val v2 = map.get("b") match {
case Some(i) => i
case None => 0
}
println(v2) //打印输出结果:2
// 第三种方式: 更好的方式,可以指定当key不存在的时候返回一个默认值
val v3 = map.getOrElse("c", 0)
println(v3) //打印输出结果:0
}
}
打印输出: