今天在学习Scala时,突然想用Idea来创建一个学习类(cmd撸代码太痛苦),直接创建了一个class:
class Test {
def main(args: Array[String]) {
print("Hello World!")
}
}
当我要运行这个main函数时,缺无法执行,当时就郁闷了,再次查看新建时,才知道,Scala class的分类:
那这三中类型:class,Object,Trait有什么区别嘛?
class
在scala中,类名可以和对象名为同一个名字,该对象称为该类的伴生对象,类和伴生对象可以相互访问他们的私有属性,但是他们必须在同一个源文件内。类只会被编译,不能直接被执行,类的申明和主构造器在一起被申明,在一个类中,主构造器只有一个所有必须在内部申明主构造器或者是其他申明主构造器的辅构造器,主构造器会执行类定义中的所有语句。scala对每个字段都会提供getter和setter方法,同时也可以显示的申明,但是针对val类型,只提供getter方法,默认情况下,字段为公有类型,可以在setter方法中增加限制条件来限定变量的变化范围,在scala中方法可以访问改类所有对象的私有字段
object
在scala中没有静态方法和静态字段,所以在scala中可以用object来实现这些功能,直接用对象名调用的方法都是采用这种实现方式,例如Array.toString。对象的构造器在第一次使用的时候会被调用,如果一个对象从未被使用,那么他的构造器也不会被执行;对象本质上拥有类(scala中)的所有特性,除此之外,object还可以一扩展类以及一个或者多个特质:例如,
abstract class ClassName(val parameter){}
object Test extends ClassName(val parameter){}
注意:object不能提供构造器参数,也就是说object必须是无参的
trait
在java中可以通过interface实现多重继承,在Scala中可以通过特征(trait)实现多重继承,不过与java不同的是,它可以定义自己的属性和实现方法体,在没有自己的实现方法体时可以认为它时java interface是等价的,在Scala中也是一般只能继承一个父类,可以通过多个with进行多重继承。
trait TraitA{}
trait TraitB{}
trait TraitC{}
object Test1 extends TraitA with TraitB with TraitC{}
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
}
}
2.scala没有静态的修饰符,但object下的成员都是静态的 ,若有同名的class,这其作为它的伴生类。在object中一般可以为伴生类做一些初始化等操作,如我们常常使用的val array=Array(1,2,3) (ps:其使用了apply方法)
object Dog{
private var age=0
def Age={
age+=1
age
}
}
class Dog{
var age1=Dog.age //Dog.age是object Dog的私有字段。这不禁让我回想起了C++的友元类
}
3.Apply的使用
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()
}
}