首页 > 其他分享 >类(class)和包

类(class)和包

时间:2023-08-13 09:25:59浏览次数:43  
标签:case 特质 Scala 构造 方法 class

第5章 类和包

5.1 简单类和无参方法

在Scala中,类并不声明public;一个源文件中可以包含很多类,并且可以都是public级别

在使用public级别的对类时,直接实例化对象就行了

class Course(val courseName: String,var courseNum: Int) {
        var desc: String = "Scala 编程"
}

在调用无参方法时,()可写可不写

5.2 带getter和setter的属性

定义字段为私有的,则getter和setter方法也是私有的
定义 var 属性,默认会生成getter和 setter方法
定义 val 属性 默认生成getter方法
如果不需要任何getter或setter,可以将字段声明为private[this]

5.3对象私有字段

类的方法只能访问当前对象的字段,而不能访问该类的其他对象的字段

5.4 Bean属性

当你将Scala字段标注为@BeanProperty时,这样的方法会自动生成

import scala.reflect.BeanProperty
class Person{
	@BeanProperty var name: String = _
}

将会生成四个方法:name、name_、getname、setName

5.5 构造函数

构造函数(primary constructor & auxiliary constructor)

主构造器紧跟在类名后边,主构造器中参数会被编译成字段、主构造器会执行类中所有语句。

主构造器中参数如果不带 val 或者 var 相当于private[this]

附属构造器用this 命名,附属构造器必须调用存在的构造器

5.6 嵌套类

在类中嵌套类

实例化内部类时只需:new 外部类名.内部类名

5.7 继承

Scala类的继承层级

image-20200113173604922

5.7.1 继承(extends)

在定义时给出子类需要而超类没有的字段和方法,或重写超类的方法

如果不想类、方法或字段被继承,可声明为final

5.7.2 继承(override )

继承的字段方法必须写override 关键字否则语法错误

重写父类⽅方法(override def)

重写字段(override val , override var)

isInstanceOf方法:用于测试某个对象是否属于某个给定的类

asInstanceOf方法:将引用转换为子类的引用

5.8 案例类(case class)

本质上case class是个语法糖,对你的类构造参数增加了getter访问,还有toString, hashCode, equals 等方法

Case class实现了一个伴生对象,这个伴生对象里定义了apply方法和 unapply 方法

定义简单的case class B,反编译其生成的class

编译器对case类混入了Product特质,编译器对case类增加了copy方法

编译器对case类实现了equals/hashCode/toString等方法

伴生对象中最重要的方法是 unapply 这个方法是在进行构造器模式匹配时的关键。

伴生对象中apply方法则为创建对象提供方便,相当于工厂方法

伴生对象继承了AbstractFunction,允许接收 Tuple 作为参数构造

从case类的设计目的来看,最重要的是提供构造器模式匹配(且构造时的参数,与解构的结果一致),另外case类可看作是数据对象,不可变的数据对象。

case class A(a: Int, b: Int)
     A.tupled
     val t  = (100,100)
     A.tupled(t)

5.9 抽象类(abstract class)

类的一个或者多个方法没有没完整的定义

声明抽象方法不需要加abstract关键字,只需要不写方法体

子类重写父类的抽象方法时不需要加override

父类可以声明抽象字段(没有初始值的字段)

子类重写父类的抽象字段时不需要加override

5.9 抽象

抽象类、字段、方法都是用abstract来标记。

抽象字段、方法必须写在抽象类中,但抽象类中不一定包含抽象方法或字段

5.10 特质(trait)

目的:解决多继承的问题

Trait是字段和行为的集合

Trait 是可以有具体实现的接口(和Java不同)

类可以实现任意数量的特质;类/trait 通过with 关键字一个类可以扩展多个特质
第一混入特质用extends

混入类中

从左到右被实例化(超类->所有特质构造在超类之后,类构造器之前->特质由左到右->有父特质,父特质先构造,父特质只会构造一次)

特质不能有构造器参数,每个特质都有一个无参数的构造器

特质中的字段可以是抽象的也可以是具体的
有具体值就是具体的

特质中的每一个具体字段,使用该特质的类都会获得一个字段与之对应

这些字段不是继承的它们只是简单的被加入到子类中,一个类在JVM中只能有一个超类,因此来自特质的字段不能以相同方式继承,由于这个原因,从特质“继承”来的字段被直接加入到子类中(可以查看字节码文件看到这种关系)。

特质中的抽象字段在具体子类中必须被重写,不需要写override

特质的构造顺序
首先调用超类构造器混入类中
特质构造器在超类构造器之后、类构造器之前执行
每个特质中父特质先被构造
多个特质共有一个父特质,该父特质只构造一次
所有特质构造完毕,子类构造
特质的构造顺序从左向右跟线性化的顺序相反

select关键字

(1) 修饰的trait,class只能在当前文件里面被继承
(2) 用sealed修饰这样做的目的是告诉Scala 编译器在检查模式匹配的时候,让 Scala 知道这些case的所有情况,scala就能够在编译的时候进行检查,看你写的代码是否有没有漏掉什么没case到,减少编程的错误。

扩展类的特质

特质也可以扩展类,这个类将自动成为所有混入该特质的超类

image-20200113204022314

自生类型

当特质扩展类时编译器能够确保所有混入该特质的类都以这个类为超类

自身类型也能做到相同的效果,特质并没有扩展Exception,而是有一个自身类型,在特质的方法中我们可以调用该自身方法的任何方法;自类当然也可以是复合类型

5.11 包

Scala 的包和Java 中的包目的相同,管理大型程序中的名称,java 中有个名称叫做完全限定名,是指包名+类名的组合名称,在类路径中唯一标识一个类,避免重复。

Scala的包支持嵌套,你可以访问上层作用域中的名称

包语句可以包含一个“串”(路径区段)

5.12 引入

让你在使用时可以使用更短的名称而不是原来较长的名称

包引入通过import 关键字,在程序的任意位置引入

import 包名._: 可以引入该包下所有的成员

import 包名.{成员名, 成员名,···} 可以引入该包下指定的成员

每个Scala 程序都隐式的引入

​ import java.lang._

​ import scala._

​ import Predef._

重命名 import java.util.{HashMap => JavaHashMap}

protected修饰的成员只能被子类访问,且对类所属包是不可见的

protected[this]将访问权限定在当前的对象

标签:case,特质,Scala,构造,方法,class
From: https://www.cnblogs.com/simpleness/p/17626130.html

相关文章

  • TestNG注解-方法注解(1,BeforeMethod和AfterMethod 2,BeforeClass和AfterClass 3,BeforeSu
    packagecom.course.testng;importorg.testng.annotations.*;publicclassBasicAnootation{//最基本的注解用来把方法标记为测试的一部分@TestpublicvoidtestCase1(){System.out.println("这是测试用例1");}@Testpublicvoidt......
  • [React Typescript] Generics in Class Component
    interfaceTableProps<T>{rows:T[];renderRow:(row:T)=>ReactNode;}exportclassTable<T>extendsReact.Component<TableProps<T>>{render():ReactNode{return(<table><tbody>......
  • 论文解读(TAT)《 Transferable Adversarial Training: A General Approach to Adapting
    Note:[wechat:Y466551|可加勿骚扰,付费咨询]论文信息论文标题:TransferableAdversarialTraining:AGeneralApproachtoAdaptingDeepClassifiers论文作者:HongLiu,MingshengLong,JianminWang,MichaelI.Jordan论文来源:ICML2019论文地址:download 论文代码:download......
  • 谷粒商城报错:java.lang.IllegalStateException: Failed to load property source from
    遇到这种问题如果检查了配置文件没有出错可以尝试打开target文件,去找配置文件,查看是否为空或者中文乱码,一般情况下删除中文注释就可以,因为这个文件的编码格式是GBK,项目的编码格式是UTF-8,注释乱码,导致编译失败。还有另一种做法就是更改编码。......
  • class和interface的区别
     Class(类):一个class是一个Java类,它可以包含属性(字段)和方法,用来定义对象的状态和行为。class可以被实例化为对象,可以有构造函数、成员方法和成员变量。class可以被继承,即一个类可以派生出另一个类,继承父类的属性和方法。一个Java程序通常以class作为基本单元,可以包含main方法......
  • 解决ValueError: Tokenizer class LLaMATokenizer does not exist or is not currentl
    LLaMA大模型是元宇宙平台公司(Meta)研发的大语言模型。问题:loadLLaMA7b的weights的时候报错:ValueError:TokenizerclassLLaMATokenizerdoesnotexistorisnotcurrentlyimported.出现原因:新版transformers里面llama的tokenizer命名为LlamaTokenizer但是旧的模型里面的tokeni......
  • k8s--kubernetes--argo----使用动态存储PVC---基于nfs 的storageclass
    PVC简介Docker中有volumes的概念,在Docker中,volume是对物理节点服务器node路径目录的一种映射,也就是我们可以把服务器的一个目录挂载给镜像使用。同样的,k8s创建的pod也可以挂载volume,而且不仅仅支持pod所在的服务器node的目录映射,也可以挂载其他网络存储的作为目录挂载。k8s支......
  • Kotlin中的Data Class
    DataClassKotlin中的DataClass主要用于封装和持有数据,作用类似Java中的POJO对象。dataclassUser(nickname:String,sex:Int,age:Int)在class之前加上data关键字即可声明一个DataClass。Kotlin中编译器会自动为DataClass实现equals()方法hashcode()方法toStr......
  • 你可能不需要 classnames或者clsx
    classnames是一个npm用来连接多个类名的工具包,可以加入逻辑判断从而生成自己需要的类名。例如:classNames('foo','bar');//=>'foobar'classNames('foo',{bar:true});//=>'foobar'classNames({'foo-bar':true});//=>&......
  • Sqoop 连接mysql 错误 java.lang.NoClassDefFoundError(已解决)
    错误信息Exceptioninthread"main"java.lang.NoClassDefFoundError:org/apache/commons/lang/StringUtilsatorg.apache.sqoop.manager.MySQLManager.initOptionDefaults(MySQLManager.java:73)atorg.apache.sqoop.manager.SqlManager.<init......