http://blog.csdn.net/pipisorry/article/details/52902609

Scala类和对象

类是对象的抽象,而对象是类的具体实例。类是抽象的,不占用内存,而对象是具体的,占用存储空间。类是用于创建对象的蓝图,它是一个定义包括在特定类型的对象中的方法和变量的软件模板。

类的创建和实例化

class Point(xc: Int, yc: Int) {
   var x: Int = xc
   var y: Int = yc

   def move(dx: Int, dy: Int) {
      x = x + dx
      y = y + dy
      println ("x 的坐标点: " + x);
      println ("y 的坐标点: " + y);
   }
}

Scala中的类不声明为public,一个Scala源文件中可以有多个类。

以上实例的类定义了两个变量 xy ,一个方法:move,方法没有返回值。

Scala 的类定义可以有参数,称为类参数,如上面的 xc, yc,类参数在整个类中都可以访问。

接着我们可以使用 new 来实例化类,并访问类中的方法和变量:

import java.io._

class Point(xc: Int, yc: Int) {
   var x: Int = xc
   var y: Int = yc

   def move(dx: Int, dy: Int) {
      x = x + dx
      y = y + dy
      println ("x 的坐标点: " + x);
      println ("y 的坐标点: " + y);
   }
}

object Test {
   def main(args: Array[String]) {
      val pt = new Point(10, 20);

      // 移到一个新的位置
      pt.move(10, 10);
   }
}

实例的默认参数

def this() = this(x = 1, y = 2)

Scala 继承

Scala继承一个基类跟Java很相似, 但我们需要注意一下几点:

  • 1、重写一个非抽象方法必须使用override修饰符。
  • 2、只有主构造函数才可以往基类的构造函数里写参数。
  • 3、在子类中重写超类的抽象方法时,你不需要使用override关键字。

继承会继承父类的所有属性和方法,Scala 只允许继承一个父类。

Scala重写一个非抽象方法,必须用override修饰符。

实例:

class Point(xc: Int, yc: Int) {
   var x: Int = xc
   var y: Int = yc

   def move(dx: Int, dy: Int) {
      x = x + dx
      y = y + dy
      println ("x 的坐标点: " + x);
      println ("y 的坐标点: " + y);
   }
}

class Location(override val xc: Int, override val yc: Int,
   val zc :Int) extends Point(xc, yc){
   var z: Int = zc

   def move(dx: Int, dy: Int, dz: Int) {
      x = x + dx
      y = y + dy
      z = z + dz
      println ("x 的坐标点 : " + x);
      println ("y 的坐标点 : " + y);
      println ("z 的坐标点 : " + z);
   }
}

Scala 使用 extends 关键字来继承一个类。实例中 Location 类继承了 Point 类。Point 称为父类(基类),Location 称为子类。

override val xc 为重写了父类的字段。

皮皮blog

Scala单例对象与伴生对象

Scala的单例对象

Scala没有 static 这个东西,不能定义静态成员,而是代之定义单例对象(singleton object)。以object关键字定义。
对象定义了某个类的单个实例,包含了你想要的特性:

object Accounts{
    private var lastNumber = 0
    def newUniqueNumber() = { lastNumber += 1; lastNumber}
}

当你在应用程序中需要一个新的唯一账号时,调用Account.newUniqueNumber()即可。
对象的构造器在该对象第一次被使用时调用。

在下面几个场景下可以使用Scala单例对象:

- 作为存放工具函数或常量的地方
- 高效地共享单个不可变实例
- 需要使用单个实例来协调某个服务时

类和单例对象间的差别是,单例对象不带参数,而类可以。因为单例对象不是用new关键字实例化的,所以没机会传递给它实例化参数。每个单例对象都被实现为虚拟类(synthetic class)的实例,并指向静态的变量,因为它们与Java静态类有相同的初始化语义。

独立对象(standalone object)

不与伴生类共享名称的单例对象称为独立对象。它可以用在很多地方,例如作为相关功能方法的工具类,或者定义Scala应用的入口点。

伴生对象(companion object)

当单例对象与某个类共享同一个名称时,它就被称为是这个类的伴生对象(companion object)。类和它的伴生对象必须定义在同一个源文件中。类被称为是这个单例对象的伴生类(companion class)。类和它的伴生对象可以互相访问其私有成员

1
2
3
4
5
6
7
8
9
10
11
class Account {
val id = Account.newUniqueNumber()
private var balance = 0.0
def deposit(amount: Double){ balance += amount }
...
}
object Account { //伴生对象
private var lastNumber = 0
def newUniqueNumber() = { lastNumber += 1; lastNumber}
}

注意

  • 类的伴生对象可以被访问,但并不在作用域当中。Account类必须通过Account.newUniqueNumber()来调用伴生对象的方法。
  • 在REPL中,要同时定义类和对象,必须用粘贴模式。键入:paste,然后键入或粘贴类和对象的定义,最后一Ctrl+D退出粘贴模式。

将伴生对象作为工厂使用

我们通常将伴生对象作为工厂使用。
下面是一个简单的例子,可以不需要使用’new’来创建一个实例了。

1
2
3
4
5
class Bar(foo: String)
object Bar {
def apply(foo: String) = new Bar(foo)
}

单例对象实例

import java.io._

class Point(val xc: Int, val yc: Int) {
   var x: Int = xc
   var y: Int = yc
   def move(dx: Int, dy: Int) {
      x = x + dx
      y = y + dy
   }
}

object Test {
   def main(args: Array[String]) {
      val point = new Point(10, 20)
      printPoint

      def printPoint{
         println ("x 的坐标点 : " + point.x);
         println ("y 的坐标点 : " + point.y);
      }
   }
}

伴生对象实例

/* 文件名:Marker.scala */

// 私有构造方法
class Marker private(val color:String) {
  println("创建" + this)
  override def toString(): String = "颜色标记:"+ color
}

// 伴生对象,与类共享名字,可以访问类的私有属性和方法
object Marker{
    private val markers: Map[String, Marker] = Map(  //一调用这个函数,就会创建3个class Marker
      "red" -> new Marker("red"),
      "blue" -> new Marker("blue"),
      "green" -> new Marker("green")
    )
    def apply(color:String) = {
      if(markers.contains(color)) markers(color) else null
    }
    def getMarker(color:String) = {
      if(markers.contains(color)) markers(color) else null
    }

    def main(args: Array[String]) {
        println(Marker("red"))       //println会调用object Marker的toString函数,伴生对象就直接调用class Marker的toString函数了。
        // 单例函数调用,省略了.(点)符号
	println(Marker getMarker "blue")
    }
}
$ scalac Marker.scala
$ scala Marker
创建颜色标记:red
创建颜色标记:blue
创建颜色标记:green
颜色标记:red
颜色标记:blue

[【Scala】单例对象与伴生对象]

皮皮blog

Scala Trait(特征)

Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。

与接口不同的是,它还可以定义属性和方法的实现。

一般情况下Scala的类只能够继承单一父类,但是如果是 Trait(特征) 的话就可以继承多个,从结果来看就是实现了多重继承。

Trait(特征) 定义的方式与类类似,但它使用的关键字是 trait,如下所示:

trait Equal {
  def isEqual(x: Any): Boolean
  def isNotEqual(x: Any): Boolean = !isEqual(x)
}

以上Trait(特征)由两个方法组成:isEqualisNotEqual。isEqual 方法没有定义方法的实现,isNotEqual定义了方法的实现。子类继承特征可以实现未被实现的方法。所以其实 Scala Trait(特征)更像 Java 的抽象类。

特征构造顺序

特征也可以有构造器,由字段的初始化和其他特征体中的语句构成。这些语句在任何混入该特征的对象在构造是都会被执行。

构造器的执行顺序:

  • 调用超类的构造器;
  • 特征构造器在超类构造器之后、类构造器之前执行;
  • 特质由左到右被构造;
  • 每个特征当中,父特质先被构造;
  • 如果多个特征共有一个父特质,父特质不会被重复构造
  • 所有特征被构造完毕,子类被构造。

构造器的顺序是类的线性化的反向。线性化是描述某个类型的所有超类型的一种技术规格。

from: http://blog.csdn.net/pipisorry/article/details/52902609

ref:

Scala:类,对象和特征(接口)的更多相关文章

  1. 将Model实体类对象作为WebService接口参数(转)

    转自:http://www.cnblogs.com/fengyishou/archive/2009/02/27/1399281.html 关于web服务的有关基础知识,看了基本书,但是不敢在这里乱说, ...

  2. spark快速开发之scala基础之3类,对象,特征

    类 scala的类定义非常灵活 class test4 class test2{} class test3(x:Int) 定义一个带构造函数的类 class Point (x : Int,y : In ...

  3. Scala类与对象

    类简介 简介 类是对象的蓝图.一旦你定义了类,就可以用关键字new根据类的蓝图创建对象.在类的定义里,可以放置字段和方法,这些被笼统地称为成员.对于字段,不管是val还是var定义的,都是指向对象的变 ...

  4. Spark记录-Scala类和对象

    本章将介绍如何在Scala编程中使用类和对象.类是对象的蓝图(或叫模板).定义一个类后,可以使用关键字new来创建一个类的对象. 通过对象可以使用定义的类的所有功能. 下面的图通过一个包含成员变量(n ...

  5. Scala学习——类,继承,接口(中)

    基本类的使用:(初) package com.dtspark.scala.basics /** * trait是一个接口 * 接口的第一次继承用extends,多继承时用with * 多继承时,如果这 ...

  6. Scala类和对象(二)

    1. 类和属性 1.1 如何控制构造函数字段的可见性 在Scala中: 如果一个字段被声明为var, Scala会为该字段生成getter和setter方法. 如果字段是val, Scala只生成ge ...

  7. Java中的对象、类、抽象类、接口的理解

    1.对象 对象是个具体的东西,有着明确的属性特征和行为特征. 例如:你手上牵着的女朋友或男朋友就是个具体的对象. 如图中的苏格兰折耳猫,特征是耳朵向下呈折叠状,有着具体的颜色(你看到的颜色),并且和其 ...

  8. 【无私分享:ASP.NET CORE 项目实战(第二章)】添加EF上下文对象,添加接口、实现类以及无处不在的依赖注入(DI)

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 上一章,我们介绍了安装和新建控制器.视图,这一章我们来创建个数据模型,并且添加接口和实现类. 添加EF上下文对象 按照我们以前 ...

  9. 规则引擎集成接口(九)Java类对象

    Java类对象 右键点击“对象库” —“添加java类对象”,如下图: 弹出窗体,在文本框中输入类的全名“com.flagleader.test.Test”,选择该类型后确定,如下: 显示如下,勾选上 ...

随机推荐

  1. 关于阮大神的es6标准入门第一章

    题记:之前在10月份的时候写过阮大神的es6的第一章,但是由于那段时间项目组的动荡,所以也没有什么后续,导致我现在对es6基本都忘的差不多了,不过,现在换了新公司,最近也没什么任务,所以现在开始重新写 ...

  2. jsonViewer json格式化工具

    以前一直以来都觉得xml个可读性要比json的可读性好,后来使用了JSON Viewer这个小工具之后,发现自己错了.之前认为json的可读性差,完全是因为没有很好的查看工具.JSON Viewer这 ...

  3. SQL SERVER之查询外键及索引

    --查询表或数据库中的所有外键 select A.name as 约束名, object_name(b.parent_object_id) as 外健表, c.name as 外键列, object_ ...

  4. Jenkins + Gradle + pgyer + Android自动发布

    Jenkins配置与必要的环境配置 一:Jenkins服务端(Linux系统为例说明): 1.jdk安装与配置 2.SDK安装与配置 3.安装配置对应的gradle版本(建议gradle版本在4.1版 ...

  5. Spring Boot简单应用——会员管理系统

    简介 本项目是使用Spring Boot编写的一个简单的会员管理系统. 提供了会员的解决方案,主要有会员模块,管理员模块,礼品模块,商品模块,会员等级模块,生日提醒模块,积分模块,详细模块如下图 准备 ...

  6. OC/Swift/C/C++混合使用的编程姿势

    一,OC调用C语言方法 1.OC中的.m文件对C语言完全兼容,可以直接导入C头文件,进行使用 2.定义一个.c的C语言文件,在.m文件中导入,就可以使用.   二,OC调用C++语言方法 1.需要将. ...

  7. [JSOI2008]球形空间产生器

    Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球 面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧 ...

  8. 灰狼呼唤着同胞(brethren)

    先求出确定边的联通块,有cnt块,显然方案数为2^(cnt-1) 联通块用dfs很好求 但此题还有并查集解法,且与一道叫团伙的题很像 边为0为敌人,1为朋友,敌人的敌人是朋友,朋友的朋友是朋友,正好对 ...

  9. Codeforces Round #460 D. Karen and Cards

    Description Karen just got home from the supermarket, and is getting ready to go to sleep. After tak ...

  10. [UOJ UR #4追击圣诞老人]

    来自FallDream的博客,未经允许,请勿转载, 谢谢. 传送门 考虑直接维护一个堆,然后往里面丢链,并且取出k个堆顶就行了. 然后就需要分类讨论啥的,给你的三个点变成两条链,每次取出一条链之后选择 ...