scala学习笔记8:面向对象(基础)

32 阅读6分钟

scala学习笔记


一、类与对象

  1. Java是面向对象的编程语言,由于历史原因,Java中还存在着非面向对象的 内容:基本类型 ,null,静态方法等。
  2. Scala语言来自于Java,所以天生就是面向对象的语言,而且Scala是纯粹的 面向对象的语言,即在Scala中,一切皆为对象
  3. Scala中类与对象的关系,和Java语言中的类与对象的关系一样。

1.类是什么?

  1. 类是抽象的,概念的,代表 一类事物,比如人类,猫类..
  2. 对象是具体的,实际的,代表 一个具体事物,如张三
  3. 类是对象的抽象模板,对象是类的一个个体,对应一个实例

2.如何定义?

[ 修饰符] class  类名 {
类体
}
//scala语法中,类并不声明为public,
//所有这些类 都具有公有可见性( 即默认就是public),
//[修饰符在后面再详解].
//一个Scala源文件可以包含多个类.
class Dog {
  XXXX
}

3.对象

//基本语法
// val | var  对象名 [ :类型] = new dog 
//创建一个具体狗,实例化,这里使用类型推断,类型可以省略
//完整写法: val german1:Dog = new Dog()
val german1 = new Dog()
  • 如果我们不希望改变对象的引用(即:内存地址), 应该声明为val 性质的,否则声明为var, scala设计者推荐使用val,因为一般来说,在程序中,我们只是改变对象属性的值,而不是改变对象的引用。
  • scala在声明对象变量时,可以根据创建对象的类型自动推断,所以类型声明可以省略,但当类型和后面new对象类型有继承关系即多态时,就必须写了

二、属性

1.属性定义

定义类之后,还要有类的属性,属性是类的一个组成部分,一般是 值数据类型,也可是引用类型。比如人的年龄,性别,动物的颜色,种类等等。 定义方式

[ 访问修饰符] var  属性名称 [ :类型] =  属性值

举例

class Dog {
  var name:String='二狗'
  var age:Int =3
  //初始化数据的类型自动推断,属性类型可以省略
  var high=50  
  //如果赋值为null,则一定要加类型,
  //因为不加类型, 那么该属性的类型就是Null类型
  var color:String=null 
 // 使用符号_( 下划线),让系统分配默认值.
   var sex:String=_
  
}
  • 属性的定义类型可以为任意类型,包含值类型或引用类型
  • Scala中声明一个属性**,必须 显示的初始化**,
  • 如果根据初始化数据的类型自动推断,属性类型可以省略(这点和Java不同)
  • 如果赋值为null,则一定要加类型,因为不加类型, 那么该属性的类型就是Null类型
  • '_'下划线代表的基础数据类型和默认值对应关系 在这里插入图片描述

1.属性访问

对象名.属性名

 val erha = new Dog()
 println(erha.name)

三、方法

Scala中的方法其实就是函数,本质是一样的,都是一组逻辑的封装实现某个功能,在对象里,经常使用方法这个名称,在对象外,经常用函数

def  方法名( 参数列表) [ :返回值类型] = {
方法体
}
举例:
  def eat(food:String)={
      println(name+"like eat "+food)
    }

四、构造器

构造器(constructor) 又叫构造方法,是类的一种特殊的方法,它的主要作用是完成对新对象的初始化。 JAVA 构造器特点:

  • 在Java中一个类可以定义多个不同的构造方法,构造方法重载
  • 如果 没有定义构造方法,系统会自动给类生成一个 默认无参构造方法 (也叫默认构造器),比如 Dog (){}. 一旦定义了自己的构造方法(构造器),默认的构造方法就覆盖了,就不能再使用默认的无参构造方法,除非 显示的定义一下,即: Dog(){};

1. scala主构造器 和 辅助构造器

class 类名( 形参列表) { // 主构造器
// 类体
def this(形参列表) { // 辅助构造器
}
def this(形参列表) { //辅助构造器可以有多个...
}
}
  1. 辅助构造器 函数的名称this(这个和Java 是不一样的), 可以有多个,编译器通过不同参数来区分.在底层就是f 构造器重载
  2. Scala构造器作用是完成对 新对象的初始化,构造器没有返回值
  3. 主构造器的声明直接放置于类名之后 [ 反编译 ]
  4. 主构造器会执行类定义中的所有语句,这里可以体会到Scala的函数式编程 和面向对象编程融合在一起,即:构造器也是方法(函数),传递参数和 使用方法和前面的函数部分内容没有区别
  5. 如果主构造器无参数,小括号可省略,构建对象时调用的构造方法的小括 号也可以省略
  6. 辅助构造器无论是直接或间接,最终都一定要调用主构造器,执行主构造器的逻辑而且需要放在辅助构造器的第一行(这点和java一样)
  7. 辅助构造器的声明不能和主构造器的声明一致,会发生错误(即构造器名重复)

举例

 class Dog {
  //如果var换成val,改属性会变成私有属性,对象无法直接调用
    var name:String="二狗"
    var age:Int =3
    var high=50
    var color:String=null
    var sex:String=_

    def eat(food:String)={
      println(name+"like eat "+food)
    }

    def this(name:String){
      this()
      this.name=name
    }
    def this(name:String,age:Int){
      this()
      this.name=name
      this.age=age
    }

//main
  def main(args: Array[String]): Unit = {
    val erha = new Dog()
    println(erha.name)
    erha.name="中华田园犬"
    println(erha.name)
    erha.eat("狗粮")
    //调用辅助构造器一
    val bullgod = new Dog("bullgod")
   //调用辅助构造器二
    val corgi = new Dog("corgi", 2)

  }

2.构造器参数

  1. Scala类的主构造器的形参未用任何修饰符修饰,那么这个参数是局部变量。
  2. 如果参数使用val关键字声明,那么Scala会将参数作为类的私有的只读属性
  3. 如果参数使用var关键字声明,那么那么Scala会将参数作为类的 成员属性使用,并会提供属性对应的xxx()[类似getter]/xxx_$eq()[类似setter]方法,即这时的 成员属性是私有的,但是可读写。

3.Bean 属性

JavaBeans规范定义了Java的属性是像getXxx()和setXxx()的方法。许多Java工具(框架)都依赖这个命名习惯。为了Java的互操作性。将Scala字段加@BeanProperty时,这样会自动生成 规范的 setXxx/getXxx 方法 方法。这时可以使用 对象.setXxx() 和 对象.getXxx() 来调用属性

import scala.beans.BeanProperty

object Dog {

  def main(args: Array[String]): Unit = {
  
    val corgi = new Dog("corgi", 2)
   //直接调用get/set方法
    corgi.setAge(10)
    
  }

  class Dog {
    var name: String = "二狗"
    // @BeanProperty 注解,会自动生成get/set方法
    @BeanProperty var age:Int =3
    var high=50
    var color:String=null
    var sex:String=_

    def eat(food:String)={
      println(name+"like eat "+food)
    }

    def this(name:String){
      this()
      this.name=name
    }
    def this(name:String,age:Int){
      this()
      this.name=name
      this.age=age
    }

  }

}


总结

scala的面向对象比java更彻底,有较多相同的地方,也有很多细节差异的地方,多多对比,联想记忆