首页 > 其他分享 >Scala 类

Scala 类

时间:2022-11-11 16:31:47浏览次数:44  
标签:String val Scala Member new class name


1  简单类和无参方法

类的定义可以通过class关键字实现,如下:

package unit7

class Dog {
private var leg = 4
def shout(content: String) {
println(content)
}
def currentLeg = leg
}

使用这个类:

val dog = new Dog
dog shout "汪汪汪"
println(dog currentLeg)

尖叫提示:在Scala中,类并不声明为Public,一个Scala源文件可以包含多个类。所有这些类都具有公有可见性。调用无参方法时,可以加(),也可以不加;如果方法定义中不带括号,那么调用时就不能带括号。

2  Getter Setter方法

对于scala类中的每一个属性,编译后,会有一个私有的字段和相应的getter、setter方法生成:

//getter
println(dog leg)
//setter
dog.leg_=(10)
println(dog currentLeg)

当然了,你也可以不使用自动生成的方式,自己定义getter和setter方法

class Dog2 {
private var _leg = 4
def leg = _leg
def leg_=(newLeg: Int) {
_leg = newLeg
}
}

使用之:

val dog2 = new Dog2
dog2.leg_=(10)
println(dog2.leg)

尖叫提示:自己手动创建变量的getter和setter方法需要遵循以下原则:

1) 字段属性名以“_”作为前缀,如:_leg

2)  getter方法定义为:def leg = _leg

3) setter方法定义时,方法名为属性名去掉前缀,并加上后缀,后缀是:“leg_=”,如例子所示

3  对象私有字段

变量:workDetails在封闭包professional中的任何类中可访问。

封闭包:friends的任何类都可以被society包中任何类访问。

变量:secrets只能在实例方法的隐式对象(this)中访问。

package unit7

package society {
package professional {
class Executive {
private[professional] var workDetails = null
private[society] var friends = null
private[this] var secrets = null

def help(another: Executive) {
println(another.workDetails)
// println(another.secrets) 报错:访问不到
}
}
}
}

4  Bean属性

JavaBeans规范定义了Java的属性是像getXXX()和setXXX()的方法。许多Java工具都依赖这个命名习惯。为了Java的互操作性。将Scala字段加@BeanProperty时,这样的方法会自动生成。

1)  创建一个Bean,使用@BeanProperty注解标识某个属性变量

package unit7
import scala.beans.BeanProperty
class Person {
@BeanProperty var name: String = _
}

2)  通过getName、setName访问属性

val person = new Person
person.setName("Nick")
person.getName
println(person.name)

尖叫提示:

Person将会生成四个方法:

--name:String

--name_=(newValue:String): Unit

--getName():String

--setName(newValue:String):Unit

5  构造器

scala中构造分为主构造器和辅助构造器

1)  主构造的参数直接放置于类名之后

定义类:
class ClassConstructor (var name: String, private var price: Double){
def myPrintln = println(name + "," + price)
}
执行:
val classConstructor = new ClassConstructor("《傲慢与偏见》", 20.5)
classConstructor.myPrintln

2)  主构造器会执行类定义中的所有语句

定义类:
class ClassConstructor2(val name: String = "", val price: Double = 0) {
println(name + "," + price)
}
执行:
val classConstructor2 = new ClassConstructor2("aa", 20)
val classConstructor2_2 = new ClassConstructor2()

3)  通过private设置的主构造器的私有属性

参考1)

4)  如果不带val和var的参数至少被一个方法使用,该参数将自动升级为字段,这时,name和price就变成了类的不可变字段,而且这两个字段是对象私有的,这类似于 private[this] val字段的效果。

否则,该参数将不被保存为字段,即实例化该对象时传入的参数值,不会被保留在实例化后的对象之中。

主构造器参数

生成的字段/方法

name: String

对象私有字段。如果没有方法使用name, 则没有该字段

private val/var name: String

私有字段,私有的getter和setter方法

var name: String

私有字段,公有的getter和setter方法

@BeanProperty val/var name: String

私有字段,公有的Scala版和Java版的getter和setter方法

如果想让主构造器变成私有的,可以在()之前加上private,这样用户只能通过辅助构造器来构造对象了

class Person private () {...}

5)  辅助构造器名称为this,通过不同参数进行区分,每一个辅助构造器都必须以主构造器或者已经定义的辅助构造器的调用开始

class Person {
private var name = ""
private var age = 0

def this(name: String) {
this()
this.name = name
}
def this(name: String, age: Int) {
this(name)
this.age = age
}

def description = name + " is " + age + " years old"
}

6  嵌套类

即,在class中,再定义一个class,以此类推。

Java中的内部类从属于外部类。Scala中内部类从属于实例。

1)  创建一个嵌套类,模拟局域网的聊天场景

import scala.collection.mutable.ArrayBuffer
//嵌套类
class Network {
class Member(val name: String) {
val contacts = new ArrayBuffer[Member]
}
private val members = new ArrayBuffer[Member]
def join(name: String) = {
val m = new Member(name)
members += m
m
}
}

2)  使用该嵌套类

//创建两个局域网
val chatter1 = new Network
val chatter2 = new Network

//Fred 和 Wilma加入局域网1
val fred = chatter1.join("Fred")
val wilma = chatter1.join("Wilma")
//Barney加入局域网2
val barney = chatter2.join("Barney")

//Fred将同属于局域网1中的Wilma添加为联系人
fred.contacts += wilma
//fred.contacts += barney //这样做是不行的,Fred和Barney不属于同一个局域网,即,Fred和Barney不是同一个class Member实例化出来的对象

在Scala中,每个实例都有它自己的Member类,就和他们有自己的members字段一样。也就是说,chatter1.Member和chatter2.Member是不同的两个类。也就是所谓的:路径依赖类型,此处需要详细解释之。

如果想让members接受所有实例的Member,一般有两种办法:

1)  将Member作为Network的伴生对象存在

创建类:

import scala.collection.mutable.ArrayBuffer

// 伴生对象
class Network2 {
private val members = new ArrayBuffer[Network2.Member]
def join(name: String) = {
val m = new Network2.Member(name)
members += m
m
}
def description = "该局域网中的联系人:" +
(for (m <- members) yield m.description).mkString(", ")
}

object Network2 {
class Member(val name: String) {
val contacts = new ArrayBuffer[Member]
def description = name + "的联系人:" +
(for (c <- contacts) yield c.name).mkString(" ")
}
}

使用:

val chatter3 = new Network2
val chatter4 = new Network2

//Fred 和 Wilma加入局域网1
val fred2 = chatter3.join("Fred")
val wilma2 = chatter3.join("Wilma")
//Barney加入局域网2
val barney2 = chatter4.join("Barney")
//Fred将同属于局域网3中的Wilma添加为联系人
fred2.contacts += wilma2
//Fred将不同属于局域网3中,属于局域网4中的的Wilma添加为联系人
fred2.contacts += barney2

println(chatter3.description)
println(chatter4.description)

println(fred2.description)
println(wilma2.description)
println(barney2.description)

2)  使用类型投影,注意留意关键符号:“#

创建类:

import scala.collection.mutable.ArrayBuffer

//投影
class Network3 {
class Member(val name: String) {
val contacts = new ArrayBuffer[Network3#Member]
}

private val members = new ArrayBuffer[Member]

def join(name: String) = {
val m = new Member(name)
members += m
m
}
}

使用:

val chatter5 = new Network3
val chatter6 = new Network3

//Fred 和 Wilma加入局域网1
val fred3 = chatter5.join("Fred")
val wilma3 = chatter5.join("Wilma")
//Barney加入局域网2
val barney3 = chatter6.join("Barney")
fred3.contacts += wilma3

尖叫提示:与Java一样,在嵌套类中,如果想得到外部类的实例化对象的引用,可以使用“外部类.this”的方式得到。

标签:String,val,Scala,Member,new,class,name
From: https://blog.51cto.com/u_12654321/5845155

相关文章

  • Scala高阶函数
    1 作为参数的函数函数作为一个变量传入到了另一个函数中,那么该作为参数的函数的类型是:function1,即:(参数类型)=>返回类型defplus(x:Int)=3+xvalresult1=Array(1,......
  • Scala注解
    注解就是标签。标签是用来标记某些代码需要特殊处理的。处理的手段可以在代码运行时操作,也可以在编译期操作。1 什么可以被注解1) 可以为类,方法,字段局部变量,参数,表达式,......
  • 【THM】Linux Privilege Escalation(Linux权限提升基础)-学习
    本文相关的TryHackMe实验房间链接:https://tryhackme.com/room/linprivesc通过学习相关知识点:了解Linux权限提升的基础知识,从枚举到利用,了解多种不同的权限提升技术。介......
  • Scalable Evaluation of Multi-Agent Reinforcement Learning with Melting Pot
    提出的问题:现有的对多智能体强化学习的评估工具没有将多智能体强化学习泛化的新情况评估作为主要目标。传统的监督学习和受益于明确的实验环境和存在的评价基准,能够较为......
  • [scala基础]--拆分List操作
    运行环境:Jdk1.7、scala-2.10.4packagestudy/***Document:本类作用---->拆分List*User:yangjf*Date:2016/8/148:57*/objectTestArrays{defmain(args:A......
  • Spark简单介绍,Windows下安装Scala+Hadoop+Spark运行环境,集成到IDEA中
    一、前言近几年大数据是异常的火爆,今天小编以java开发的身份来会会大数据,提高一下自己的层面!大数据技术也是有很多:HadoopSparkFlink小编也只知道这些了,由于Hadoop,......
  • 【scala】getclass的使用
    打印属性名判断是否有该属性......
  • Scala-隐式转换
    隐式转换精度小的类型可以自动转换为精度大的类型,这个转换过程无需开发人员参与,由编译器自动完成,这个转换操作我们称之为隐式转换。如果程序编译出错,编译器会尝试在整个......
  • Scala-模式匹配
    模式匹配简介类似于java中switch当数据满足某一个分支时,执行完毕后,就直接跳出case分支类似于default语言,分支匹配其实就是顺序匹配如果数据没有匹配任何规则......
  • 在IntelliJ IDEA 运行 scala 报错 scala/Function1
    在IntelliJIDEA运行scala报错scala/Function1在IntelliJIDEA中运行scala程序有时候会报错scala/Function1在IntelliJIDEA中运行scala程序有时候会报错scala/Fu......