经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Scala » 查看文章
Scala-Unit5-Scala面对对象与模式匹配
来源:cnblogs  作者:给你一个公主抱  时间:2019/1/17 9:26:38  对本文有异议

  Java中的面向对象:万物皆对象。

  我们要封装数据,定义模板等操作,素以我们需要面向对象。

=========================================================================

一、Scala中的单例对象

  在java中用static关键字修饰方法或成员变量,作用是可以直接通过"类名."的方式调用方法或变量

  在Scala中没有static关键字,Scala给我们提供了单例对象的模式来实现,关键字是object

  1. object Person {
  2. //定义成员变量
  3. val name:String = "Hunter"
  4. //定义类方法
  5. def sleep(str:String):Unit= {
  6. println(str)
  7. }
  8. }
  9.  
  10. object ScalaDemo{
  11. def main(args: Array[String]): Unit = {
  12. print(Person.name)
  13. Person.sleep("睡得很香")
  14. }
  15. }

  在Scala中的object是一个单例对象,object中定义的方法和成员变量都是静态的,在其他的单例对象中可以直接通过“类名.”的方式进行调用。

  main方法也只能定义在object中,因为java中main方法为静态方法。

  通过class创建的类中定义的方法和对象不能直接调用,不许构造函数对象后才可调用。

 

二、Scala类与构造器的使用

  1.类的定义和使用,例子:

  1. class Person1 {
  2. //定义成员变量姓名、年龄
  3. var name:String = _
  4. var age:Int = _
  5. //注释:_的意思是不给定,可以在其他类或单例对象中调用赋值,所以用var定义
  6. }
  7.  
  8. //继承App特质,可以不写main方法,类似java的Test/Before
  9. object Test1 extends App{
  10. val p = new Person1
  11. p.name = "reba"
  12. p.age = 18
  13. println(p.name + p.age + "岁")
  14. }

  2.主构造器:写在类名后面的构造器是主构造器 

  1. class Person2 (name:String,age:Int){
  2.  
  3. }
  4.  
  5. object Test2 extends App{
  6. val p = new Person2("yangmi",24)
  7. println(p)
  8. println(p.toString) //这两行输出的都是地址,原因见辅助构造器
  9. }

  注意:主构造器里的变量没有var,val修饰不能被调用

  3.辅助构造器:定义在类内部的构造器,一个类中可以有多个辅助构造器

  1. class Person3 (var name:String,age:Int){
  2. var high:Int = _
  3. var weight:Int = _
  4.  
  5. //定义辅助构造器
  6. def this(name:String,age:Int,high:Int){
  7. this(name,age)
  8. this.high = high
  9. }
  10.  
  11. //辅助构造器可以定义多个
  12. def this(name:String,age:Int,high:Int,weight:Int){
  13. this(name,age)
  14. this.high = high
  15. this.weight = weight
  16. }
  17. }
  18.  
  19. object Test3 extends App{
  20. val p = new Person3("Hunter",34,180,140)
  21. p.weight = 150
  22. println(p.name + "身高:" +p.high + ",体重:" + p.weight)
  23. }

  注意:(1)辅助构造器内必须先声明主构造器中的所有变量,在声明自己的变量

     (2)Scala中主构造器中的变量如果没有被val、var修饰的话,是不能被访问的,
         相当于java没有给这个变量get/set方法;
         如果主构造器中的变量被val修饰,相当于提供了java中的get方法,
         如果主构造器中的变量被var修饰,相当于提供了java中的get和set方法。

  4.构造器的访问权限:private

    在主构造器或辅助构造器前添加private关键字修饰,即可限制其访问权限

  1. //定义私有主构造器
  2. class Person4 private(var name:String,age:int){
  3. var high:Int = _
  4. //定义私有辅助构造器
  5. private def this(name:String,age:Int,high:Int){
  6. this(name,age)
  7. this.high = high
  8. }
  9. }
  10.  
  11.  
  12. object ScalaDemo{
  13. def mian(args:Array[String]):Unit ={
  14. val p = new Person4("h",88)
  15. val p1 = new Person3(name = "r",age =18)
  16. println(p.name)
  17. }
  18.  
  19. }

 注意:编译时Idea不报错,运行时才会报错;

    但是编程时如果主构造器不是私有的,定义时会出现变量名的提示(如Person3,而Person4没有提示)

  5.类的访问权限,在类前添加private修饰

  测试:

  //测试封装类如下,[this]会根据情况变化为无、[scala04]父包、[demo]子包

  1. private[this] class Person5(var name:String,age:Int) {
  2. var high:Int = _
  3.  
  4. def this(name:String,age:Int,high:Int){
  5. this(name,age)
  6. this.high = high
  7. }
  8. }

  //测试运行单例对象如下:

  1. object ScalaDemo {
  2. def main(args: Array[String]): Unit = {
  3. val p = new Person5("h",18,182)
  4. println(p.name)
  5. }
  6. }

     1>>封装类在父包,省略this,测试类在父包       √
     2>>封装类在父包,省略this,测试类在子包       √
     3>>封装类在父包,添加this,测试类在子包       √
     4>>封装类在父包,添加this,测试类在父包     √
     5>>封装类在父包,添加demo,测试类在父包    ×
     6>>封装类在父包,添加demo,测试类在子包       ×
     7>>封装类在父包,添加scala04,测试类在子包   √
     8>>封装类在父包,添加scala04,测试类在父包   √
   
     1>>封装类在子包,省略this,测试类在子包      √
     2>>封装类在子包,省略this,测试类在父包      ×
     3>>封装类在子包,添加this,测试类在父包      ×
     4>>封装类在子包,添加this,测试类在子包      √
     5>>封装类在子包,添加Scala04,测试类在子包    √
     6>>封装类在子包,添加Scala04,测试类在父包    √
     7>>封装类在子包,添加demo,测试类在父包     ×
     8>>封装类在子包,添加demo,测试类在子包     √

   总结:(1)private[this]修饰类表示当前包下及其子包都可以访问,[this]可以省略;

      (2)若在子包中定义private类,只能子包访问,如想父包访问,需要在private后添加[父包名]

      (3)若在父包中定义private类,且添加[子包名],则父包与子包都无法访问该类

 

三、伴生对象:

  定义:在同一个类文件中,单例对象名与类名相同的两个单例对象和类,称之为伴生对象。

  1. class Person6 (private var name:String,age:Int){
  2. var high:Int = _
  3.  
  4. def this (name:String,age:Int,high:Int){
  5. this(name,age)
  6. this.high = high
  7. }
  8. }
  9.  
  10. object Person6{
  11. def main(args: Array[String]): Unit = {
  12. val p = new Person6("hunter",30)
  13. println(p.name)
  14. }
  15. }

  注意:单例对象可以访问其伴生对象类的私有成员变量和方法,

       但伴生对象他们必须在同一个类文件中。

 

四、Scala特质和混入特质

  特质:相当于java中的接口

  混入特质:相当与实现多个接口

  1. trait Animal {
  2. //定义未实现方法
  3. def eat(name:String)
  4.  
  5. //定义实现的方法
  6. def sleep(name:String):Unit={
  7. println(s"$name 在睡觉")
  8. }
  9. }
  10.  
  11. trait Running {
  12. def how(str:String)
  13. }
  14.  
  15. object Pig extends Animal with Running {
  16. override def eat(name: String): Unit = {
  17. println(s"$name 在吃鸡")
  18. }
  19.  
  20. override def how(str: String): Unit = {
  21. println(f"$str 在奔跑")
  22. }
  23.  
  24. def main(args: Array[String]): Unit = {
  25. Pig.sleep("reba")
  26. Pig.eat("wyh")
  27. Pig.how("hunter")
  28. }
  29. }

  注意:(1)Scala中没有implement,只有extends

     (2)Idea中ctrl+i与ctrl+o的区别:

        ctrl+i:实现未实现的方法

        ctrl+o:重写已经实现的方法

 

五、Scala抽象类

  1. abstract class AbstractDemo {
  2. def eat(food:String)
  3.  
  4. def sleep(how:String):Unit={
  5. println(s"$how->很香")
  6. }
  7. }
  8.  
  9. object AbstractImpl extends AbstractDemo {
  10. override def eat(food: String): Unit = {
  11. println(s"hunter is eating $food")
  12. }
  13.  
  14. override def sleep(how: String): Unit ={
  15. println(s"hunter 睡得$how")
  16. }
  17.  
  18. def main(args: Array[String]): Unit = {
  19. AbstractImpl.eat("大猪蹄子")
  20. AbstractImpl.sleep("很香")
  21. }
  22. }

  注意:Scala中可以先继承抽象类在继承特质,但是抽象类必须写在前面!!

 

六、模式匹配(match/case)

  以下为三个模式匹配的例子,分别匹配了字符串、数组、元祖三种类型:

  1. object MatchTest {
  2. def main(args: Array[String]): Unit = {
  3. def strMatch(str:String):Unit = str match {
  4. case "Hunter" => println("很帅?")
  5. case "reba" => println("真的美")
  6. case _ => println("what?")
  7. }
  8.  
  9. strMatch("Hunter")
  10. strMatch("hunter")
  11.  
  12. def ArrayMatch(arr:Any):Unit = arr match {
  13. case Array(1) => println("只有一个元素的数组")
  14. case Array(1,2) => println("有两个元素的数组")
  15. }
  16.  
  17. ArrayMatch(Array(1))
  18.  
  19. def tupleMatch(tuple:Any):Unit = tuple match {
  20. case (1,_) => println("元祖第一个元素为1,第二个元素为任意类型")
  21. case ("hunter",34) => println("这哥们老帅了")
  22. }
  23. tupleMatch(("hunter",34))
  24. }
  25. }

 

原文链接:http://www.cnblogs.com/HelloBigTable/p/10275550.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号