浅谈Scala对象构造过程

我们通过一个例子来体会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成员变量的值。

时间: 2025-01-12 01:19:10

浅谈Scala对象构造过程的相关文章

浅谈 js 对象 toJSON 方法

前些天在<浅谈 JSON.stringify 方法>说了他的正确使用姿势,今天来说下 toJSON 方法吧.其实我觉得这货跟 toString 一个道理,他是给 stringify 方法字符串化的时候调用的.看下 MDN 官方文档吧<toJSON behavior>.非常简单,但是要注意的是他和 stringify 方法第二个参数稍微有点不同.因为 stringify 第二个参数是回调函数时,只是对当前 key 对应的值进行修改.而 toJSON 则是对当前对象进行修改.例如: v

Java内存结构、类的初始化、及对象构造过程

概述 网上关于该题目的文章已经很多,我觉得把它们几个关联起来讲可能更好理解一下.与其它语言一样,它在执行我们写的程序前要先分配内存空间,以便于存放代码.数据:程序的执行过程其实依然是代码的执行及数据的读写过程:除了在执行我们写的显式的可见代码外,Jvm还会自动帮我们帮一些事,包括类的加载.初始化.GC等,这些也不特殊.以下分别来说下这些概念. Java内存结构.类的初始化.及对象构造过程

Java之对象构造过程

先来运行一段代码 class A { public A() { init(); } public void init() { } public static void main(String[] args) { B b = new B(); System.out.println("终于i的值为:" + b.i + ",j的值为:" + b.j); } } class B extends A { int i; int j = 999; public void init

浅谈html基本构造

html(HyperText Markup Language)即超文本标记语言,标准通用标记语言下的一个应用. "超文本"就是指页面内可以包含图片.链接,甚至音乐.程序等非文字元素.html又为htm,由于历史问题出现的三个字母,本质上是一样的 <!DOCTYPE html><html> <head> <meta  charset="utf-8"> <title>浅谈HTML</title> &

浅谈 JavaScript new 执行过程及function原理

前言 最近在学习JavaScript语言精粹,感觉写得相当不错.所以这里也算是总结一下.一个方法使用new的方式创建到底是怎样的过程,一个function的声明内部又是怎样执行的呢 另外学的过程中,不断参照ECMAScript的API,也能理解不少东西.ECMAScript Api:下载地址 W3C参考地址:http://www.w3school.com.cn/js/pro_js_functions.asp 正文 1.首先,看个例子,看下面例子的输出. 结果通过new运算符执行结果与直接执行函数

浅谈js对象之数据属性、访问器属性、Object.defineProperty方法

一.对象 这个不用多说,常见的几种创建对象的方法有: 1.通过构造函数创建对象,如下所示: function Person(){ } var person = new Person(); 2.通过Object创建简单对象,例如: var obj = new Object(); 3.通过字面量创建对象. var obj = {}; 常用的一般是第一种和第三种方法. 二.属性类型 javascript中有两种属性:数据属性和访问器属性,确切的说这两种特性是用来描述对象属性的各种特征,比如说这个对象属

浅谈Js对象的概念、创建、调用、删除、修改!

一.我们经常困惑,对象究竟是什么,其实这是一种思维,一种意识上的东西,就像我们都说    世界是有物质组成的道理一样,理解了下面的几句话!对象也不是那么抽象!    1.javascript中的所有事物都是对象,字符串.数值.数组.函数!    而且js还允许自定义对象!    2.对象就只是带有属性和方法的特殊数据类型    3.属性是与对象相关的值,方法是能够在对象上执行的动作! 其实在这里的时候我们应该就有一个疑问要解决了,我们说函数是一个对象,为什么?    很简单,js中所有的事物都是

【一个小功能】从js判断ie版本,浅谈navigator对象的appName属性

判断IE版本主要的是获取两个属性,a.当前浏览器名称,b.当前浏览器版本,为此不得不了解navigator对象. 先贴代码 1 window.onload = function() { 2 var browser_name = navigator.appName, //获取当前浏览器的名称 3 browser_version = navigator.appVersion, //获取当前浏览器的平台和版本信息 4 version_arr = browser_version.split(";&quo

浅谈java对象的equals方法

作为一个被问的很多的一个面试题:java中==和equals有什么区别? 网上普遍的回答都是:==比较的是内存地址,equals比较的是值. 其实这种回答是很不标准的,稍微标准一点的回答应该JDK自带的一些类对equals的实现各不同,例如 Object对象的equals的定义是这样的: public boolean equals(Object obj) { return (this == obj); } 所以在Object中==和equals是没有任何区别的. 但在String中,重写的equ