一.本章要点

  • 类中的字段自动带有getter方法和setter方法
  • 你可以用定制的getter/setter方法替换掉字段的定义,而不必修改使用类的客户端——这就是所谓的”统一访问原则“
  • 用@BeanProperty注解来生成JavaBean的getXxx/setXxx方法
  • 每个类都有一个主要的构造器,这个构造器和类定义”交织“在一起。它的参数直接称为类的字段。主构造器执行类体中所有的语句
  • 辅助构造器是可选的。它们叫做this

二.简单类和无参方法

Class Counter{
private var value=0 //你必须初始化字段
def increment(){ value=+1}// 方法默认是共有的
def current=value //可以用不带()的方式强制风格
}

  注:调用无参方法时,可以写上(),也可以不写,这里有一种风格(对于改值器方法[改变对象状态的方法]使用(),而对于取值器方法[不会改变对象状态的方法]去掉())

三.带getter和setter的属性

  Scala为每个字段都提供getter和setter方法 (gettter和setter分别对应xxx和xxx_)。

  注:

      • 如果字段是私有的,则getter和setter方法也是私有的;
      • 如果字段是val,则只有getter方法被生成;
      • 如果你不需要仍个getter和setter,可以将字段声明为private[this]    

四.只带getter的属性

  有时候你需要一个只读属性,有getter但没有setter,则可以使用val字段,这样Scala会生成一个私有的final字段和一个getter方法。

  注:

    通过这种方式客户端不能任意改值,但如果需要可以通过其他方式根据自己的需求改变,且在Scala中不能实现只写属性,例:

class Counter{
private var value=0
def increment(){value+=1}
def current=value }

  小结:

      • var foo:Scala会自动合成一个getter和setter
      • val foo:Scala自动合成一个getter
      • 由你来定义foo和foo_=方法
      • 由你来定义foo方法  

五.对象私有字段

  在Scala中,和Java/C++等一样,方法可以访问所有对象的私有字段,例:

Class Counter{
private var value=0
de increment(){value+=1}
def isLess(other:Counter)=value<other.value
//同样可以访问另一个对象的私有字段
}

  于是Scala允许我们定义更严格的访问限制,通过private[this]修饰符来实现。(private[this] var value=0 //类似某个对象.value这样的访问将不被允许,因此Counter类的方法只能访问当前对象的value字段,而不能访问同样是Counter类型的其他对象的字段,这样的访问有时被称为对象私有的[对于对象私有的字段,Scala根本不会生成getter和setter方法])。

  注:Scala允许你将访问权赋予指定的类,private[类名]修饰符可以定义仅有指定类的方法可以访问给定的字段。这里的类名必须是当前定义的类或者是包含该类的外部类。

六.Bean属性

  Scala会对定义的字段提供setter和getter方法,但是这些名称都不是预期的(Java工具依赖于setFoo和getFoo这样的命名)。使用@BeanProperty会自动生成四个方法,例子:

impoer scala.reflect.BeanProperty
class Person{
@BeanProperty var name:String=_
}

  提供的四个方法:

    1.name:String;

    2.name_=(new Value:String):Unit;

    3.getName():String;

    4.setName(new Value:String):Unit  

七.辅助构造器

  Scala和Java一样,可以有任意多个构造器(一个主构造器[重要]多个辅助构造器)。

  注意(构造器与Java/C++不同点):

    1.辅助构造器的名称是this(而不像Java中与类名相同);  

    2.每一个辅助构造器都必须以一个对先前已经定义的其他辅助构造器或主构造器的调用开始

  例:

class Person{
private var name=""
private var age=0
def this(name:String){
//一个辅助构造器
this()//调用主构造器
}
def this(name:String,age:Int){
this(name) //调用前一个辅助构造器
this.age=age
} }

八.主构造器

  如果没有显式定义主构造器,则自动拥有一个无参的主构造器(简单的执行类体中的所有语句而已)。

  要点:

    1.主构造器的参数直接放置在类名之后:

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

    2.主构造器会执行类定义中的所有语句(如配置某个字段的特性时非常有用)

class MyProg{
private val props=new Properties
props.load(new FileReader("myprog.properties"))
//上述语句是主构造器的一部分
}

  注:

    主构造器的参数可以是任意形态的,如private,val,var的;

    也可以是普通的方法参数(不加val/var),这样的参数如何处理取决于它们在类中如何被使用,如:

      1.不带val/var的参数至少被一个方法使用,则升格为字段,类似于private[this] val字段的效果;

      2.否则,该参数不被保存为字段(仅仅是可以被主构造器访问的普通参数)

    如果想把构造器变成私有的,可以calss Person private(val id:Int){...}

九.嵌套类

  Scala中,几乎可以任何语法结构嵌套任何语法结构(函数中嵌套函数,类中嵌套类)

  

import scala.collection.mutable.ArrayBuffer
class Network{
class Member(val name:String){
val contacts=new ArrayBuffer[Member]
}
private val members=new ArrayBuffer[Member]
def join(name:sSring)={ val m=new Member(name)
member+=m
m
}
}

  每个实例对象都有自己的Member类,这和Java不同(Java的内部类从属于外部类)。

每个实例只能在各自中添加成员,而不能跨实例。

  如果不希望是上图那样,可以使用伴生对象或者类型投影:

伴生对象

类型投影

建立引用别名

十.练习

  

  1.

class Counter {
private var value = 0 def increment = if (value == Int.MaxValue) value else value += 1 def current = value } object Counter {
def main(args: Array[String]): Unit = {
val counter = new Counter
for (i <- 1 to Int.MaxValue)
counter.increment
println(counter.current) }

  2.

class BankAccount {
private var balance: Double = 0.0 def deposit(depamount: Double) = {
balance += depamount
} def withdraw(drawamount: Double) = {
balance -= drawamount
} def current = balance } object BankAccount {
def main(args: Array[String]): Unit = {
val bankAccount = new BankAccount
bankAccount.deposit(1000)
bankAccount.withdraw(200)
print(bankAccount.current)
}
}

  3.

class Time {
private var hours: Int = 0
private var minute: Int = 0 def this(hr: Int, min: Int) = {
this()
this.hours = hr
this.minute = min
} def before(other: Time): Boolean = {
hours < other.hours || (hours == other.hours && minute < other.minute)
} def <(other: Time) = before(other)
}
object Time{
def main(args: Array[String]): Unit = {
val t1=new Time(20,20)
val t2=new Time(20,25)
print(t1 < t2)
}
}

  4.

class TimeMinute {
private var minute: Int = 0 def this(hr: Int, min: Int) = {
this()
this.minute = min + hr*60
} def before(other: TimeMinute): Boolean = {
minute < other.minute
} def <(other: TimeMinute) = before(other)
} object TimeMinute {
def main(args: Array[String]): Unit = {
val t1 = new TimeMinute(22, 20)
val t2 = new TimeMinute(22, 25)
print(t1 < t2)
}
}

  5.

import scala.beans.BeanProperty

class Student {
@BeanProperty var id: Long = 0L
@BeanProperty val name: String = null }

  6.

class Person(ag: Int) {
val age = if (ag > 0) ag else 0
}
object Person{
def main(args: Array[String]): Unit = {
val p=new Person(-12)
println(p.age)
}
}

  7.

class Person(namestr: String) {
val firstName = namestr.split(" ")(0)
val lastName = namestr.split(" ")(1) }

  8.

class Car(val producer: String, val modelName: String, val modelYear: Int = -1, var carCode: String = "") {
}

  9.

 public class Car {
private String producer;
private String modelName;
private int modelyear;
private String carCode; public Car() { } public Car(String producer, String modelName) {
this.producer = producer;
this.modelName = modelName;
this.modelyear = -1;
this.carCode = "";
} public Car(String producer, String modelName, String carCode) {
this.producer = producer;
this.modelName = modelName;
this.modelyear = -1;
this.carCode = carCode;
} public Car(String producer, String modelName, int modelYear, String carCode) {
this.producer = producer;
this.modelName = modelName;
this.modelyear = modelYear;
this.carCode = carCode;
} public String getProducer() {
return producer;
} public void setProducer(String producer) {
this.producer = producer;
} public String getModelName() {
return modelName;
} public void setModelName(String modelName) {
this.modelName = modelName;
} public int getModelyear() {
return modelyear;
} public void setModelyear(int modelyear) {
this.modelyear = modelyear;
} public String getCarCode() {
return carCode;
} public void setCarCode(String carCode) {
this.carCode = carCode;
}
}

  10.

class Employ(val name:String,var salary:Double){
}

Scala学习五——类的更多相关文章

  1. Scala学习(五)---Scala中的类

    Scala中的类 摘要: 在本篇中,你将会学习如何用Scala实现类.如果你了解Java或C++中的类,你不会觉得这有多难,并且你会很享受Scala更加精简的表示法带来的便利.本篇的要点包括: 1. ...

  2. Scala学习(五)练习

    Scala中的类&练习 1. 改进Counter类,让它不要在Int.MaxValue时变成负数 程序代码: class Counter { private var value=100 def ...

  3. scala学习笔记——类和对象

    基础语法关于Scala程序,这是非常要注意以下几点. 区分大小写 - Scala是大小写敏感的,这意味着标识Hello 和 hello在Scala中会有不同的含义. 类名 - 对于所有的类名的第一个字 ...

  4. PHP面向对象学习五 类中接口的应用

    类中接口的应用 接口:一种成员属性全部为抽象的特殊抽象类,在程序中同为规范的作用   抽象类:1.类中至少有一个抽象方法.2.方法前需要加abstract 接口: 1.类中全部为抽象方法,抽象方法前不 ...

  5. scala 学习笔记(04) OOP(上)主从构造器/私有属性/伴生对象(单例静态类)/apply方法/嵌套类

    一.主从构造器 java中构造函数没有主.从之分,只有构造器重载,但在scala中,每个类都有一个主构造器,在定义class时,如果啥也没写,默认有一个xxx()的主构造器 class Person ...

  6. Scala中的类学习

    Scala中的类学习 从java了解类的情况下,了解Scala的类并不难.Scala类中的字段自动带getter和setter方法,用@BeanProperty注解生成javaBean对象的getXX ...

  7. Scala学习随笔——深入类和对象

    函数化对象(又称方程化对象)指的是所定义的类或对象不包含任何可以修改的状态. 本篇随笔就是着重记录函数化对象.定义了一个有理数类定义的几个不同版本,以介绍 Scala 类定义的几个特性:类参数和构造函 ...

  8. scala学习-类与对象

    类 / 对象 [<快学Scala>笔记] 一.类 1.Scala中的类是公有可见性的,且多个类可以包含在同一个源文件中: class Counter{ private var value ...

  9. scala学习笔记(四)样本类与模式匹配

    访问修饰符 格式:private[x]或protected[x],x指某个所属包.类或单例对象,表示被修饰的类(或方法.单例对象),在X域中公开,在x域范围内都可以访问: private[包名]:在该 ...

随机推荐

  1. centos7下面改变亮度

    通过改自己的配置文件来改变亮度的方法在我的机器上面是不中用了,我的是台式机,我用的集成显卡,目前我找到的还勉强的方法就是通过安装redshift来改变屏幕的亮度,我就是不喜欢太亮,差点瞎了. 具体是这 ...

  2. Leetcode题目39.组合总和(回溯+剪枝-中等)

    题目描述: 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的数字可以无 ...

  3. 【零基础】搞懂GPU为什么比CPU“快”

    一.前言 近几年深度学习在各领域大显神威,而”GPU加速"也得到了越来越多的篇幅,似乎任何程序只要放到GPU上运行那速度就是杠杠的.GPU代替CPU计算已成了大势所趋?我先告诉你结论”那是不 ...

  4. vuejs2项目开发实战视频教程

    0.课程大纲 一.点餐系统(移动) 1.0.课件 1.1.项目初始化_首页顶部 1.2.首页列表_底部导航 1.3.商家顶部_商家优惠信息弹层 1.4.商品主体_类别菜单 1.5.购物车操作_商品信息 ...

  5. idea svn 主干分支切换

    使用快捷键ctrl+t或者点击工具栏中的 vcs update 出现如下窗口:点击复选框,在框2中进行选择你要切换的分支的地址,点击OK即可 : 查看是否切换成功可以再version control ...

  6. 几句java代码搞定十万个为什么数据

    最近想做一个app,为小朋友推荐十万个为什么的故事,但是找了很久数据,发现挺难的找的,又去写爬虫,发现没有一个好的网站可以爬,最后一个偶然的机会在csdn上发现一个可用的接口,很快就把问题解决了,下面 ...

  7. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_3-4.动态Sql语句Mybaties SqlProvider

    笔记 4.动态Sql语句Mybaties SqlProvider     简介:讲解什么是动态sql,及使用 1.             @UpdateProvider(type=VideoSqlP ...

  8. Vim的强大配置文件

    我的vim配置主要有以下优点: 1.按F5可以直接编译并执行C.C++.java代码以及执行shell脚本,按“F8”可进行C.C++代码的调试 2.自动插入文件头 ,新建C.C++源文件时自动插入表 ...

  9. CetOS 服务不支持 chkconfig 的解决方法

    今天在添加Elasticsearch系统自动启动服务的时候,提示 “服务 elasticsearch 不支持 chkconfig ”,如下图: 后来查找了下原因,是脚本编写的不符合规范,缺少关键的前三 ...

  10. docker命令小结

    文档:docker命令小结.note链接:http://note.youdao.com/noteshare?id=54015b76db9ae764182cb921e348b7fc&sub=DD ...