您现在的位置是:首页 > 正文

Scala学习笔记(二)

2024-04-01 00:25:56阅读 1

一、函数

1. 定义函数

//  用def关键字定义一个函数  
//  格式  def 函数名(参数名 : 类型): 函数返回值的类型 = {}
def main(args: Array[String]): Unit = {
  // .... 函数体
}

2. 接收可变长参数

// 带 '*' 接收多个参数会组成一个数组
def inner(aStr: String*): Unit = {
  println(aStr)
}
inner("b", "c")

3. 匿名函数和函数的简化写法

def inner: Unit = {
  println("+++++")
}
inner // 如果函数没有参数可以直接写不需要加括号,定义的函数名也可以不用加括号

// 定义匿名函数
val stringToUnit= (aStr: String) => {
  println(aStr)
}
stringToUnit("aa")

// 将函数作为参数传入 参数类型的格式为  入参类型=>出参类型
def f(func: String => Unit): Unit ={
   func("pppp")
}
f((gender: String) => println(gender))
f(println(_)) // 如果参数只出现一次可以用下划线来代替  多个参数同样用下划线  但是必须都出现一次

//  简化匿名函数的写法
(gender: String) => println(gender)

4. 函数嵌套

def inner(): () => Unit ={
  println("inner")
  def innerSom(): Unit ={
    println("innerSon")
  }

  innerSom
}
inner()()    // 这里返回函数和py一样,返回一个函数加括号去执行

5. 传递代码块

// 这样n就代表是一个代码块传进来了
// => Int 代表传入的函数返回值是Int
def fact(n: => Int): Int ={
  println("n-->"+ n)
  println("n-->"+ n)
  15
}

def f1(): Int={
  println("我执行了")
  5
}

// 这里并不会直接执行f1函数,在fact函数里面调用了n几次,f1就执行几次
fact(f1())

6. 懒加载

// 惰性加载  当函数声明为lazy的时候  函数会延迟执行  直到首次执行才会执行 
def f1(): Unit={
  println("我执行了")
}

lazy val func = f1()   // 这里不会执行f1方法
println("222")
println(func)

二、面向对象

1. 包对象

package com

// 创建一个包对象  Scala就是包名  这里要和包名保持一致
package object scala {

  // 在这里可以定义当前包共享的对象、变量、资源
  val name:String = "atguigu"
}

2. 嵌套包

// 嵌套包
package aaa{
  package bbb{
    object TestMain{
      def main(args: Array[String]): Unit = {
        println(school)
      }
    }
  }

  // 必须在同一个包下 bbb才会生效
  package object bbb{
    val school: String = "aaa"
  }
}

3. 包的导入

1. 一般直接通过import 类路径即可导入
2. import java._  // _代表全部 和Java中的*意义相同
3. import java.util.{ArrayList => pig}  // 这样是给包取别名
4. import java.util.{ArrayList => _,_}  // 这样是不导入ArrayList, 导入剩下所有的

4. 访问权限

1. Scala没有public 一个Scala文件可以写多个公共类
2. protected是受保护的权限  只有同类、子类可以进行访问  同包无法访问


class Person {
  val name:String = "aaa"
  protected val age:Int = 15

  // 设置包访问权限  只有在entity包下才可以访问这个变量
  private[entity] var gender:String = "男"

}


class Son extends Person {
  override val name: String = "bbb"
}

5. 类和构造方法

1. Scala中的构造方法有两种  分为主构造器和辅助构造
2. 写在类上的是主构造  用this的是辅助构造器 辅助构造器可以有多个
class Girl(var age: String) {   // 如果这里的age是用var赋值的就可以进行修改 用val就不可以

  // 初始化参数 此时 age为null  size为0
  //  var age:String = _

  @BeanProperty     // 这样就创建一个getter和setter
  var size:Int = _

  def this(age: String, size:Int){
    this(age)  // 在辅助方法直接调用主构造器

    this.size = size
  }
}

6. 继承和多态

1. extends关键字代表继承  
2. Scala是单继承
3. 先调用父类构造器 然后调用子类构造器

class father(){
  var name:String = _
  var age:Int = _

  def sayOut(): Unit ={
    println("father: " + name + "age: " + age)
  }

  def this(name: String, age: Int){
    this()
    println("父类调用构造器")
    this.name = name
    this.age = age
  }

}

// 主构造器会从上到下执行一遍类
class Boy(name: String, age: Int) extends father {
  var sellerNo:Int = _

  def this(name: String, age: Int, sellerNo: Int){
    this(name, age)
    this.sellerNo = sellerNo
    println("子父类调用构造器")
  }
}

当父类的构造方法有参数的时候和私有的情况

1. 父类构造方法都有参数的情况  如果父类主构造器有参数那么子类也必须有参数
class father(name: String, age: Int){
  var name:String = _
  var age:Int = _
}

// 这里的name和age会传给父类
class Boy(name: String, age: Int) extends father(name, age) {
  var sellerNo:Int = _

  def this(name: String, age: Int, sellerNo: Int){
    this(name, age)
    this.sellerNo = sellerNo
    println("子父类调用构造器")
  }
}

2. 父类的构造方法是私有的情况  通过调用伴生对象的方式进行创建
class Student private(name: String, var age: Int) {
 .....
}

object Student{
  // 伴生对象可以访问私有方法
  val student = new Student("dfdf", 15)
}

7. 抽象类

1. 抽象类用 abstract  关键字
2. 子类需要全部实现抽象属性和方法
3. 子类只能重写val属性 不能重写var 因为var就可以直接重新赋值
4. override 关键字代表重写 可以重写方法和属性

abstract class Chouxiang {

  // 属性没有初始化那就是抽象属性
  val name:String

  // 只定义没有实现就是抽象方法
  def hello():Unit
}

class zilei extends Chouxiang{
  override val name: String = "jax"

  override def hello(): Unit = {
    println("开始抽象")
  }
}

8. 匿名内部类

object TestScala1{
  def main(args: Array[String]): Unit = {

    // 这样就创建了一个匿名子类
    val chouxiang = new Chouxiang {
      override val name: String = "ToM"

      override def hello(): Unit = {println("Jerry")}
    }
    chouxiang.hello()
  }
}

9. 伴生对象

1. 伴生对象的出现是为了解决在Scala中没有static关键字的问题
2. 伙伴对象之间可以互相访问
3. 伴生对象是单例的全局唯一,伴生对象的对象名必须和class保持一致
4. 伴生对象用object关键字进行声明  一般将静态方法和属性放到伴生对象中

class Student(name: String, var age: Int) {
  def printInfo(): Unit = {
    // 使用伴生对象的属性
    println(Student.school)
  }
}

object Student{
  val school: String = "xxxx"
  def main(args: Array[String]): Unit = {
      ...
  }
}

10. 特质

Scala的特质和Java中的接口(interface)的概念类似

1. trait 特质 用来代替接口的概念
2. trait中可以有抽象方法也可以有非抽象方法  一个类可以有多个特质
3. extends关键字引入一个特质  with关键字导入多个  extends...with...
4. 需要重写特质中的抽象方法和变量
5. 当特质和父类中的变量名相同时就会报错,混入特质需要重写

trait FirstStep{
  var age:Int
  val name: String= "pp"

  def cloneOne(): Unit
}

class RushA{
  val name: String= "aa"
}

class RushB extends RushA with FirstStep{
  override val name:String = "cc"
  override var age: Int = 18
  override def cloneOne(): Unit = {
    println(name)
  }
}

动态的混入特质,和引入匿名内部类相似

val b1 = new RushC with FirstStep{
     override var age: Int = 19

     override def cloneOne(): Unit = {
      println("动态混入")
     }
}

一个类混入国多个特质的执行顺序

1. 当混入多个特质和父类 会从右到左执行特质和父类

trait One{
  def who(): Unit ={
    println("I am One")
  }
}

trait Two{
  def who(): Unit ={
    println("I am Two")
  }
}

class Superposition extends One with Two {
  override def who(): Unit = super.who()
}

特质的菱形继承问题

// 最终的父类方法只会调用一次
trait Seller{
  def sell: Unit ={
    println("Seller开始售卖")
  }
}

trait Color extends Seller {
  override def sell: Unit = {
    println("我是红颜色")
    super.sell
  }
}

trait Price extends Seller {
  override def sell: Unit = {
    println("我是高价")
    super.sell
  }
}

class Diamond extends Color with Price {
  override def sell: Unit = {
    println("我是Diamond")
    super.sell
  }
}

>>> 我是Diamond
>>> 我是高价
>>> 我是红颜色
>>> Seller开始售卖

调用指定父类或者特质的方式

这样就是将顺序跳到Color这个特质,并不会调用已经跳过的特质

super[Color].sell

class A extends B with C
执行顺序就是[C,B]
super[B].sell 直接跳到B,跳过的C不会执行

特质的自身类型

class SelfType {
  var name: String ="pp"
}

trait Number{
  1. 这样就会定义一个自身类型  所有引入这个特制的都是SelfType类型 _是个通配符
  2. 这个相当在当前的特质中初始化了一个对象用this直接调用
  _: SelfType =>

  def callMe(): Unit ={
    println(this.name)
  }
}

11. 枚举类和应用类

应用类

1. 应用类 需要继承app这个类
object TestApp extends App{
  2. type重命名
  type MyString = String
  val gender: MyString = "asc"
}

枚举类

1. 枚举类 需要继承enumeration这个类这个类
object Week extends Enumeration{
  val Monday: Value = Value(1, "Monday")
  val Sunday: Value = Value(7, "Sunday")
}

Week.Monday

 

网站文章

  • 如何打包谷歌插件

    如何打包谷歌插件

    第一步 浏览器输入以下,按回车 chrome://version/ 找到 个人资料路径 复制 第二步 快捷键 win+e 把剪贴板中的粘贴到地址栏,按回车 找到这个文件夹 或者ctrl+f 输入Extensions按回车 第三步 浏览器进入chrome://extensions/ 选择要打包的插件 观察id 在第二步的文件夹中找到以上面id...

    2024-04-01 00:25:31
  • 如何创建一个Vue工程

    如何创建一个Vue工程

    (1)以管理员身份打开命令行界面,进入任意一个想要创建项目的文件夹,输入。如果出现版本号,说明我们成功安装了nodejs。出现以下版本号,说明我们的环境安装成功。(2)你的第一个vue项目页面就创建好...

    2024-04-01 00:25:24
  • WebApi测试工具 Postman

    WebApi测试工具:Postman转载于:https://www.cnblogs.com/lgq880821/p/11591964.html

    2024-04-01 00:25:16
  • eclipse和mysql登录注册_使用Eclipse+MyEclipse+MySql开发一个用户注册登录系统

    eclipse和mysql登录注册_使用Eclipse+MyEclipse+MySql开发一个用户注册登录系统

    1.开启Eclipse,单击Flie→New→Project..出现New Project对话框如下图。选择MyEclipse→J2EE Projects→Web Project单击Next如下图。在...

    2024-04-01 00:24:48
  • 洛谷 P1325 雷达安装 贪心

    洛谷 P1325 雷达安装 贪心

    **- 将问题转化为区间覆盖问题 此题求的是需要多少个头尾不相交的区间 贪心策略:按区间的左端点排序,若i的左端点与i-1的右端点不相交(在精度范围内)就增加一个区间** #include #include #include using namespace std; int n, r; typ...

    2024-04-01 00:24:41
  • 文本日期转真正日期(转)

    文本日期转真正日期(转)

    打开excel文件,在表格中输入一些文本日期,例如2/01/18,指的是2018年2月1日。 选中表格,点击数据-选择分列选项。 在文本分列向导1中选择分隔符号,下一步。 在文本分列向导2中选择默认,一般是tab键,下一步。 在文本分列向导3中选择日期mdy,完成。 最后看一下日期格式是否变成了真日期了。 ...

    2024-04-01 00:24:34
  • fopen打开文件名(文件路径含中文或韩语)方法测试

    fopen打开文件失败问题分析和处理

    2024-04-01 00:24:08
  • JavaSE学习:第九章、封装

    1、封装的概念: 将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来对隐藏的信息进行操作和访问。 2、好处: (1)只能通过规定的方法访问数据 (2)隐藏类的实例细节,方便修改和实现。 3、封装的实现步骤 1、将属性进行私有化private。 2、提供公共(public)的get、set方法,用来获取修改属性值 3、在set、get方法中,可以加入属性控制语句。 ...

    2024-04-01 00:24:01
  • 云服务器 ipv6,开通IPv6

    云服务器 ipv6,开通IPv6

    操作说明在支持IPv6的数据中心,创建云服务器可同步开通IPv6,已存在的云服务器也可进行IPv6开通(需要云服务器所在VPC及子网先开通IPv6网段)。云服务器开通IPv6后,IPv6地址直接配置在...

    2024-04-01 00:23:53
  • git 客户端使用

    1、TortoiseGit记住密码 在settings->git->Edit local .git/config,加上下面的内容,就能记住密码了。[credential] helper = store

    2024-04-01 00:23:45