scala学习-介绍scala的几种特性7

承接上篇,前提条件检查,使用require。
1添加成员变量
记得上篇的时候,使用了类参数的方式来构建主构造函数,但是这是由缺陷的。
现在我们构建一个两个rational相加的操作。

class Rational (n:Int,d:Int){
  println("i am a class construction~"+n+"/"+d)
  require(d!=0)
  override def  toString = n+"/"+d

  def add(that:Rational):Rational = {
    new Rational (n*that.d + that.n*d,d*that.d)
  }
}

这里写图片描述
这里编译都通不过的,为什么呢?在新定义的方法add中,是可以访问n和d的。但是对于that来说,无法使用that.d来访问d,因为that不再定义的类的访问范围之类。这也表明,d和n不能作为类Rational的成员变量,这是要定义成员变量了。做如下修改:

class Rational (n:Int,d:Int){
  println("i am a class construction~"+n+"/"+d)
  require(d!=0)
  val num=n
  val denom=d
  override def  toString = n+"/"+d
  def add(that:Rational):Rational = {
    new Rational (n*that.denom + that.num*d,d*that.denom)
  }
}

注意下的是,这里我们使用了val,因为我们要实现的是immutable的类定义。还有就是num,denom都用定义类型,其实add也不用,但是个人喜欢定义出来,方便阅读。
2引用自身
Scala中也可以使用this,和java的使用方式是一样的,是代表当前的对象,比如实现一个Rational是否小与另一个。

def lessthan(that:Rational)={
    this.num*that.denom<that.num*this.denom
  }
  def lessthan2(that:Rational)={
    num*that.denom<that.num*denom
  }

3辅助构造函数
以前我们说过,主构造函数,而且除了方法,整个类都会运行一次。除了主构造函数之外的构造函数,都叫做辅助构造函数。
这里定义一个Rational的辅佐构造函数,scala构造辅佐构造函数的语法为this(),且所有辅佐构造函数的语法都是这样。
所有辅佐构造函数的第一个语句都要调用其他的构造函数,不论是辅助构造函数还是主构造函数,这样设计的原因是,一个构造函数最后都会调用到主构造函数,使得主构造函数成为创建类对象的一个单一入口。提高一致性。
4私有成员和私有方法
和java一样都是使用private来修饰的,含义都是一样的。下面定义一个私有方法,求分子分母的最大公倍数。

class Rational (n:Int,d:Int){
  println("i am a class construction~"+n+"/"+d)
  require(d!=0)
    private val g = gcd(n,d)
  val num=n/g
  val denom=d/g
  override def  toString = n+"/"+d
  def add(that:Rational):Rational = {
    new Rational (n*that.denom + that.num*d,d*that.denom)
  }
  def lessthan(that:Rational)={
    this.num*that.denom<that.num*this.denom
  }
  def lessthan2(that:Rational)={
    num*that.denom<that.num*denom
  }
  def this (n:Int)={
    this(n,1) 
  } 
   private def gcd(a:Int,b:Int):Int =
     if(b==0) a else gcd(b, a % b)

}

自身调用自身,一定要加返回类型,其实,习惯还是加返回类型把,减少错误。还有要注意一点,scala中是按照顺序来初始化变量的,所以g变量要放在Num和denom之前。
5定义运算符
以前我们说过,在scala中运算符其实也就是一个方法而已,没有什么特殊,在上面的列子中,我们定义了一个add方法,你可以x.add(y),也可以x add y,使用,但是我们还可以直接使用+,-来做操作。

def +(that:Rational)={
        new Rational (n*that.denom + that.num*d,d*that.denom)
     }

这里写图片描述
这里的”i am a class^^”运行了3次,是因为new Rational了三次,运行了里面的println方法。
可以使用相同的方式扩展-,/,*等运算符的用法。
6标识符
其实和java比较相似,字符数据和符号,字符或者以下划线开始。符号的话,避免使用$符号,这是scala在编译时,有些时候要使用的,所以我们避免使用。其实习惯还是以字符开始,做了那么久项目还没遇见过以符号开始的规范。还是以驼峰结构。
这里写图片描述
还有这种混合的,字符和符号
7方法重载
和java一样,重载就是方法名相同,参数不同,假如我想,一个Rational可以和一个Int相加。可以这样

def +(that:Int)={
    new Rational(num+that*denom,denom)
  }```

val x = new Rational(2,1)
println(x+5)
“`
和java是一样的。
8隐式类型转换-这个比较重要
我们刚才定义了rational+Int,可以解决x+2的问题,但是如果是2+x呢,因为2是Int类型,Int类型没有支持相加的方法?这怎么办?1修改Int源码,加重载其+方法(想想也不可能用这种方法)。2通过静态扩展方法来实现,就是隐式类型转换。就是如果遇到2+x这种情况,Int没有这种方法,就把这个Int类型的实列转换成Rational类型。
scala中是通过implicit def来定义。
这里写图片描述
在eclipse中和教程说的不一样,我晕了个去了……是怎么回事呢?
但是在命令行环境是可以的。我个人觉得是这么回事,eclipse的编译scala的问题。原本编译器看见z+x的时候,发现Int没有+Rational的方法,它是要报错的,但是在它报错之前,会检测当前的作用域,发现了intToRational的方法,所以把它编译成了intToRational(z)+x。
估计eclipse编译的时候,有问题,所以才回出现这种情况。以后在研究下。
隐含类型转换在scala编程中,十分重要。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫二哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值