scala面向对象综述

一、Scala面向对象编程综述

1.1 Scala是纯粹的面向对象的语言

以Java为例, Java并不是一门纯面向对象的语言,其允许非对象值的存在,也允许不属于任何对象的静态字段和方法存在。
Scala是纯粹的面向对象的语言,每个值都是对象,每个操作都是方法调用。

1.2 Scala大量重用了 Java中的类型

Scala与 Java完全兼容, Scala程序会被编译成 Java字节码,访问 Java字段,继承 Java类,实现 Java接口都不需要特别的语法,实际上 Scala也使用了大量的Java库代码。比如 Scala String类与 java.lang.String一样。

1.3 Scala OOP比较 Java OOP的主要差异

  • Scala取消了接口( Interface),新增了类似的 特质 概念( Trait)
  • Scala取消静态字段和方法,新增 单例对象 的概念( Singleton Object)
  • Scala新增了 样例类 case class)

二、类和对象

  • 类是对对象的抽象模板,描述了该类对象可以拥有的属性和方法
  • 对象是类 的具体实例
  • 类和对象最明显的 区别:类不占用内存,对象占用内存

2.1类的定义

Scala与 Java创建普通类的方式基本一样:

class 类名 (参数列表 ){
辅助构造器
成员变量
成员方法
}
  • Scala提出主构造器与辅助构造器的概念,类似 Java构造方法。主构造器是 “类名 (构造参数列表 )” ,辅助构造器 this(构造参数列表 )” ,辅助构造器类似于 Java中的构造方法重载,所有构造器都没有返回值。注意辅助构造器必须间 接或直接调用主构造器。
  • Scala中,“ this” 是关键字,用于引用当前对象。可以使用 this调用实例变量、方法、构造器。
  • Scala类成员默认为 public ,也可修改为 privateprotected
  • Scala类中无法定义静态成员和方法,因为没有 static关键字。
  • 类中可以有字段和方法,统称为成员变量。字段可以用var或 val定义,都是指向对象的变量。

示例: 创建一个 Studnet 类

class Student() {    //默认无参。括号可以不加    默认有一个无参构造器
  //定义成员变量      //使用var修饰自带了get、set方法, val只有get方法
  var name:String="张三"      //设置name默认值为 张三
  var age:Int= _    //默认为0
  var gender:String = _  //默认null
  var banji:Int = 1   //设置班级默认为1

  //定义一个辅助构造器1,设置 name,age属性
  def this(name:String,age:Int)={      
    //辅助构造器必须从调用其他构造器开始
    this()
    this.name=name
    this.age=age
  }
  //定义一个辅助构造器2,设置gender属性
  def this(gender:String){          
    this("李四",18)      //可以在this中设置name,age的默认值
    this.gender =gender
  }

  //定义一个成员方法
  def study()={
    println(name+"喜欢学习scala")
  }
}

object Test01{    //main方法只能写在object中
   def main(args: Array[String]): Unit = {
     //使用默认无参的构造方法
     val stu1: Student = new Student()
     println(stu1.name)
     println(stu1.age)
     println(stu1.gender)
     stu1.study()
     //控制台输出:
     /*张三
     0
     null
     张三喜欢学习scala
     */

     //调用辅助构造器1
     val stu2: Student = new Student("小明", 22)
     println(stu2.name)
     println(stu2.age)
     println(stu2.gender)
     stu2.study()
      //控制台输出:
     /*小明
     22
     null
     小明喜欢学习scala
     */
     
     //调用辅助构造器2
     val stu3=new Student("男")
     println(stu3.name)
     println(stu3.age)
     println(stu3.gender)
     stu3.age=18
     stu3.study()
       //控制台输出:
     /*李四
     18
     男
     李四喜欢学习scala
     */
   }
 }

除了上面介绍的类定义方法,还有一种更简便的创建类的方式:

class Dog(var name: String,var age:Int){ //自动生成类的属性
  def cry()=println("wow ...")
}

object Dog {
  val dog = new Dog("Harry",2)
  dog.name="Wang" //编译错误,需要将val类型改成var
  dog.age=3 //编译通过
}

注: 主构造器中,使用val的定义的变量自动生成 getter var定义的变量自动生成 getter&setter。在 Scala中,严格来说是没有 getter和 setter这个说法,使用了“ value”和 value_=”两个方法来分别代替了 getter和 setter。如下所示:

class Counter(var value:Int)
class Counter{
	private var privateValue = 0  //私有变量,外界无法直接访问
	def value = privateValue  //定义一个方法,代替 getter
	def value_= ( newValue : Int ){   // value_= 是方法名字 ,代替 setter
	value = newValue     //将 newValue 赋值给 value,类似于set方法
	} //注意, scala中默认方法是 public的
}

2.2 样例类

样例类(case class) 在匹配模式中经常使用到,当一个类被定义成为case类后,Scala会自动创建一个伴生对象,实现了 apply 与 unapply 等其他方法,方便很多。而 普通类 只有在伴生对象中定义apply和unapply方法才能够利用伴生对象的方式创建对象和模式匹配

①:默认实现 apply 方法(apply方法通常称为注入方法,在伴生对象中做一些初始化操作,不需要new关键字就能创建该类对象,创建对象的参数列表不需要和构造器的参数列表统一)
②:默认实现 unapply 方法(unapply通常称为提取方法,使用unapply方法提取固定数量的参数来进行模式匹配,unapply方法会返回一个序列(Option),内部产生一个Some对象,Some对象存放一些值)
③:默认实现类构造参数的 getter 方法(构造参数默认被声明为 val ),但是当构造参数声明是 var 类型的,默认会实现 settergetter 方法(不建议将构造参数类型声明为 var )
④:默认实现 toStringequalscopyhashCode 等方法

示例:

定义一个普通类 People

class People(val name:String,var age:Int,var sex:String){

}

object PeopleDemo{
  //注入方法apply
  def apply(name:String,age:Int,sex:String): People= new People(name,age,sex)
  //提取方法unapply
  def unapply(people: People): Option[(String,Int,String)] = {
    if (people == null){
      None
    }else{
      Some(people.name,people.age,people.sex)
    }
  }

  def main(args: Array[String]): Unit = {
    //创建对象
    val p = People("milk",18,"male") //省略的new关键字

    //unapply方法结合匹配模式使用
    p match {
      case People("milk",_,_) =>println("Hello,milk")
      case _ => println("not such People")
    }  //控制台打印: Hello,milk

    println(p.name)  //打印:milk      默认实现了getter方法

//    p.name = "Jack"   报错,因为构造参数声明为val类型,所以没有实现setter方法

  }
}

People 定义为 样式类 我们可以这样写:

case class People(val name:String,val age:Int,val sex:String){

}

object PeopleDemo {  //此处为非伴生对象
  def main(args: Array[String]): Unit = {
    //创建对象
    val p = People("milk",18,"male") //省略的new关键字
    val p1 = People("Tom",20,"female")

    //unapply方法结合匹配模式使用
    p match {
      case People("milk",_,_) =>println("Hello,milk")
      case _ => println("not such People")
    }  //控制台打印: Hello,milk

    println(p.name)  //打印:milk      默认实现了getter方法
    println(p1.name)  //Tom

//    p.name = "Jack"   //报错,因为构造参数声明为val类型,所以没有实现setter方法

  }
}

2.3 单例对象Object

  • Scala中没有java里面的静态类、静态成员、静态方法,但是scala提供了Object对象,类似于java静态类,,它的成员、它的方法都默认是静态的。
  • 本质上, 单例对象是一种特殊的类,有且只有一个实例 。单例对象在第一次使用时被创建,所有成员都可以直接访问。
  • **main()**方法必须定义在单例对象中, Object 对象继承 App(内置特质)会默认提供main()方法,不需要在写main()方法
  • 小结:在
    Scala中,类和单例对象的差别在于,单例对象不能带参数,而类可以。因为单例对象无法使用 new关键字实例化,也就没有办法为它传递实例

2.4 伴生

①:伴生关系
限制条件:object(单例对象)与 class(普通类)同名且在一个文件中
示例:

//伴生类
class Student(n: String, a: Int) {
private var name = n //私有变量,伴生对象可以访问
private var age = a
}

//伴生对象
object Student {
def apply(n: String, a: Int): Student = new Student(n, a)
def main(args: Array[String]): Unit = {
val stu=Student("Jason",9) //通过伴生对象的 apply()方法创建实例
println(stu.name) //Jason
	}
}

一旦建立伴生关系,伴生对象与伴生类可相互访问私有成员。伴生对象主要为伴生类提供一种静态成员访问的途径。

②:伴生类
指在伴生关系中的伴生类,在class(伴生类)中访问 object(伴生对象)的
私有属性,使用“ object名 .成员”

③:伴生对象
指在伴生关系中的单例对象,在object(伴生对象)中访问 class(伴生类的私有属性,必须通过 class实例对象访问,如上面的“ stu.name”

2.5 特质

  • 特质封装了字段和方法的定义,并可以混入到类中重用。每个类只能继承一个超类,但可以混入多个特质 。定义特质使用 trait 关键字,其它与类定义相似,使用extendswith关键字可将特质混入类中。
  • 对象也可以使用 with混入特质,称为动态混入
  • 特质类似于带有具体方法的Java接口,在特质中实现一次方法,而不再需要在每个混入特质的类中重新实现。
  • 特质也像抽像类,但抽象类只能继承一次,而特质可以混入多次
  • 特质中未被实现的方法默认就是抽象方法
  • 重写特质的抽象方法时, 不需要 override 关键字
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值