我将在互联网上浏览一些scala教程,并注意到在一些示例中,在示例的开头声明了一个对象。
scala中的class和object有什么区别?
DR
- EDCOX1 1定义了一个类,就像Java或C++一样。
- object O创建一个单例对象O作为某个匿名类的实例;它可以用来保存与某个类的实例无关的静态成员。
- object O extends T使对象O成为trait T的实例;然后您可以在任何地方传递O,预计会有T。
- 如果存在class C,那么object C是C类的伴生对象;注意伴生对象不是C的自动实例。
另请参见scala文档了解对象和类。
用作静态成员的宿主
通常,您需要一个object来保存方法和值/变量,这些方法和值/变量不需要先实例化某个类的实例就可以使用。这与Java中EDCOX1、14个成员的使用密切相关。
然后可以使用A.twice(2)调用上述方法。
如果twice是某一类A的成员,那么您需要先举个例子:
1 2 3 4 5 6
| class A () {
def twice (i : Int ): Int = 2 * i
}
val a = new A ()
a. twice(2) |
您可以看到这是如何冗余的,因为twice不需要任何特定于实例的数据。
用作特殊命名实例
您也可以将object本身用作类或特性的一些特殊实例。当您这样做时,您的对象需要扩展一些trait,以便成为它的子类的一个实例。
请考虑以下代码:
此声明首先声明一个匿名(不可访问)类,它扩展了B和C,并实例化了这个名为A的类的单个实例。
这意味着A可以传递给预期对象类型为B或C或B with C的函数。
object的附加功能
scala中还存在一些对象的特殊特性。我建议阅读官方文件。
- def apply(...)启用A(...)的常用方法无名称语法。
- def unapply(...)允许创建自定义模式匹配提取器
- 如果与同名类一起使用,则在解析隐式参数时,对象将承担特殊角色。
- 它还将定义类A,并将对象A中的所有方法创建为类A上的静态方法(用于与Java接口)。(对scala 2.7中已在scala 2.8中修复的bug进行模块化)
- @肯布鲁姆真的吗?我尝试过但没有成功:scala>commerce res8:commerce.type=commerce$@6eb2756 scala>classof[commerce]:23:error:not found:type commerce classof[commerce]^scala>new commerce:23:error:not found:type commerce new commerce^
- HeNYY:Scala将无法识别EDCOX1 0类,但是JVM和Java语言会。(这就是您可以执行object Foo{ def main(args:Seq[String]) }并期望程序运行的方法。)
- 我认为Ziggystar的答案更精确,类是匿名类,除非明确定义了一个名为Commerce的相应类(那么Commerce对象将是Commerce类的伴生对象)。
- 另一个不完全正确的简单解释。至少在scala 2.9.1中,我记得在某些情况下,我很难将对象作为接口的实例传递。
- @我敢打赌,我的回答中没有足够的微妙之处。但这些对大多数人来说可能并不重要。我从来没有把一个物体当作某种特性的实例来传递的问题,这并不意味着它们不存在,但它应该起作用。
class是一个定义,一个描述。它根据方法和其他类型的组合来定义类型。
object是一个单例——类的一个实例,它保证是唯一的。对于代码中的每个object,都会创建一个匿名类,该类继承自您声明要实现的object类。从scala源代码中看不到这个类——尽管您可以通过反射来获得它。
object和class之间存在着关系。如果一个对象共享同一个名称,那么它就被称为类的伴生对象。当这种情况发生时,每种方法都可以访问另一种方法中的private可见性。但是,这些方法不会自动导入。您要么显式地导入它们,要么在它们前面加上类/对象名称。
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class X {
// class X can see private members of object X
// Prefix to call
def m (x : Int ) = X. f(x )
// Import and use
import X. _
def n (x : Int ) = f (x )
private def o = 2
}
object X {
private def f (x : Int ) = x * x
// object X can see private members of class X
def g (x : X ) = {
import x. _
x. o * o // fully specified and imported
}
} |
- 很抱歉打扰您,但是您可以举出一个例子来说明如何将方法导入到伴生对象中,或者如何给它们加前缀吗?
- 伊斯库尔完成了。对不起,这个愚蠢的例子,我想不出一个好的和短的。
- 如果我想在对象中使用类方法呢?可能吗?如果我有一个类的方法,并且我想在对象中使用它,那么如果您尝试导入该类,您将无法导入。最后,您必须创建一个构造函数,然后调用该方法。因此,通过生成一个伴生对象,您可以使用import访问对象的方法,但反之亦然。有人能验证一下吗?
- @皮尤什戈亚尔不是真的。假设对象有一个方法def f(x: X) = ???,那么它就可以调用伴生类x的x上的私有方法。
- 这里传递给x的函数是x类的实例吗?如果是,那么最终您将使用对象x调用def f中x类的方法。对吗?
- @Piyushgoyal我在答案中扩展了这个例子来举例说明我的意思。
- @Piyushgoyal指出,进口成员与同伴毫无关系。您可以导入scala中任何值的成员。
- 首先,我要感谢你为解释事情付出了这么多努力。:)我看到了这个例子。所以另一个问题,我理解在defg中使用类的"o"val/def的逻辑。我的问题是,如果我不想传递a的对象,就不能通过在对象中直接执行import a来直接使用o。最后,您将构造一个as x的对象,然后使用它。为了进一步解释,代码对象A import A val random=O*O将无法工作,因为对象A将永远无法识别import A。_
- @比尤什戈亚尔正确。对象x是一个值,"new x"是一个值,但"class x"不是。
一个对象只有一个实例(不能调用new MyObject)。一个类可以有多个实例。
对象与Java中的静态方法和字段具有相同的(和一些附加的)目的。
正如许多人所解释的,object定义了一个单例实例。我认为这里的答案中有一点被遗漏了,那就是object有多种用途。
它可以是class/trait的伴生对象,包含可能被认为是静态方法或方便方法的内容。
它可以像一个模块一样工作,包含相关/附属类型和定义等。
它可以通过扩展class或一个或多个trait来实现接口。
它可以表示不包含数据的sealed trait的情况。在这方面,它通常被认为比没有参数的case class更正确。只有case object实现者的sealed trait的特殊情况或多或少是枚举的scala版本。
它可以作为implicit驱动逻辑的证据。
它引入了单例类型。
这是一个非常强大和一般的结构。对于scala初学者来说,非常令人困惑的是,相同的结构可以有非常不同的用途。而一个object可以同时提供许多不同的用途,这可能会更加令人困惑。
在Scala中定义一个对象就像在Java中定义一个只有静态方法的类。但是,在scala中,对象可以扩展另一个超类,实现接口,并像类的实例一样传递。(这就像类上的静态方法,但更好)。
形式上的区别-
不能为对象提供构造函数参数
对象不是类型-不能使用新运算符创建实例。但它可以有领域、方法、扩展超类和混合特性。
使用上的差异:
- "不能为对象提供构造函数参数"对象具有apply(…)方法,该方法的功能非常类似于构造函数。这让我有点困惑。
object关键字创建一个新的singleton类型,类似于一个只有一个命名实例的类。如果你熟悉Java,在Scala中声明一个对象很像创建一个匿名类的新实例。
斯卡拉没有等价于Java的静态关键字,并且在斯卡拉中经常使用一个对象,您可以在Java中使用具有静态成员的类。
在scala中,没有static概念。所以scala创建了一个singleton对象来为程序执行提供入口点。如果不创建singleton对象,代码将成功编译,但不会生成任何输出。在singleton对象内声明的方法可以全局访问。单例对象可以扩展类和特性。
scala singleton对象示例
1 2 3 4 5 6 7 8 9 10 11 12
| object Singleton {
def main (args :Array [String ]){
SingletonObject. hello() // No need to create object.
}
}
object SingletonObject {
def hello (){
println ("Hello, This is Singleton Object")
}
} |
输出:
1
| Hello, This is Singleton Object |
在scala中,当有一个类与singleton对象同名时,它被称为伴生类,singleton对象被称为伴生对象。
伴生类及其伴生对象都必须在同一源文件中定义。
scala伴生对象示例
1 2 3 4 5 6 7 8 9 10 11
| class ComapanionClass {
def hello (){
println ("Hello, this is Companion Class.")
}
}
object CompanoinObject {
def main (args :Array [String ]){
new ComapanionClass (). hello()
println ("And this is Companion Object.")
}
} |
输出:
1 2
| Hello, this is Companion Class.
And this is Companion Object. |
在scala中,类可以包含:
1。数据成员
2。成员法
三。构造函数块
4。嵌套类
5。高级信息等。
必须初始化类中的所有实例变量。没有默认范围。如果不指定访问范围,则它是公共的。必须存在定义了主方法的对象。它为您的程序提供了起点。在这里,我们创建了一个类的例子。
scala类示例
1 2 3 4 5 6 7 8 9 10
| class Student {
var id :Int = 0; // All fields must be initialized
var name :String = null;
}
object MainObject {
def main (args :Array [String ]){
var s = new Student () // Creating an object
println (s. id+ ""+s. name);
}
} |
对不起,我来的太晚了,但我希望它能帮助你。
对象是一个类,但它已经有一个实例,因此不能调用new ObjectName。另一方面,类只是类型,它可以通过调用new ClassName()作为实例。
Scala类与Java类相同,但Scala不提供类中的任何输入方法,如Java中的main方法。与对象关键字关联的主方法。可以将object关键字视为创建隐式定义的类的singleton对象。
更多信息请查看本文scala编程中的类和对象关键字
如果你来自Java背景,Scala中的类的概念类似于Java,但是Scala中的类不能包含静态成员。
Scala中的对象是单体类型,在对象中使用对象名称调用方法,在Scala对象中是关键字,而Java对象是类的实例。
对象等于Java中的静态类到一些扩展,静态特性意味着静态类在向JVM放置时不需要创建对象,它可以直接由它的类名使用。
类对象:类是描述实体或对象的所有属性的定义。对象是类的一个实例。
- 在Java中,这是真的。在斯卡拉,不是很多,也不是问题所在。