主构造器和辅助构造器|学习笔记

简介: 快速学习主构造器和辅助构造器。

开发者学堂课程【Scala 核心编程-基础主构造器和辅助构造器】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/609/detail/8949


主构造器和辅助构造器

 

内容简介

一、构造器

二、Scala 构造器注意事项和细节

 

一、构造器

1Scala 构造器的介绍

(1)和 Java 一样,Scala 构造对象也需要调用构造方法,并且可以有任意多个构造方法;换句话说,Scala 构造器也可以重载;

(2)Scala 类的构造器包括:主构造器和辅助构造器

2Scala 构造器的基本语法

class 类名(形参列表){//主构造器,并且只有一个(跟 Java 不一样,在 Java 中类名后面是不可以带形参的)

//类体

def this(形参列表){//辅助构造器

}

def this(形参列表){//辅助构造器可以有多个...

}

(1)区别不同的辅助构造器

辅助构造器函数的名称 this,可以有多个,编译器通过不同参数来区分,参数可以是个数不一样,也可以是类型不一样,比如第一个辅助构造器只有一个参数,第二个辅助构建器有两个参数;当第一个构造器的类型是 int,第二个构造器的类型是 string,这样也可以区分开,这点跟 Java 是相同的。

3、Scala 构造器的快速入门

创建 Person 对象的同时初始化对象的 age 属性值和 name 属性值,案例演示。

操作演示:

先新建一个包,并设置名称,再新建一个文件;

代码设置:

package com. atguigu.chapter06.constructor

object ConDemo01 {

def main(args: Array[string]): unit = {

val p1 =new Person( "jack",20)

print Ln(p1)l

}

//构造器的快速入门

//创建 Person 对象的同时初始化对象的 age 属性值和 name 属性值

class Person(in Name : string, in Age : Int){

var name: string = in Name

var age: Int = in Age

/代码执行结果:

com.atguigu.chapter06.constructor.Person@4ec6a292这是类的信息/

/重写了 tostring,便于输出对象的信息

override def tostring: string = {

"name=” +this.name + "\t age" + this .age

执行结果:

Name=Jack age20

 

二、Scala 构造器注意事项和细节

1Scala 构造器作用是完成对新对象的初始化,构造器没有返回值;可以从案例中发现是没有返回值的;

2、主构造器的声明直接放置于类名之后[反编译];比如代码 in Name : string, in Age : Int 看起来比较奇怪,构造器本就是方法,但此代码看着不伦不类的,其实在通过反编译之后,后面整体代码会放在构造器里面去,所以通过反编译是可以看到本质的。

3、主构造器会执行类定义中的所有语句,这里可以体会到 scala 的函数式编程;和面向对象编程融合在一起,即:构造器也是方法(函数),传递参数和使用方法和前面的函数部分内容没有区别【案例演示+反编译】

详解:

可以在代码中直接输入一句话,这种做法在 Java 里面是不可能实现的,并且可以直接处理变量

添加后的代码如下:

class Person(in Name: string, in Age : Int) {

var name: string = in Name

var age: Int = in Age

age+= 10

print ln( "~~~~~~~~~~")

//重写了 tostring,便于输出对象的信息

override def tostring: string = {

"name=" + this.name + "lt age" + this. Age

}

print ln( "ok ~vmo~~")print ln( "age=" + age)

}

执行结果:

~~~~~~~~~~

Ok~~~~~

age=30

name=Jack   age30

可以看到是按照顺序执行的,整个输出之后,代码 val p1 =new Person( "jack",20)便会导致输入,在调用 p1,然后输出 tostring。方法里面是不会执行的,可以看看是如何做的,打开反编译器,本质的东西一目了然,在构造器中,能看到所有编辑的代码被整体包装到一个构造器中。

可以理解成主构造器是所编辑的代码除去函数部分,都会被执行一遍。

4、如果主构造器无参数,小括号可省略,构建对象时调用的构造方法的小括号也可以省略。

详解:

把代码写出 val a=new A、val a2=new A()和 class A()其中一个都是可以的。

5、辅助构造器名称为 this(这个和 Java 是不一样的),多个辅助构造器通过不

同参数列表进行区分,在底层就是构造器重载。【案例演示+反编译】

(1)代码设置:

package com.atguigu.chapter06.constructor

object ConDemoo1 {

def main (args:Array[String]):unit={

//下面这句话就会调用 def this (name : string)

val p2 = new Person("tom")

print ln(p2)

}

}

//构造器的快速入门

//创建 Person 对象的同时初始化对象的 age 属性值和 name 属性值

class Person( in Name: string, in Age : Int) {

var name: string = in Name

var age: Int = in Age

age +=10

print ln("~~~~~~~~~~")

//重写了 tostring,便于输出对象的信息 override def tostring: string = {

"name=” + this.name + "\t age"+ this. Age

print ln("ok ~~~~~~")

print ln( "age=" + age)

def this(name :string){//只初始化年龄

//辅助构造器,必须在第一行显式调用主构造器

this( "jack",10)

this.name = name

执行结果:

~~~~~~~~~~

Ok~~~~~

age=20

name=tom   age20

运行流程:首先是上传了姓名,其次调用了主构造器,代码 this( "jack",10)相当于是执行了 var 和 print ln 部分,做完主构造器的部分之后,又重新赋值了 name 部分,name 最终变成 Tom;如果没有这句话 this( "jack",10),会被报语法错误。辅助构造器,必须在第一行显式调用主构造器

(2)Scala 设计者为什么要调用主构造器?

因为需要实现在调用主构造器时,需要调用主构造器的父类构造器,可以回忆在 Java 中是否存在这样的情况?在写Java 时,会有一个默认调用父类的程序,要是没有便会被报错。

(3)为什么要调用 this?

代码设置:

package com. atguigu.chapter06.constructor

object conDemo02 {

def main(args: Array [string]): unit ={//转述

val a = new AA()//构建了 A 的实例

)}

class BB{

print ln( "b~~~")}

class AA()extends BB(){

def this(name : string) {

this //调用 A 的主构造器

print ln( "A this( name : String)")

}

执行结果:

b~~~

在构建 AA 实例时,调用的是主构造器,调用主构造器又继承了 BB,此时走的代码是 print ln(“b~~~”),也会顺带调用 AA 父类的主构造器。

(4)在实现 AA 时,代码 val a = new AA()括号中什么都不写,会先走BB的主构造器,如果没有 this 辅助构造器,逻辑便讲不通,这样会导致跟父类的关系断掉,所以要先去调用主构造器的根本原因,是为了实现子类跟父类的继承关系,在 Java 中,要去实现子类,默认的父类构造器也会被调用。

(5)接下来讲代码中 val a = new AA()的括号里添加上“Jack”,变成 val a = new AA(“Jack”),再执行代码看结果;

代码如下:

package com. atguigu.chapter06.constructor

object conDemo02 {

def main(args: Array [string]): unit ={

val a = new AA(“jack”)

}

class BB(){

print ln( "b~~~")

class AA() extends BB() {

print ln( "AA()")

def this( name : string) {this

print ln( "A this( name : String)")

}

执行结果:

b~~~

AA()

A this (name : string)

执行顺序是会先去执行 AA 的主构造器,在执行 AA 的主构造器时,会优先执行 BB 里面的“b~~~”构造器,仍然是延用了 Java 机制。输出的顺序是,先是 b~~~父类,然后是AA()主构造器,再是 A this (name : string)辅助构造器

6)如果没有 this,辅助构造器不会去调用主构造器,代码中的联系便会断掉。在 Scala 中,对语言做了简化,不允许辅助构造器直接调用父类构造器,比如在代码中加入 super(),语法直接报错,因为在 Java 中,super()是调用父类构造器的意思,如果后面有参数,括号中决定调用父类中的哪个构造器所以在 Scala 中没有 super()

7)加强对辅助构造器的理解

代码如下:

package com. atguigu.chapter06.constructor

object conDemo03 {

def main(args: Array[string]):unit ={

val p1 = new Person2()

}

//定义了一个 person 类

//person 一共有4个构造器

class Person2() {

var name: String =-

var age: Int =-//这是两个属性

def this(name : string){

//辅助构造器无论是直接或间接,最终都一定要调用主构造器,执行主构造器的逻辑

//而且需要放在辅助构造器的第一行{这点和 java 一样,java 中一个构造器要调用同类的其它构造器,也需要放在第一行}

this()//直接调用主构造器(为了给父类留下入口)

this.name = name

}

def this(name : string, age : Int){

this(//直接调用主构造器

this.name = name

this. age = age

}

def this(age : Int) {

this("匿名")//简介调用主构造器,因为 def this(name : string)中调用了主构造器!

this. age = age

}

def show Info(): Unit = {

print Ln( "person信息如下:")

print ln( "name=” + this.name)

print ln( "age=" + this. age)

}

执行结果:

Process finished with exit code 0

再看看是否有四个 person,打开编译器查看,是有四个 person 的。

8)在 Java 中,要调用同类构造器的代码设置如下:

package com. atguigu.chapter06.constructor;

public class JavaDemo01 {

public static void main( string[ ] args){

}

}

//构造器

class AAA {

public AAA(){

//这里调用 AAA(String name)

this( name: "aaa");//必须放在第一行,在第一行前面会有一个默认 super(),但是两者不能同时存在

system. out. print ln( "AAA()");

}

//构造器

public AAA(String name){

super();

}

相关文章
C# 创建已实例化类的副本类
C# 创建已实例化类的副本类
|
编译器 C++
46 C++ - 非自动继承的函数
46 C++ - 非自动继承的函数
38 0
|
6月前
|
前端开发 算法 JavaScript
检查是否是类的对象实例
检查是否是类的对象实例
47 0
|
缓存 IDE API
C#反射与特性(五):主类型成员操作
C#反射与特性(五):主类型成员操作
387 0
C#反射与特性(五):主类型成员操作
第五周学习java 继承 在子类父类中有相同参数,子类继承分类后如何进行调用,判断创建的对象属性哪个类
第五周学习java 继承 在子类父类中有相同参数,子类继承分类后如何进行调用,判断创建的对象属性哪个类
第五周学习java 继承 在子类父类中有相同参数,子类继承分类后如何进行调用,判断创建的对象属性哪个类
|
设计模式
单子设计模式 (对创建初始对象为静态,构造函数私有,返回值为对象的创建函数,private应用)
单子设计模式 (对创建初始对象为静态,构造函数私有,返回值为对象的创建函数,private应用)
单子设计模式 (对创建初始对象为静态,构造函数私有,返回值为对象的创建函数,private应用)
|
Python
5 类的创建及使用
5 类的创建及使用
124 0
|
Java 编译器 Scala
主构造器和辅助构造器的细节|学习笔记
快速学习主构造器和辅助构造器的细节。
130 0
类初始列表和类对象作为类成员
类初始列表和类对象作为类成员
类初始列表和类对象作为类成员
【错误记录】反射时调用方法及成员报错 ( 执行反射方法 | 设置反射的成员变量 | 设置方法/成员可见性 )
【错误记录】反射时调用方法及成员报错 ( 执行反射方法 | 设置反射的成员变量 | 设置方法/成员可见性 )
179 0
下一篇
无影云桌面