10类基础

本文最后更新于 2021-08-05 11:42:59

类基础

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
object ObjDemo1 {

def main(args: Array[String]): Unit = {
val user = new User
println(user.age)
println(user.name)
user.age=21
println(user.age)
user.age_$eq(11)
println(user.age)
user.eat()

println(user.getAge())

//给类起别名
type U = User
val u = new U
u.eat()
//打印的名字还是 User
println(u.getClass.getName())


}
}

/**
* 默认是public class
* 在java中 如果是public class 类名必须与文件名相同
* 内部类可以有private ,static
**/
class User{
//默认是私有的变量
//并且默认提供了 getter setter 但是不满足标准的javaBean规范,可以加上@BeanPropertity生成规范的,原来的也不会去掉
//比如 age -> age() ,age_$eq()
//但是age()不能用,age_$eq(xxx)可以用
// @beanGetter 只加get
// @beanSetter 只加set
@BeanProperty
var age =20
@BeanProperty
var name = "king"
//private final 且只有getter
val contry="china"
//private
//但是getter和setter是私有的了
private var sex = "man"

def eat()={
println(s"$name eat")
}
}

class User1{

//当属性为var时,可以使用 _ 占位不赋初值
//必须要手动指定类型
// 数字 默认0
// boolean 默认false
//引用类型 默认null
var name:String = _
var age:Int = _
}


class User3(var name:String,val age:Int,sex:String){
def eat={
println(sex)
}
}
//使用 有参主构造器 定义对象
//定义的参数自动成为成员变量
//如果没有指定 val或var 例如 sex ,则为private final ,如果内部没有使用,则会优化去掉(直接没有该成员变量)


class User4(@BeanProperty var name:String,val age:Int,sex:String){
//辅助构造器,相当于构造器重载
//辅助构造的参数就不是成员变量
def this(){
//第一行必须调用构造器
this("aaa",1,"")
}

def this(c:Int){
//后面的构造器可以调用前面定义辅助构造器的
//前面的构造器不能调用后面的辅助构造器
//this()
this("aa",c,"")
}

def eat={
println(sex)
}
}

导包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
object ObjDemo2 {

def main(args: Array[String]): Unit = {
//在任何地方导入包
//局部使用
import java.util.HashMap
val stringToString = new HashMap[String,String]()


//使用包对象
foo
}
}


//在priv.king.obj 下有一个类A
class A
package aa{
//在priv.king.obj.aa 下有一个类A
class A
}


/*
scala也有包的概念,命名于使用规则于java一样
1.包的声明
package priv.king.obj
2.包语句
在scala中, .scala文件一般会有多个类,所有的类都默认在一个包中

3.包使用
在文件最顶层导入
import java.util.HashMap

在代码任何需要的地方导入
比如在方法内导入


通配符导入
//导入util下所有包
import java.util._
//导入多个
import java.util.{HashMap,TreeMap}
//除了HashMap其他都导入

//导包的时候起别名
import java.util.{HashMap=>HM}

//除了HashMap其他都导入
//先给HashMap起别名,在导入所有
import java.util.{HashMap=>_ ,_}

//默认导入
//java中java.long.*
//scala中
java.lang._
scala._
scala.Predef._ Predef下所有的方法


*/

包对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package priv.king

/**
*
* @author king
* TIME: 2020/11/8 - 18:54
*
**/

//创建包对象
//包内的所有方法和属性,在包内的对象可以直接使用
//一个包下只能由一个包对象
package object obj {

def foo={
println("foo.......")
}
}

image-20201108190418105

权限修饰符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
object ObjDemo3 {
def main(args: Array[String]): Unit = {
// val hello = new Hello()
val hello2 = new Hello2(1)

}
}


//对主构造器私有
class Hello private(var age:Int){
//对成员变量私有
private var a=10

}


//对主构造器私有
//但是对obj包下所有的类公开 []
//指定公开对成员变量也适用
class Hello2 private[obj](var age:Int){
//对成员变量私有
private[obj] var a=10


}
/*
权限修饰符
java中
public:所有地方
protected: 同包和子类
[default]: 同包
private: 本类


scala中
[default] 默认是public
protected 子类
private 只能在本类

权限修饰灵活性

*/

继承于多态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
object ObjDemo4 {


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

}
}



class QQQ(var arg:String){
private var a=1
protected var b=1

val c=222

def name()={
println("1111")
}

}

class WWW(var arg1:String) extends QQQ(arg1){
def fun={
// println(a) error
println(b)

}

//属性重写
//加上override关键字
override val c:Int=2


//子类重写必须加上override关键字
override def name(): Unit ={
super.name()
println("2222")
}
}

/*
单继承
构造器
先执行父构造器再执行子构造器

方法的重写必须加上override关键字

新概念:属性的重写
属性重写 加上override关键字
val只能重写val和不带参数的def
var只能重写抽象var


多态
java只有方法有多态,属性没有多态

scala中方法和属性都有多态
属性其实还是访问的是getter方法

*/

抽象类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
object ObjDemo5 {
def main(args: Array[String]): Unit = {

//匿名内部类
var aa = new ZZZ(10) {
override var b: Int = 1

override def foo(): Int = 1
}

}
}

abstract class ZZZ(var a:Int){
//抽象字段,不初始化
var b:Int

//抽象方法
//需要指定返回类型
def foo():Int
}

class XXX extends ZZZ(1){
override var b: Int = _

// ??? 实际上是调用Predef中的函数
//def ???:Nothing=throw new NotImplementedError
override def foo(): Int = ???
}

/*
scala抽象类
1.普通类有的抽象类都有
2.抽象类可以有抽象方法
3.抽象类不可以创建对象
*/

object && 伴生类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
object ObjDemo6 {
def main(args: Array[String]): Unit = {
CCC.fun

//apply 方法可以实现不用new 例如List()
//相当于调用CCC.apply()
//对象和类都有这个特性
println(CCC())
}
}


//CCC 相当于就是单例
//可以直接调用里面的方法
object CCC{
def fun=println("111")

//apply可以重载
def apply(): Int =10

}

//在一个.scala中有同名的object和class ,则称他们为伴生对象,伴生类
//编译过后 object中的相当于静态方法,class中的相当于非静态方法
//用来做静态工厂很方便

class CCC{

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
object ObjDemo7 {

def main(args: Array[String]): Unit = {
println(Phone.getPhone("iphone"))
println(Phone.getPhone("huawei"))
println(Phone.getPhone("google"))
println(Phone.getPhone("google"))

}

}

object Phone{

val map=mutable.Map[String,Phone](
"iphone"->new Phone("iphone"),
"huawei"->new Phone("huawei")
)

def getPhone(brand:String)=map.getOrElseUpdate(brand,new Phone(brand))

}

class Phone private (var brand:String){
//相当于主构造器中的代码
println(s"$brand .........")

override def toString:String = s"品牌->$brand"

}
//iphone .........
//huawei .........
//品牌->iphone
//品牌->huawei
//google .........
//品牌->google
//品牌->google

Trait

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
object ObjDemo8 {

def main(args: Array[String]): Unit = {
val abc = new ABCtrait
abc.eat() //eat c

val dtrait = new Dtrait with Atrait

}
}

trait Atrait {
def eat(): Unit ={
println("eat a")
}
}

trait Btrait extends Atrait {
override def eat()={
super[Atrait].eat()
println("eat b")
}
}

trait Ctrait extends Atrait {
override def eat()={
super.eat()
println("eat c")
}
}

class Dtrait {
def fff()={
println("555555")
}
}


trait Etrait{
//自身类型
//相当于继承Dtrait
self:Dtrait=>
def fun()={
self.fff()
}
}

class ABCtrait extends Atrait with Btrait with Ctrait {

}



/*
没有父类:class 类名 extends 特质1 with 特质2 with 特质3 …
有父类:class 类名 extends 父类 with 特质1 with 特质2 with 特质3…

scala没有提供接口,但是提供了trait 编译后也是接口
1.抽象类中有的东西,trait都可以有
2.trait可以多混入
3.先混入的先初始化
4.如果一个类混入特质中有相同的方法,则会产生成员冲突,可以使用菱形结构解决问题(同时继承一个父类,在父类中定义方法),或者时在子类直接重写该方法
5.在多混入的菱形结构中,super调用前一个混入的方法,或者时 super[xxx]指定调用谁的
6.动态混入,,new B with A
7.trait也可以继承类,但是注意scala最终还是要去单继承
8.自身类型 self:XXX=> 相当于继承,将某个类注入到self变量中
*/

类型转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
object ObjDemo9 {
def main(args: Array[String]): Unit = {
val kkk = new KKK

//类型判断
println(kkk.isInstanceOf[KKK])
println(kkk.isInstanceOf[LLL])
println(kkk.isInstanceOf[Object])

//类型转换
val lll = kkk.asInstanceOf[LLL]

}
}

class LLL

class KKK extends LLL

枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
object ObjDemo10 {
def main(args: Array[String]): Unit = {
var o = OOO1
println(OOO1.isInstanceOf[PPP])


println(Season.Spring)
println(Season.judge(1))
}
}

sealed abstract class PPP

object OOO1 extends PPP

object OOO2 extends PPP

object OOO3 extends PPP


object Season extends Enumeration{
type Season =Value //为了将Enumration.Value的类型暴露出来给外界使用
val Spring,Summer,Autumn,Winter =Value ///在这里定义具体的枚举实例

def judge(month:Int)={
if(month>=1 && month<=3) Spring
}

}

/*
sealed 修饰的类叫密封类
修饰后子类只能出现在当前文件中
1.模拟枚举
sealed abstract class PPP
object OOO1 extends PPP
2.java中编写,scala调用
3.继承Enumeration


*/

10类基础
https://jiajun.xyz/2020/11/03/scala/10类基础/
作者
Lambda
发布于
2020年11月3日
更新于
2021年8月5日
许可协议