码迷,mamicode.com
首页 > 其他好文 > 详细

浅谈Scala对象构造过程

时间:2015-05-26 16:10:44      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:scala   java   

我们通过一个例子来体会scala对象的构造过程
首先创建一个车站类:
class Station {
    val size = 100
    val spots = new Array[String](size)
}


通过size来模拟停车位数,通过字符串数组模拟具体的停车位。
在创建一个停车场类,它是车站的子类
class Park extends Station {
    override val size = 20
}


停车场没有车站那么多车位,只拥有20个,因此在Park中重写了Station的size成员变量。在Park中也自然继承了station中的spots成员
现在我们执行以下代码:
object Client extends App{
    val park = new Park
    println(park.spots.size)
}


输出结果为0
这是为什么呢?
这要从构建对象的过程说起。当创建一个Park对象的时候,会首先创建Park的父类Station对象,在Station对象初始化的时候调用了子类的getSize方法,而子类此时还没有初始化,于是得到了0.
具体步骤如下:
1、调用子类Park构造方法。在调用子类构造方法时首先调用了父类Station的构造方法。
2、Station的构造方法中初始化了size = 100。
3、Station构造方法初始化spots并调用getSize方法获取size。
4、getSize方法被子类Park重写,因此调用Park的getSize方法。
5、Park的getSize方法获取子类size。
6、此时Park对象还没有初始化,因此size = 0。
7、spots被设置为长度为0的数组。


上述两个类用java等效编写的话如下:
public class Station {
	int size;
	String[] spots;
	public Station(){
		size = 100;
		spots = new String[getSize()];
	}
	int getSize(){
		return size;
	}
}
public class Park extends Station {
	int size;
	public Park(){
		size = 20;
	}
	@Override
	int getSize() {
		return size;
	}
}




在scala中想要解决上述问题的方法有以下两种:
1、在父类的成员变量前加上lazy修饰符。这样的话这些变量就会等子类初始化之后再初始化。代码如下:
class Station {
    val size = 100
    lazy val spots = new Array[String](size)
}


2、在子类的构造方法中加入参数size并设置默认值,这样在构造父类的时候size的值就已经初始化了。代码如下:
class Park(override val size:Int = 20) extends Station {
}


3、在子类中使用提前初始化预发,代码如下:
class Park extends {override val size = 20} with Station {
}



上述方式虽然能够解决问题,但是代码并不是非常美观,因此在实际编码时还是要尽量注意在构造方法中不要依赖val成员变量的值。

浅谈Scala对象构造过程

标签:scala   java   

原文地址:http://blog.csdn.net/u010256841/article/details/46008201

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!