scala中object和class的区别
object
在scala中没有静态方法和静态字段,所以在scala中可以用object来实现这些功能,直接用对象名调用的方法都是采用这种实现方式,例如Array.toString。对象的构造器在第一次使用的时候会被调用,如果一个对象从未被使用,那么他的构造器也不会被执行;对象本质上拥有类(scala中)的所有特性,除此之外,object还可以一扩展类以及一个或者多个特质:例如,
abstract?class ClassName(val parameter){}
object Test extends ClassName(val parameter){}
trait TraitA{}
trait TraitB{}
trait TraitC{}
object Test1 extends TraitA with TraitB with TraitC{}
注意:object不能提供构造器参数,也就是说object必须是无参的
我们通常会定义和使用object的apply方法,有如下情形,apply方法就会被调用,Object(参数1 ,参数2 ,……)这样是隐含的调用apply方法,当然也可以显示的调用,如下Array("Mary","tong"),当然也可以这样来写Array.apply("Mary","tong"),一般我们提倡隐式的写法。
所有的main方法都必须在object中被调用,来提供程序的主入口,十分简单,不举例说明,处理main方法以外,scala中还提供了扩展App特质,然后将程序代码放入都早起方法体内,如
object?Hello?extends?App{
???println("Hello?World !!!")
}
这样的代码可以直接执行,输出
如果需要命令行参数,可以直接调用args属性来得到,例如
def main(args: Array[String]) { if (args.length > 0 ) println("Hello " + args(0)) else println("Hello World") } scala中并没有枚举类型,但是,标准类库中提供了一个枚举类型的接口,在object下面,可以扩展出枚举类型(Enumeration), 具体示例如下:
object EnumerationDemo extends Enumeration{ val red, green, blue, pink = Value val black = Value // 上面一条语句是简写 val white = Value val gray = Value val yellow = Value(12, "huang") //可以随意指定id和名称,但是避免重复 val purple = Value("zi") //id为13 val orange = Value(20) }上面的代码为实现枚举类型的具体代码,如果不指定id和name,系统默认是id从0开始,name就是变量的名称,可以指定其中的
任何一个或者是两个全部指定,已经指定的就按指定的初始化,并且后面的依次递增。
枚举的引用
可以直接objectName.red这样来进行引用,也可以将import objectName._来进行导入引用,还可以给枚举类型增加一个类型别名,
具体如下:
object EnumerationDemo extends Enumeration{ type EnumerationDemo = Value val red, green, blue, pink = Value val black = Value val white = Value val gray = Value val yellow = Value(12, "huang") val purple = Value("zi") val orange = Value(20) }现在枚举类型变成了EnumerationDemo.EnumerationDemo 这种用法只有在使用import语句的时候才显得有意义。
package enumeration import EnumerationDemo._ /** * Created by tongtong on 2015/9/8. * */ class EnumDemo { def transportation(color:Enumeration): Unit ={ if (color == red) "Stop" else if (color == green) "go" else if (color == yellow) "wait" } }枚举类型也可以通过for循环将所有元素输出,同时可以通过Enumeration(Int)和Enumeration.withName("")来进行定位操作
class
在scala中,类名可以和对象名为同一个名字,该对象称为该类的伴生对象,类和伴生对象可以相互访问他们的私有属性,但是 他们必须在同一个源文件内。类只会被编译,不能直接被执行,类的申明和主构造器在一起被申明,在一个类中,主构造器只有一个, 所有必须在内部申明主构造器或者是其他申明主构造器的辅构造器,主构造器会执行类定义中的所有语句。scala对每个字段都会提供 getter和setter方法,同时也可以显示的申明,但是针对val类型,只提供getter方法,默认情况下,字段为公有类型,可以在setter 方法中增加限制条件来限定变量的变化范围,在scala中方法可以访问改类所有对象的私有字段
Scala之旅-class和object详解
1.class
scala的类和C#中的类有点不一样,诸如: 声明一个未用priavate修饰的字段 var age,scala编译器会字段帮我们生产一个私有字段和2个公有方法get和set ,这和C#的简易属性类似;若使用了private修饰,则它的方法也将会是私有的。这就是所谓的统一访问原则。
细节的东西太多,还是上代码在注释里面细讲吧
//类默认是public级别的??
class?Person{????var?age=18??//字段必须得初始化()??
??def?Age=age?//这个是方法,没有参数可以省略()????def?incremen(){this.age+=1}??
}????
??class?Student{??
??var?age=20?????//底层编译器会自动为私有的age添加get和set的公有方法,可以理解为伪public类型????private[this]?var?gender="male"?//private[this]?只有该类的this可以使用??
??private?var?name="clow"?//声明了private,底层编译器会自动为私有的name添加get和set的私有方法????//但是可以自己定义属性方法??
??def?getName=this.name????def?setName(value:String){this.name=value}??
}????
//构造器的使用??class?Teacher?{??
??var?age:?Int?=?_????var?name:?String?=?_??//可以预留??
????//重载的构造器和C#里面的public?Teacher(){}类似??
??def?this(age:?Int,?name:?String){??????this()?//必须得调用一次主构造器??
????this.age=age??????this.name=name??
??}??}??
//1.主构造器在类名后,参数会被声明字段,若参数没有使用var或者val声明,则会被声明称私有字段??
//2.实例化类的时候,类中的语句会被执行:println("person")??class?Person(name:String,var?age:Int)?{??
??println("person")????
??def?show():?Unit?=?{??????println("show.."+name)??
??}????
??var?gender:String=_????
??//次构造器必须调用主构造器,参数不能使用var????def?this(name:String,age:Int,?gender:String){??
????this(name,age)??????this.gender=gender??
??}??}??
object?Dog{??
??private?var?age=0????def?Age={??
????age+=1??????age??
??}??}??
??class?Dog{??
??var?age1=Dog.age?//Dog.age是object?Dog的私有字段。这不禁让我回想起了C++的友元类??}??
class?ApplyTest{??
????val?name="clow";??
??def?apply()??{??????println("class?ApplyTest--apply()...");??
??}????
}????
//object下的成员默认都是静态的??object?ApplyTest{??
??def?apply()?=?{??????println("object?ApplyTest--apply()...");??
????new?ApplyTest()????}??
}????
??object?Basic4?{??
????def?main(args:?Array[String])?{??
????//类名()->调用了对应object下的apply方法??????var?a1=ApplyTest()??
????println(a1.name)??????//对象名()->调用了对应class的apply方法??
????a1()?//输出:class?ApplyTest--apply()...????}??
}??
Apply怎么用它来实现单例模式
class?ApplyTest?private{??//添加private隐藏构造器??
??def?sayHello(){??????println("hello?jop")??
??}??}??
??object?ApplyTest{??
??var?instant:ApplyTest=null????def?apply()?={??
????if(instant==null)?instant=new?ApplyTest??????instant??
????}??
}????
object?ApplyDemo?{????def?main(args:Array[String]){??
??????val?t=ApplyTest()????????t.sayHello()??
??}??}
上一篇: zipalign的使用
推荐阅读
-
解析iptables中SNAT和MASQUERADE之间的区别
-
C#中Property和Attribute的区别实例详解
-
Android 中raw和assets文件夹的区别
-
SQL左右连接中的on and和on where的区别
-
Javascript中类式继承和原型式继承的实现方法和区别之处
-
详解HTML5中div和section以及article的区别
-
老生常谈jquery中detach()和remove()的区别
-
Android MotionEvent中getX()和getRawX()的区别实例详解
-
详谈js中数组(array)和对象(object)的区别
-
关于Sequelize连接查询时inlude中model和association的区别详解