• Scala学习笔记(二)


    Scala面向对象:

    类:

    声明类(一个源文件中可以包含很多public的类)
    getter和setter
    构造函数(主构造器和附属构造器)
    继承(extends)
    重写父类方法(override def)
    重写字段(override val,override var)

    1.声明类

    /**
    * 
    * 在scala 中,类默认是public,而且一个源文件可以包含多个public,源文件名可以和文件中定义的类名不一致
    */
    class Person {
    val name:String = "jack"
    //普通类不允许声明一个变量不给任何值的指定
    var age:Int = _ //var 可以不指定值,给个占位符
    //定义一个私有成员
    // private[this] val gender:String = "male" //private 在哪个包能访问,其他的包不能访问
    private[this] var gender:String = "male"
    //可以通过暴露一个getter来访问类中的私有成员
    def getGender:String = {
    this.gender
    }
    def setGender(gender:String){
    this.gender = gender
    }
    //定义成员方法
    def sayHello(msg:String){
    println(msg)
    }
    }
    object Person{
    def main(args: Array[String]): Unit = {
    //默认无参构造函数,可以不用带括号
    val p = new Person
    println(p.name)
    p.age = 18
    println(p.age)
    //跟java中一样,不能对私有成员进行访问 p.gender
    println(p.getGender)
    p.setGender("nonFemale")
    println("new Gender: "+p.getGender)
    p.sayHello("today is very fine,i like it")
    }
    }

    2.构造函数:

    //class 有一个默认的无参构造器
    //带参的主构造器,就是在类名后指定参数,主构造器的参数会被编译成类的成员变量(前提:参数必须有val或者var)
    class Book(val name :String ,var price:Float) {
        //类定义中的语句其实就是在主构造器方法体中
        println("这是在Book类的主构造器")
        private[this] var author :String = _
      //附属构造器,名称一定是this,参数不能带var或者val
       def this (name:String,price:Float,author:String){
           //一定要在第一行调用主构造器
         this(name,price);
         this.author = author
         println("这是在Book类附属构造器中")
      }
        def  sayHello{
            println("hello world")
        }
       sayHello
    }
    object Book{
        def  main(args:Array[String]):Unit = {
         val b  = new Book("hadoop权威",100,"张三")
          println(b.name)
          println(b.price)
          b.price=80F;
          println("new price " + b.price);
        }
    }

    3.继承:

    class TestExtends {
    }
    //先执行父类的构造函数,在执行子类的构造函数
    //子类继承父类的成员变量,所以在主类构造器中的相应参数可以不带val或者var,子类特有的成会员变量应该带val或者var
    class Teacher(val name:String,val  age :Int ){
        val major :String = "math";
        println("在Teacher的主构造器中......")
    }
    class CollegeTeacher(name:String,age:Int,school:String) extends  Teacher(name,age){
    //重写父类中的成员变量, 必须加override修饰符
        override  val major:String = "HighLevelMath"
        println("在CollegeTeacher的主构造器中......")
    //在父类中已经实现的方法,子类重写时一定要加override
      override def toString: String="override toString......"
    }
    object  Runner{
      def main(args: Array[String]): Unit = {
        val ct = new CollegeTeacher("tom",33,"TsingHua")
        println(ct.toString)
        println(ct.major)
      }
    }

    抽象类(abstract class):

    类的一个或者多个方法没有完整的定义
    声明抽象方法不需要加abstract关键字,只需要不写方法体
    子类重写父类的抽象方法时不需要加override
    父类可以声明抽象字段(没有初始值的字段)
    子类重写父类的抽象字段时不需要加override,否则需要override

    class TestAbstractClass {
    }
    //定义抽象类,要加abstract关键字
    abstract class AbstractParent {
      //可以定义有初始化的成员
      val name: String = "jack"
      //也可以定义没有初始化的成员,即抽象成员
      val age: Int
      //可以定义有具体是实现的方法
      def add(x: Int, y: Int) = x + y
      //也可以定义抽象方法
      def concat(a: String, b: String): String
      println("in the abstract parent......")
    }
    class son extends AbstractParent {
      //抽象的成员或者方法 在子类中实现时,不需要加override
      //抽象父类中的抽象成员在子类中必须实现
      //给个占位符或者具体值
      val age:Int = 18
      //抽象父类中的抽象方法必须在子类中实现
      def concat(a:String,b:String):String = a+b
      //重写抽象父类中的成员或者方法 ,必须加override
      override  val name :String = "tom"
      override  def add(x:Int,y:Int)= x+ y + 10
      println("in the son")
    }
    object son{
      def main(args: Array[String]): Unit = {
        val s = new son
        println("add function " + s.add(4,5))
      }
    }

    特质(trait)—-对比java8中的接口

    字段和方法的集合
    混入类中
    通过with关键字,一个类可以扩展多个特质

    class TestTrait {
    }
    class AbstractParent01 {}
    //定义一个trait特质
    trait Logger {
    //trait 中也可以定义抽象方法
      def append(msg: String): Unit
    //trait 中可以定义具体实现的方法
      def log(info: String) {
        println("INFO: logging in traint Logger......" + info)
      }
    }
    trait ConsoleLogger extends Logger {
    //子trait中可以实现父trait中的抽象方法,也可以不去实现,保持抽象
      def append(msg: String): Unit = {
        println("append in the ConsoleLogger......")
      }
    //子trait可以重写父trait中有具体实现的方法,一定要加override关键字
      override def log(info: String) {
        println("INFO: logging in traint Logger......" + info)
      }
    }
    //通常用with来“继承”trait, 但是如果子类没有其他的父类,则用extends 关键字来“继承”trait
    class ClassA extends AbstractParent01 with Logger {
    //必须实现trait中的抽象方法
      def append(msg: String) {}
      val name: String = "jack"
    }
    class ClassB extends ConsoleLogger {
    }
    //定义一个普通类,在定义时没有指定继承任何trait,但是在创建时,可以临时混入trait
    class ClassC{
    }
    object Runner01 {
      def main(args: Array[String]): Unit = {
        val ca = new ClassA
        println(ca.name)
        ca.log("Successfully with a trait")
        println("-------------------")
        val b = new ClassB
        b.log("User zhangsan loged in")
        println("------------------")
    //可以在创建对象时混入trait,扩展类的功能
        val c = new ClassC with ConsoleLogger
        c.log("Successful with  a trait  when instaniating a class")
      }

    apply方法

    单例对象

    class TestApply {
    }
    class AAA{
      def test(): Unit ={
        println("worked in class AAA")
      }
      def apply(): Unit ={
        println("apply in  class AAA")
      }
    }
    object  AAA{
    //注意:此处的new AAA()是调用class AAA的构造器,返回的是AAA的是实例对象
    //相当于一个创建类实例的普通工厂方法
    //def apply()= new AAA()
    //改造一下,就成了一个创建单例对象的工厂方法
      var aaa:AAA = _
      def apply() =  if(aaa == null ){aaa= new AAA();aaa}else aaa
    }
    object  AAA0{
      def apply(): Unit ={
        println("apply in object AAAo")
      }
    }
    object Runner{
      def main(args: Array[String]): Unit = {
    //apply方法可以被显示调用
          AAA0.apply()
    //更多地是通过对象名加圆括号来调用
          AAA0()
    //对象是一样的道理
          val a  = new AAA
          a.apply()
          a()
    //通过调用类AAA的伴随object AAA的apply方法来初始化一个AAA类的实例对象
    //apply方法通常就是通过这样一种模式来为一些类进行实例对象的创建
          val aaa = AAA()
          aaa.test
          val aaa1 = AAA()
          println(aaa.toString)
          println(aaa1.toString)
      }
    }

    模式匹配
    标准用法(match)
    使用守卫
    匹配类型

    object TestMatchCaseDemo {
      def main(args: Array[String]): Unit = {
        val a = 1
        a  match {
          case 1 => println("it is 1")
          case 2 => println("it is 2")
          case _ => println("other thing ")
        }
        a match{
          case x if x==1 => println("it is 1 again")
          case x if x==2 => println("it is 2 again")
          case _  => println("other thing again ")
        }
        def test(a:Int) =a match{
          case 1 => println("it is 1 in  function ")
          case 2 => println("it is 2 in function")
          case _ => println("other thing in function")
        }
        test(3)
        def t(obj:Any) = obj match{
          case x:String => {println("it is a String ");x}
          case x:Int => println("it is a Int")
          case _ => println("it is some other ")
        }
        t(Array("tom"))
        println(t("jack"))
        }
    }

    case class(多用在模式匹配中)
    构造器中的每一个类型默认都为val
    不用new就可以直接产生对象(为什么?apply方法)

    class TestCaseClass {
    }
    //case class 用关键字 case 来定义
    //主构造器中的参数不应加val或者var,也会被自动地编辑成成员变量
    //在case class中,主构造器中的参数默认是val ,且不建议用var
    case class User(name:String,psw:String){
    }
    object TestCaseClass {
      def main(args: Array[String]): Unit = {
        //获得一个case class 的实例对象,不用显示new,而是直接"类名(参数)"就可以(为什么?apply()方法)
           val u = User("tom","a good boy")
            u  match {
              //匹配类型的标准写法
              //case  i:User  => println("it is a User......")
              //匹配类型的另一种写法,可以根据传入构造函数的具体字段进行精确匹配
              case User("tom","a good boy") => println("it is a User of tom  and 123")
              case User("jack","a good boy") => println("it is a User of jack and 123")
              case  x:TestCaseClass => println("it is a TestCaseClass......")
              case _ => println("it is some other thing......")
            }
           //在scala中很多场景下可能会看到两个case class:Some(代表有值) 和 None(代表无值),它们都是option的子类
           val m = Map(1->2,3->4);
           var x :Int = 0
           m.get(x) match {
             case Some(_) => println("key exists......")
             case None =>println("key not exists.....")
             case _  => println("other......")
           }
      }
    }

    文件访问
    按行读取
    按字符读取
    从网络读取

    import scala.io.{Codec, Source}
    class TestFileRead {
    }
    object  TestFileRead{
      def main(args: Array[String]): Unit = {
        //读取本地文件
        val file = Source.fromFile("F:\上网账号.txt")(Codec("GBK"))
        //按字符访问
    //    for(c <- file){
    //        println(c)
    //    }
        //按行访问
    //    for( file <- file.getLines()){
    //      println(file)
    //    }
        //读取网页
        val   webHtml = Source.fromURL("http://www.www.163.com/","GBK");
        for (line <- webHtml.getLines()){
            println(line)
        }
      }
    }
  • 相关阅读:
    第一次结对作业
    第二次个人编程作业
    第一次个人编程作业
    第一次个人作业
    个人总结-人生如戏
    第二次结对编程
    第一次结对作业
    第二次个人编程作业:代码互改
    第一次个人编程作业
    软件工与UML程第一次作业
  • 原文地址:https://www.cnblogs.com/bigdata1024/p/8387415.html
Copyright © 2020-2023  润新知