Scala-隐式转换-私有函数-重载-构造器

本文介绍Scala中的类构造过程,包括先决条件设置、函数与操作符重载、私有函数使用及隐式转换等核心概念,并通过Rational类实例进行详细解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.zhu.scala

/**
  * Created by zhuhailong-dc on 2017/3/3.
  *
  * Scala编译器将把你放在类内部的任何不是字段的部分或者方法定义的代码,编译进主构造器中
  * 1.先决条件
  * 2.函数重载
  * 3.操作符重载
  * 4.私有函数
  * 5.隐式转换
  */

class Rational(n:Int,d:Int){
  //先决条件使用 require
  require(d!=0)
  require(n!=1)

  //在初始化Rational对象的时候执行
  //println("created "+n+"/"+d)

  //重载toString函数
  override def toString = n+"/"+d

  //添加字段
  val number:Int=n
  val denom:Int=d
  def add(that:Rational):Rational={
    println(n)
    println(d)
    new Rational(number*that.denom+that.number*denom,denom*that.denom)
  }

  def lessThan(that:Rational)=this.number*that.denom<that.number*this.denom
  def max(that:Rational)=if(this.lessThan(that)) that else this

  /**
    * 从构造器
    * Scala里的每一个从构造器的第一个动作都是调用同一个类里面其他的构造器.换句话说就是,每个Scala类里的每个从构造器都是以this(..)
    * 形式开头的.被调用的构造器即可以是主构造器,也可以是从文本上来看早于调用它的其他构造器.这个规则的根本结果就是每一个Scala
    * 的构造器调用终将结束于对类的主构造器的调用.因此主构造器是类的唯一入口点
    */

  def this(n:Int)=this(n,1)

  //私有字段和方法
  private def gcd(a:Int,b:Int):Int=if(b==0) a else gcd(b,a%b)
  private val g=gcd(n.abs,d.abs)

  //定义操作符
  def +(that:Rational):Rational=new Rational(number*that.denom+that.number*denom,denom*that.denom)
  def *(that:Rational):Rational=new Rational(number*that.number,denom*that.denom)

  //scala标识符

  //方法重载
  def +(i:Int):Rational=new Rational(number+i*denom,denom)

}

object Scala_4 {
  def main(args: Array[String]): Unit = {
    val rational=new Rational(2,2) //如果给0会提示 java.lang.IllegalArgumentException: requirement failed
    //println(rational.toString)

    val tmp1=new Rational(2,2)
    val tmp2=new Rational(2,3)
    val res1=tmp1 add tmp2
    val res2=tmp1.add(tmp2)
    val res3=tmp1 add(tmp2)

    //println(res1)
    //println(res2)
    //println(res3)

    val x=new Rational(2,2)
    val y=new Rational(2,3)
    //println(x+y)
    //println(x.+(y))
    //println(x+x*y)

    //隐式转换
    /**
      * 会抛出异常 2没有 * 方法
      * 这行代码定义了从Int到Rational的转换方法,方法前面的implicit修饰符告诉编译器若干情况下自动调用它
      */
    implicit def intToRational(x:Int)=new Rational(x)
    val r=new Rational(2,3)
    println(2*r)

  }
}


<think>嗯,用户现在想了解Scala构造器与Java的区别,以及相关的填空题答案。首先,我需要回忆一下Scala和Java在构造器方面的不同点。 Scala的主构造器是直接嵌入在类定义中的,这点和Java不同。Java的构造器有明确的名称,与类名相同,而Scala的主构造器参数直接写在类名后面。比如,Scala的类定义可能是class Person(name: String, age: Int),而Java则需要显地写一个构造方法。 接下来,参数的处理。Scala的主构造器参数可以自动转换为字段,特别是如果用val或var声明的话。例如,如果写成class Person(val name: String),那么name会自动成为类的字段。而Java中,构造函数的参数不会自动转为字段,需要手动定义类的字段并在构造函数中赋值。 编译后的差异也很重要。Scala编译后,主构造器会被编译成一个构造函数,可能包含类体中的所有语句。而Java的构造函数在编译后是独立的方法。 然后是关于填空题的答案。用户可能需要填空的地方可能涉及主构造器的参数是否生成字段、是否需要显调用父类构造器等。例如,Scala中如果主构造器参数没有val/var,默认不会生成字段,而Java必须显定义字段。另外,Scala的主构造器调用父类构造器,而Java如果不写super(),则会调用父类的无参构造器。 还需要考虑用户可能的误区,比如Scala的主构造器参数默认可见性,是否支持多个构造器等。Scala支持多个辅助构造器,但必须最终调用主构造器,而Java可以有多个构造器,各自独立。 然后,结合提供的引用内容,引用[1]提到Scala的trait和Java接口的区别,虽然不直接相关,但可能帮助确认Scala的特性。引用[2]中的Java final修饰符可能和构造器中的不可变字段有关联,但需要具体分析。引用[3]关于Spark的内容可能暂时无关。 最后,确保回答结构清晰,分点列出区别,并给出填空题的答案示例,可能涉及参数转字段、构造器定义方、继承中的构造器调用等。</think>### Scala构造器与Java构造器区别及填空题答案 #### 一、Scala构造器核心特点 1. **定义方** Scala构造器直接嵌入类声明中,参数列表紧接类名: ```scala class Person(val name: String, age: Int) // name为公有字段,age为私有临时变量 ``` Java需要显编写构造方法: ```java public class Person { private String name; public Person(String name, int age) { this.name = name; } } ``` 2. **参数自动生成字段规则** - 使用 `val`/`var` 修饰的 Scala构造器参数**自动生成公有/可变字段** - 未修饰的参数**仅作为类内部临时变量**,不会生成字段[^1] 3. **代码执行逻辑** Scala构造器包含**类体中所有语句**(除方法外的表达): ```scala class Demo(msg: String) { println(s"初始化消息:$msg") // 属于主构造器逻辑 } ``` 4. **继承关系处理** Scala构造器**调用父类无参构造器**,若需显调用需通过 `extends` 子句: ```scala class Child(arg: Int) extends Parent(arg) // 显调用父类构造器 ``` #### 二、与Java构造器关键差异对比 | 特性 | Scala构造器 | Java构造器 | |---------------------|---------------------------------------|-------------------------------| | 定义位置 | 类声明行 | 类内部独立方法 | | 多构造器支持 | 必须通过辅助构造器实现 | 允许多个重载构造器 | | 字段自动生成 | 通过val/var声明自动转换 | 需手动声明和赋值 | | 代码执行范围 | 包含类体中所有顶层语句 | 仅构造方法体内代码 | | 父类构造器调用 | 通过extends子句显指定 | 通过super()在第一行/显调用| #### 三、典型填空题答案示例 1. **Scala构造器参数默认生成字段的条件是______** → 必须使用`val`或`var`修饰符 2. **Java子类构造器必须显调用父类构造器的情况是______** → 当父类没有无参构造器时 3. **Scala中类体内直接编写的println语句会被编译到______中** → 主构造器 4. **与Java不同,Scala构造器的参数可以具有______级别的可见性** → `private val`/`protected var`等完整访问修饰符 : Scala官方文档指出主构造器参数若未用val/var修饰,仅在类内可见且不生成字段 [^2]: Java构造器必须通过new关键字调用,而Scala构造器随对象创建执行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值