Scala学习笔记---Day04

**### 方法
基本说明:
Scala中的方法其实就是函数,声明规则请参考函数式编程中的函数声明.
基本语法:
def 方法名(参数列表)[:返回值类型]={
方法体
}

方法的调用机制原理
1. 当我们Scala开始执行时,先在栈区开辟一个main栈,main栈是最后被销毁的
2. 当scala程序在执行到一个方法时,总会开一个新的栈
3. 每个栈是独立的空间,变量(基本数据类型)是独立的,相互不影响(引用类型除外)
4. 当方法执行完毕后,该方法开辟的栈就会被JVM回收( )

构造器

基本介绍:
构造器(constructor) 又叫构造方法,是类的一种特殊的方法,它的主要作用是完成对新对象的初始化
1. java构造器基本语法
[修饰符] 方法名 (参数列表){
    构造方法体
}
1.1 回顾-Java构造器的特点
    1.在Java中一个类可以定义多个不同的构造方法,构造方法重载
    2.如果程序员没有定义构造方法,系统会自动给类生成一个默认无参构造方法(也叫默认构造器),比如Person(){}
    3.一旦定义了自己的构造方法(构造器),默认的构造方法就覆盖了,就不能再使用默认的无参构造方法,除非显示的定义一下即:Person(){};
Scala构造器的介绍
和java一样,Scala构造对象也需要调用构造方法,并且可以有任意多个构造方法.(Scala中构造器也支持重载 )
Scala类的构造器包括:主构造器和辅助构造器
Scala构造器的基本语法
class 类名(形参列表){//主构造器
//类体
def this(形参列表){//辅助构造器
}
def this(形参列表){//辅助构造器可以有多个...}
}
1. 辅助构造器 函数的名称this,可以有多个 ,编译器通过不同参数来区分
Scala构造器注意事项和细节
1. Scala构造器作用是完成对新对象的初始化,构造器没有返回值
2. 主构造器的声明直接放置于类名之后
3. 主构造器会执行类定义中的所有语句,这里可以体会到Scala的函数式编程和面向对象编程融合在一起,即:构造器也是方法(函数),传递参数和使用方法和前面的函数部分内容没有区别
4. 如果主构造器无参数,小括号可省略,构建对象时调用的构造方法的小扩号可以省略
5. 辅助构造器名称为this(这个和Java不一样的),多个辅助构造器通过不同参数列表进行区分,在底层就是Javaf的构造器重载
6. 辅助构造器,必须在第一行显示地调用主构造器(直接或间接)
6.1 scala朱支持辅助构造器,直接调用父类构造器
```
def this(name:String){
this("jack",10)
this.name=name
}
```
案例:
package Day04

object Rect {
  def main(args: Array[String]): Unit = {
  val rect = new Rect
    rect.printRect(5,3)
  }
}
class Person1(){
  var name:String= _
  var age :Int = _
  def this(name:String)={
    //辅助构造器无论是直接或间接,最终都一定要调用主构造器,执行主构造器的逻辑
    //而且需要放在辅助构造器的第一行[这点和Java一样,Java中一个构造器要调用同类的其他构造器,也需要放在第一行
    this()
    this.name=name
  }
  def  this(name:String,age:Int){
    this()//直接调用主构造器
    this.name=name
    this.age=age
  }
  def this(age:Int){
    //简介调用主构造器,因为def this(name:String)中调用了主构造器
    this("匿名")
    this.age=age
  }

}
class Rect{
  def printRect(m:Int,n:Int)={
    for(i<-0 until m){
      println("*"*n)
    }
  }
}
6. 如果想让主构造器编程私有的,可以在()之前加上private,这样用户只能通过辅助构造器来构建对象了
 class Person private(){
     ...
 }
7. 辅助构造器的声明不能和主构造器的声明一致,会发生错误

属性高级

构造器参数:
1. Scala类的主构造器的形参未用任何修饰符修饰,那么这个参数是局部变量.
class Preson(name:String){
}
2. 如果参数使用val关键字声明,那么Scala会将参数作为类的私有的只读属性使用.
3. 如果参数使用var关键字声明,那么Scala会将参数作为类的成员属性使用,并会提供属性对应的xxx()[类似getter/xxx_$eq()[类似setter]方法,即这时的成员属性是私有的,但是可以读写
案例:
def main(args: Array[String]): Unit = {
  //val rect = new Rect
  //  rect.printRect(5,3)
    val worker = new Worker("wmith")
    worker.name//不能访问inName
    val worker2 = new Worker2("wmith")
    worker2.name
    worker2.inName//可以访问inName
    new Worker3("jack")

  }
}
//1. 如果主构造是Worker(inName:String),那么inName就是一个局部变量
class Worker (inName:String){
  var name=inName
}
//2. 如果主构造器是Worker2(val inName:String),那么inName就是Worker的一个private
//的只读属性
//反编译:
/**
  * private final String inName;
  * public String inName(){
  * return this.inName;}
  */
class Worker2 (val inName:String){
  var name=inName
}
//3. 如果主构造器是Worker2(val inName:String),
// 那么inName就是Worker的一个private的可读写属性
class Worker3 (var inName:String){
  var name=inName
}

Bean属性

JavaBeans规范定义了Java的属性是想getXxx()和SetXxx()的方法,许多Java工具(框架)都依赖这个命名习惯,为了Java的互操作性,将Scala字段加@BeanProperty,这样会自动生成规范的setXxx/getXxx方法,这时可以使用对象.setXxx()和对象.getXxx()来调用属性.
注意:
    给某个属性加入@BeanProperty注解后,会生成getXxx和setXxx的方法并且对原来底层自动生成类似xxx(),xxx_$eq()方法,没有冲突,二者可以共存
import scala.beans.BeanProperty
class Car{
    @BeanProperty var name:String=null
}
object BeanPropertyDemo {
  def main(args: Array[String]): Unit = {
    val car = new Car
    //使用@BeanProperty 自动生成 getXxx 和SetXxx
    car.setName("奔驰")
  }
}
class Car{
  @BeanProperty var name:String= _
}

对象创建流程

class Person {
  var age: Int = _
  var name: String = _
  def this(name: String, age: Int) {
    this()
    this.name = name
    this.age = age
  }
}
val p: Person = new Person("hel", 12)
Scala对象创建 流程分析
1. 加载类的信息,(属性信息,方法信息(存入栈中)
2. 在内存中(堆)开辟空间
3. 先使用父类主构造,副构造(进行初始化)
4. 使用主构造器对属性进行初始化[age=0,name=null]
5. 使用辅助构造器对属性进行初始化[age=10,name="hello"]
6. 将开辟的对象的地址赋给p这个引用

Java包的三大作用

1. 区分相同名字的类
2. 当类很多时,可以很好的管理类
3. 控制访问范围

Java对包的要求

1. 类的源文件,需要和包对应的文件路径匹配
2. 当我们编译Dog类,后生成对应的.class文件,编译器会将.class文件也放在和包对应的文件路径下

Scala包的基本介绍

和Java一样,Scala中管理可以使用包,但Scala中的包的功能更加强大,使用也相对复杂些,
Scala包快速入门
1. 使用打包技术解决上面的问题,
//使用xh的tiger
    val t1 = new Day04.xh.Tiger
    //使用xm的tiger
    val t2 = new Day04.xm.Tiger
  }
Scala包的特点概述
基本语法:
    package 命名
Scala包的三大作用:
    1. 区分相同名字的类
    2. 当类很多时,可以很好的管理类
    3. 控制访问范围
    4. 可以对类的功能进行扩展
注意:
    Scala中包名和源码所在的系统文件目录结构要可以不一致,但是编译后的字节码文件路径和包名会保持一致(这个工作由编译器完成)
Scala包的命名
命名规则:
    只能包含数字,字母,下划线,小圆点,但不能用数字开头,也不要使用关键字.
    demo.class.exec1//错误,因为class是关键字
    demo.12a//错误,因为内不能使用数字作为关键字
命名规范:
    com.公司名,项目名,业务模块名
Scala会自动引入的常用包
java.lang.*
scala包不代表子包
Predef包
Ctrl+B==>查看包的内容
Scala 包注意事项和使用细节
1. Scala进行package打包时,可以有如下形式  // 传统方式
    1.1 package com.iflytek.scala           // 和第一种完全等价
    1.2 package com.iflytek 
    1.2 package scala
    1.3 package com.iflytek{    
    1.3 package scala{}}
2. 包也可以像嵌套类那样使用(包中有包),这个在前面的第三种打包方式已经讲过,在使用第三种方式时的好处是:程序员可以在同一个文件中,将类(class/object),trait创建在不用的包中,这样就非常灵活了
3. 作用域原则:
    可以直接向上访问.即:Scala中子包直接访问父包中的内容,大括号体现作用域.
    提示(Java中子包使用父包类重名时,默认采用就近原则,如果希望指定使用某个类,则带上包名即可)
4. 父包要访问子包的内容时,需要import对应的类等.import在scala中任何位置不受限制.
5. 可以在容一个.scala文件中,声明多个并列的package(建立嵌套的package不要超过3层)
6.1 使用相对路径,使用绝对路径_root_.scala(sless)当包名冲突时使用
包对象
基本介绍:
    包可以包含类,对象和特质(trait),但不能包含函数/方法或变量的定义,为了弥补这一点不足,scala提供了包对象的概念来解决这个问题
1. 在包中直接写方法,或者定义变量,就错误==>,使用包对象的技术来解决
2. package object scala 表示创建一个包对象 scala,它是com.filytek.sclaa这个包对应的包对象
3. 每一个包都可以有一个包对象
4. 包对象的名字需要和子包一样
5. 在包对象中可以定义变量,方法
6. 在包对象中定义的变量和方法,就可以在对应的包中使用
package scala {
  //表示在 com.iflytek.scala包下创建类p1
    class p1 {
      var name: String = _
      var age: Int = _
    }
    /
    var name="hell"// 不支持
}
案例:

import Day04.xh9la.scala.p1
// com.iflytek.scala ,还可以写特质trait,类,还可以写object
//2. 即scala支持,在一个文件中,可以同时创建多个包,以及给各个包创建类,trait和object
package object scala {
  var name = "hell"

}
package scala {

  //表示在 com.iflytek.scala包下创建类p1
  class p1 {
    var name1: String = _
    var age: Int = _

    def sayHello(): Unit = {
      println(name)
    }
  }

}

object PackageDemo {
  def main(args: Array[String]): Unit = {
    val p = new p1
     p.sayHello()
  }
}

包对象的底层实现机制分析
7. 在底层这两个包对象会生成两个类,package.class 和package$.class
1. 当创建对象后,在该包下生成public final class package 和public final class package$
2. 通过package$的一个静态实例完成对包对象中的属性和方法的调用.
package object scala{
    val name= "King"
    def sayHi(){
        println("hi")
    }
}
1. 生成package.class
    publi final class scala{
        public static void sayHiv(){
            package..MODULE.sayHi();
        }
    }
    public class temp{
        public static void main(String args[]){
            sysout()...
            package$$.MODOULES$.sayOk();//调用package$里面的一个实例
        }}
    final class package${
        public static final package$$ MODULES$;
        private final String name = "ok";
        static{
            MODULE$ = new package$$();
            public void sayOk(){
                sysout()...
                public String name(){return this.name}
            }
        }
    }

回顾java访问修饰符基本介绍

前言:java提供四种访问控制修饰符号,控制方法和变量的访问权限(范围);
1. 公开级别:用public修饰,对外公开
2. 受保护级别:用protected修饰,对子类和同一个包中的类公开
3. 默认级别:没有修饰符号,向同一个包的类公开
4. 私有级别:用private修饰,只有类本身可以访问,不对外公开

当一个文件中同时出现class clerk 和object clerk

1. class clerk 称为伴生类
2. object clerk 称为伴生对象
3. 因为scala抛弃了static,它就是设计了伴生类和伴生对象的概念中
4. 伴生类 写非静态的内容 伴生对象 就是静态内容

scala中包的可见性和访问修饰符的使用

1. 当属性访问权限为默认时,从底层看属性是private,但是因为提供了xxx——$eq()[类似setter()]/XXX()[类似getter()]方法,因此从使用效果看是任何地方都可以访问。
2. 当方法权限为默认时,默认为public访问权限。
3. private 为私有权限,只在类的内部和伴生对象中可以用
4. protected 受保护权限,比Java更严格,只能子类访问同包无法访问。
5. scala中没有public,即不能使用public显示的修饰属性和方法
6. 包访问权限(表示属性有了限制,同时包也有了限制),这点和java不一样
当private 修饰的属性不能用时,可以使用包访问扩大权限,相当于扩大访问范围
private[visit] val name = ""

scala引入包基本介绍

1. scala引入包也是使用import,基本的原理和机制和java一样,但是Scala中的import功能更加强大,也更灵活
2. 因为Scala语言源自于Java,所以java.lang包中的类会自动引入到当前环境中,而Scala中的scala包和Predef包的类也会自动引入当前环境中,即其下面的类可以直接使用,
3. 如果想要

Scala引入包的细节和注意事项

1. 在Scala中,import语句可以出现在任何地方,并不仅限于文件顶部,import语句的作用一直延伸到包含该语句的块末尾,这种语法的好处是:在需要时再引入包,缩小import包的作用范围,提高效率
2. java中如过想要引入包中所有的类,可以通过通配符*,Scala中采用_(_表示将该包的所有内容引入)
3. 如果不想要某个包中全部的类,而是其中的几个类,可以使用选取器(大括号)
import scala.collection.mutable.[HashMap,HashSet]
4. 如果引入的多个包中含有相同的类,那么可以将不需要的类进行重命名进行区分,这个就是重命名.
import java.util.{HashMap>java.HashMap,List}
5. 如果某个冲突的类根本不会用到,那么这个类可以直接隐藏掉,

面向对象编程--抽象

1. 我们在前面定义一个类的时候,实际上就是把一类事物的共有属性和行为提取出来,形成一个物理模型(模板),这种研究问题的方法称为抽象

面向对象编程--封装

1. 封装就是把抽象出的数据和对数据的操作封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作(成员方法),才能对数据进行操作
2. 好处:
    1. 隐藏实现细节
    2. 可以对数据进行验证,保证安全合理
    3. 同时可以加入业务逻辑
3. 如何体现封装
    1. 对类中的属性进行封装
    2. 通过成员方法,包实现封装
4. 实现步骤
    1. 属性私有化
    2. 提供一个公共的set方法,用于对属性进行获取,设置
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356

推荐阅读更多精彩内容