Scala类、对象、Case类、字面量
Scala类、对象、Case类、字面量
我正试图弄清楚Scala基本概念。每当使用关键字“new”实例化一个类时,我们就会获得一个新对象。使用“object”关键字声明的单例对象不能使用“new”关键字实例化,因为只能有一个。在某种意义上,它在编译时实例化。
4是一个Int的案例类吗?5.07是一个Double的案例类吗?
4是一个对象吗?
类本身有时候,或者总是对象吗?
函数是对象。它们也是类的实例吗?这怎么配合在一起?
Scala像Smalltalk一样纯粹的面向对象,还是在OO方面做了一些妥协?
4和5.07不是对象。它们只是Int和Double类的实例。在这里查看层次结构。
对象不是在编译时实例化的。当您第一次访问它时,它会被实例化(在对象主体/构造函数执行的意义上)。
函数也不是对象,它们是匿名类的实例,这些类扩展FunctionN(例如Function2)。但是,是的,有对象,提供一些常见的实用程序,允许您编写:
//instance of Function2 scala> val sum = (x: Int, y: Int) => x+y sum: (Int, Int) => Int =scala> sum.curried res0: Int => (Int => Int) = // now back to uncurried version with Function object scala> Function.uncurried(res0) res1: (Int, Int) => Int =
如果您对纯粹的类和案例类之间的差异感兴趣,请在这里查看。
不幸的是,我不知道Smalltalk以进行对比Scala OOP的纯洁度的假设。
当你使用 new
运算符来实例化一个类时,你会得到该类的一个新实例。这个新实例是一个对象。
你可以使用 object
关键字声明一个单例对象。说它在编译时被实例化并没有实际意义。对象只在程序运行时存在,而不是在程序编译时存在。一个 object
对象是在第一次使用时被实例化的。
4 是 Int 的一个 Case Class 吗?5.07 是 Double 的一个 Case Class 吗?
不是的。4 和 5.07 只是类 Int
和 Double
的实例。在 Scala 中,它们的行为方式与对象相同,但在幕后,4 和 5.07 实际上并不是对象。为了理解这个,你必须了解标准 Scala 类层次结构。
层次结构的顶部是类型 Any
。所有东西都扩展 Any
。 Any
有两个直接子类型:AnyVal
和 AnyRef
。
AnyVal
是所有值类型的超类型。值类型是映射到 JVM 原始类型的类型(例如:Int
->int
,Double
->double
等)。AnyRef
是所有引用类型(“普通”对象)的超类型。
在运行时,所有扩展 AnyRef
的一切在幕后都是对象,所有扩展 AnyVal
的一切实际上并不是对象;它们映射到一个原始类型。
Case Class 只是一种语法糖。Case Class 恰好与普通 Class 相同,只是编译器自动为您添加了一些方法(这使它们适合进行模式匹配,例如)。