首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何解决Scala中从最终类非法继承的问题

如何解决Scala中从最终类非法继承的问题
EN

Stack Overflow用户
提问于 2013-07-21 22:07:37
回答 2查看 3.4K关注 0票数 2

当我定义a值时,我用Scala编写了这段代码,我还调用了对象中的一些方法,比如setStr,它非常有用,令人惊叹。但是当我将我的AClass定义为final时,编译器会抛出一个异常,因为非法继承了final类。在某些情况下,我应该使用final类,在类初始化之后调用这种类型的方法对我来说非常有用,我的问题是如何解决这个问题

代码语言:javascript
运行
复制
test("Test function call") {
    val a: AClass = new AClass {
        setStr("Pooya")
        func1(this)
    }
}

class AClass { // when I declare the class final, the compiler will raise an error
    private var str:String=""
    def setStr(str:String)={
        this.str=str
    }
    def aMethod() = print(str)
}

def func1(a: AClass) {
    a.aMethod()
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-21 22:30:42

当你使用new AClass { ... }时,你正在创建一个扩展这个类的匿名类。当一个类是final时,它不能被扩展。

一种做你想做的事情的方法是这样的:

代码语言:javascript
运行
复制
val a: AClass = new AClass 
import a._
setStr("Pooya")
func1(this)

遵循@Vladimir的建议,以一种稍微干净的方式:

代码语言:javascript
运行
复制
val a: AClass = { val a = new AClass 
  import a._
  setStr("Pooya")
  func1(this) 
  a 
}

现在,您可以多次重复该操作,而不会使setStr模棱两可。对于具有当前定义的func1来说,它是否在{}块中应该无关紧要。

票数 3
EN

Stack Overflow用户

发布于 2013-07-22 15:14:48

要获得final语义,请将初始状态传递给构造函数。

另一种模式是使用早期定义。请注意,BClass#strs是最终版本。

最后的意思是当你的初始化器完成时,值不能改变。

并失去可变状态。

但是,如果您喜欢或需要可变性,那么在构建对象时,可以使用伴生对象上的工厂来处理您需要的任何正常工作。

代码语言:javascript
运行
复制
package inheritthewind

object Test extends App {
  val a = new AClass(new AInit { val str = "Pooya" })
  a.aMethod()
  val b = new {
    val str: String = "Pooya"
  } with BClass
  b.aMethod()
  val b2 = new BClass {
    val str: String = "Pooya"
  }
  b2.aMethod()  // uh no, result is "nulls"
  val c = CClass(new CPrototype { val str = "Pooya" })
  c.aMethod()
  // not allowed
  //val nope = new CClass
}

trait AInit {
  def str: String
}

final class AClass(init: AInit) {
  private final val str: String = init.str
  def aMethod() = Console println str
}

abstract class BClass {
  val str: String
  final val strs = str + "s"
  def aMethod() = Console println strs
}

trait CPrototype extends AInit

final class CClass private() {
  private var str: String = _
  def aMethod() = Console println str
}
object CClass {
  def apply(p: CPrototype): CClass = {
    val res = new CClass
    res.str = p.str
    res
  }
}

代码语言:javascript
运行
复制
scala> :javap -pv inheritthewind.BClass
[snip]
  private final java.lang.String strs;
    flags: ACC_PRIVATE, ACC_FINAL

  public abstract java.lang.String str();
    flags: ACC_PUBLIC, ACC_ABSTRACT

  public final java.lang.String strs();
    flags: ACC_PUBLIC, ACC_FINAL
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17773189

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档