码迷,mamicode.com
首页 > 其他好文 > 详细

Scala基础:面向对象——类

时间:2015-06-29 23:58:22      阅读:125      评论:0      收藏:0      [点我收藏+]

标签:

类 (class)

类是对象的模板,通过构造类,能够使用new关键字声明一系列同结构的对象。

Scala的一个源文件可以包含多个public类。

声明Person类:

class Person{

  var name : String = _

  val age = 10

  private[this] val gender = “male”

}

说明:

name字段被赋值为“_”“_”即占位符。表示name被声明为String。但赋值为“_”,即暂不赋实际的值。

若使用占位符,Scala无法判断name的类型,所以必须声明该字段的类型。

gender 在Person中“private[this]” 限定住了,在类的外部无法被调用。

Scala构造器

Scala构造器与Java构造器有很大的不同。Scala中的构造器分为主构造器与副构造器。

主构造器

Scala中每个类都有主构造器,且与类定义交织在一起。

Scala主构造器的参数直接放置在类名之后。

一个类若没有显式定义主构造器,则自动拥有一个无参主构造器。

例:主构造器的声明。

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

  // ...

}

Scala类中没有放在方法体的语句都会被执行。

例:主构造器的方法体。

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

  println("This is primary constrator!")

}

主构造器的参数被编译成字段,并在构造对象时初始化传入。

例:

object PersonMain{

def main(args: Array[String]) {

val p = new Person("Tom",18);

    println("p is "+ p.name + "," + p.age )

  }

}

技术分享

输出:

技术分享

例:

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

  println(“Person is created”)

  val id = name + ":" + age

}

val p = new Person(“Tom” , 18)

说明:

Person类拥有三个字段name,age,id 。

主构造器的参数一般有四种:

value: String

对象的不可变私有字段,对象中没有方法使用value,则没有该字段。即相当于private[this] val 。

private val value: String 或 private var value: String

对象的私有字段,私有的getter/setter方法。

val/var value:String

对象的私有字段,公有的getter/setter方法。

@BeanProperty val/var value:String

私有字段,共有的Scala和JavaBean的getter/setter方法

私有主构造器

class HelloWorld private(主构造器){ 类成员 }

主构造器私有,只能通过辅助构造器构造对象。

副构造器(辅助构造器)

Scala类能有任意多的副构造器。

Scala的副构造器都以“this”为名称,在类中定义。

例:

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

  println("this is primary constrator!")

var gender: String = _

def this(name: String, age: Int, gender: String) {

this(name, age)

this.gender = gender

  }

}

技术分享

输出:

技术分享

副构造器中必须调用主构造器或调用其他副构造器,而其他副构造器中必须调用主构造器。也即所有副构造器中必须有一个调用主构造器。

录:

class HelloWorld{

  private var value1 = ””

  private var value2 = ””

  def this(m:String) {

    this()     //调用主构造器

    this.value1=m

  }

  def this(m:String,n:String) {

    this(m)    //调用已定义的辅助构造器

    this.value2=n

  }

}

辨析:构造器与函数

主构造器的参数允许带有val/var关键字,函数的参数不能带有这些关键字。

主构造器的参数允许带有val/var关键字,副构造器的参数不能带有这些关键字。

Scala Object

Scala中没有static的概念。但Scala中使用object提供类似的功能。

单例对象

object语法定义了的类的单实例。

object Accounts{

  private var lastNum = 0

  def newUniqueNum = {

    lastNum += 1

    lastNum

  }

}

object中的方法,即可以被当作为静态方法。

调用object中的方法,直接调用,不用new。

Accounts.newUniqueNum ()

对象的构造器在该对象第一次被使用时调用。

object语法结构与class大致相同,除了object不能提供构造器参数。

通常使用单例对象的环境:

    作为存放工具函数或常量的地方。

    共享单个不可变实例。

    利用单个实例协调某个服务。

伴生对象

Java中存在既有实例方法又有静态方法的类。在Scala中可以通过类与类的伴生对象来达到同样的目的。

当一个单例对象存在同名类的时候,称为伴生对象。

class Account{...}  //伴生类

object Account{...}  //伴生对象

类和其伴生对象可以互相访问私有属性,但必须存在同一个源文件中。

类的伴生对象可以被访问,但并不在作用域中。

例:

class Account{...}

object Account{ def newUniqueNum = {...} }

HelloWorld类必须通过Account.newUniqueNum()调用伴生对象中的newUniqueNum()方法,而不能直接用newUniqueNum()来调用。

伴生对象也是扩展类功能的一种途径。因为伴生类可以直接使用伴生对象的方法。

apply方法

apply方法专用于简化创建类实例的方法。apply方法类似于工厂方法。当需要构造有参数需求的伴生对象时,通常会定义和使用对象的apply方法。apply方法返回伴生类的对象。

当遇到如下形式的表达式时,apply方法就会被调用:Object(参数1, ... ,参数N)

例:Spark源码中Graph对象。

技术分享

GraphImpl方法也是一个Object对象。

例:Array对象定义了apply方法,则可以用如下表达式来创建数组:

Array(“Mary”,”had”,”a”,”little”,”lamb”)

辨析:

Array(100) 返回的是拥有1个元素的数组。元素值为100。

new Array(100) 返回的是拥有100个元素的数组。每个元素值为null。

例:

class ApplyOperation{}

class ApplyTest{

  def haveTry{

    println(“Have a try on apply!”)

  }

}

object ApplyTest{

  def apply() = new ApplyTest

}

object ApplyOperation extends App {

  val a = ApplyTest()

  a.haveTry

}

例:

class HelloWorld(var m:String,n:Char){...}

object HelloWorld{

    def apply(n:Char)=new HelloWorld(“ ”,n)

}

val hi=HELLOWORLD(‘j’)

例:

class Account private(val id:Int,initialBalance:Double){

  private var balance = initialBalance

}

object Account{

  def apply(initialBalance:Double) = new Account(newUniqueNum ,initialBalance)

}

构造账号对象:

val acct = Account(1000.0)

class中使用apply方法

apply方法一般只使用于object。class中也可以使用,但不常用。

例:

class ApplyOperation{}

class ApplyTest{

def apply() = "apply in class"

def haveTry{

    println("Have a try on apply!")

  }

}

object ApplyTest{

def apply() = new ApplyTest

}

object ApplyOperation extends App {

val a = new ApplyTest

val applyStr = a();

  println(applyStr)

}

技术分享

输出:

技术分享

Scala继承

继承是类的拓展。

extends是Scala中实现继承的保留字:

class week extends month{...}

说明:

week类继承了month类所有非私有成员。

week类是month类的子类,month类是week类的超类。

子类能重写超类的成员(具有相同名称和参数)。

例:

class Student(name:String , age:Int ,val major : String) extends Person(name , age) {

  println(“this is subclass of Person , major is :” + major)

}

单例对象同样能从类中继承,与类的继承语法相同:

object day extends week{...}

单例对象是否能被继承呢?

重写

Scala中使用override保留字进行方法、字段重写

class week extends month{

override def firstday = {...}

}

override保留字实际使用类似与private,声明这个保留字后的定义、声明是对超类的重写,因此,其也可以写在类定义的参数中

class week(override val lastday:String) extends month{...}

子类的重写或修改Scala会检查其超类,但是,超类的修改并不会检查其子类

例:

class Student(name:String , age:Int ,val major : String) extends Person(name , age) {

  println(“this is subclass of Person , major is :” + major)

  override def toSting = “override toSting”

}

重写包括字段和方法,但参数不同的方法可以不重写

class month{ def secondday(m:String)={...}}

class week extends month{ def secondday ={...}}

规则:

重写 def

用val :利用val能重写超类用没有参数的方法(getter)

用def:子类的方法与超类方法重名

用var:同时重写getter、setter方法,只重写getter方法报错

重写val

用val:子类的一个私有字段与超类的字段重名,getter方法重写超类的getter方法

重写var

用var:且当超类的var是抽象的才能被重写,否则超类的var都会被继承

例:

class month{

  val one = 25 //可在子类中用val重写

  var two = 15 //不可在子类中用var重写,因为不是抽象的

  var three:Int

  def firstday =                               //可在子类中用val重写

  def now =                                    //可在子类中用var重写

  def now_ =                                

  def lastday(m:Char)={}                //可在子类中用def重写

}

总结:

子类中,def只能重写超类的def,val能重写超类的val或不带参数的def,var只能重写超类中抽象的var或者超类的getter/setter对。

匿名子类

val alien = new Person(“Fred”){

  def greeting = “Greetings , Earthling! My name is Fred”

}

Scala基础:面向对象——类

标签:

原文地址:http://www.cnblogs.com/shijiaqi1066/p/4608924.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!