面向对象基础
概述
Scala是一门完全面向对象的语言,摒弃了Java中很多不是面向对象的语法,虽然如此,但其面向对象思想和Java的面向对象思想还是一致的。
package
在java中
作用
-
分类管理(实体类,demo类等区分) - 区分类(防重名)
- 包访问权限
语法
com.xxx.yyy.zzz
scala中的基本语法和java一致
扩展语法
-
Scala中包和类的物理路径没有关系
-
package关键字可以嵌套声明使用
-
同一个源码文件中 子包可以直接访问父包内容而无需import
-
Scala中package也可以看做对象,并声明属性和函数
import
java
作用
导入其他包中的类
静态导入
scala
作用
- 星号在scala中有特殊作用,因此不能使用,以下划线代替
- import 关键字可以在任何地方使用
- 可在一行中导入同一个包中多个类 import java.util.{ArrayList,List,LinkedList}
- 导包
import java.util new util.ArrayList()
- 隐藏类
- 起别名
import java.util.{HashMap=>JavaHashMap}
类
- 使用class关键字可以声明类
- 通过new的方式构建类的对象
- scala中的源码可以声明多个类,而且可以声明多个公共类,名称可以和文件名不一样
属性
基本语法
class User{var name: String = _ }
类属性就是类变量
var age:Int _
下划线表示类的属性默认初始化
访问权限
与Java类似,但是也有区别
private |
私有访问权限 只在类的内部和伴生对象中可用。 |
protected |
受保护权限,不能同包 同类、子类可以访问,同包无法访问。 |
private{包名} |
包访问权限 当前包可以访问 |
public(默认) |
公共访问权限 |
方法
类的方法就是函数,所以声明方式完全一样,但是必须通过使用对象进行调用
构造方法
概述
提供无参,公共的构造方法
构造方法的名称和类名是不一致的
scala是一个完全面向对象的语言。又是一个完全面向函数的语言
所以类也是个函数,声明一个类就等于声明一个函数
类名后面可以声明小括号,表示构造参数列表
如果提供了类的构造方法,那么jvm不会再给类提供无参的构造方法
之所以在类名后面提供构造方法,主要目的就是为了类的初始化
分类
主构造方法
完成类的初始化操作
辅助构造方法
其他的构造方法
在类初始化完成后做一些辅助功能
在执行之前应该调用主构造方法完成类的初始化
可以重载
案例
class User() { // 主构造函数
var username : String = _
def this( name:String ) { // 辅助构造函数,使用this关键字声明
this() // 辅助构造函数应该直接或间接调用主构造函数
username = name
}
def this( name:String, password:String ) {
this(name) // 构造器调用其他另外的构造器,要求被调用构造器必须提前声明
}
}
私有化构造方法
参数列表前增加private关键字
私有化之后外界怎么创建对象呢?
java中是使用静态方法 getInstance获取对象,但是scala没有静态语法
scala采用一种特殊的处理方式来代替静态语法:object
objcet关键字可以用于创建对象,对象的名字就是声明的名字
使用object关键字声明的类和对象是有关系的
这个对象等同于伴随着这个类创建时所产生的,所以将这个对象称之为伴生对象
类是伴生类
伴生对象就是一个对象,可以访问伴生类中所有东西,包括私有的
伴生对象其实就是马丁模拟静态语法所产生的
一般写代码时,将静态语法操作的代码写在伴生对象中,将成员方法写在伴生类中
高阶面向对象编程
继承
Scala也是单继承,且使用extends关键字
封装
将抽象出的数据和对数据的操作封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作(成员方法)才能对数据访问
1.将属性进行私有化
2.提供一个公共的set方法,用于对属性赋值
3.提供一个公共的get方法用于获取属性的值
抽象
- scala将一个不完整的类称为抽象类
如果一个方法只有声明没有实现,那么是抽象方法,因为它不完整
scala中如果一个属性只有声明没有初始化,那么是抽象属性
子类如果继承抽象类,必须实现抽象方法或补全抽象属性,否则也必须声明为抽象的,因为依然不完整
单例对象
- 所谓的单例对象,就是在程序运行过程中,指定类的对象
只能创建一个,而不能创建多个
。这样的对象可以由特殊的设计方式获得,也可以由语言本身设计得到,比如
object伴生对象
- Scala语言是完全面向对象的语言,所以并没有静态的操作(即在Scala中没有静态的概念)。但是为了能够和Java语言交互(因为Java中有静态概念),就产生了一种特殊的对象来模拟类对象,该对象为单例对象。
若单例对象名与类名一致,则称该单例对象这个类的伴生对象,这个类的所有“静态”内容都可以放置在它的伴生对象中声明,然后通过伴生对象名称直接调用
- 如果类名和伴生对象名称保持一致,那么这个类称之为伴生类。Scala编译器可以通过伴生对象的apply方法创建伴生类对象。apply方法可以重载,并传递参数,且可由Scala编译器自动识别。所以在使用时,其实是可以省略的。
案例
class User { // 伴生类
}
object User { // 伴生对象
def apply() = new User() // 构造伴生类对象
}
...
特质 trait
概述
将多个类的相同特征从类中剥离出来,形成一个独立的语法结构,称之为“特质”(特征)。这种方式在Java中称之为接口,但是Scala中没有接口的概念
基本语法
trait 特质名
class 类名 extends 父类 (特质1) with 特质2 with 特质3
动态混入
在创建对象的时候 with 特质名 可以让对象拥有该特质
trait eat {
println("wow he can eat so much")
}
//动态混入
val yxp = new yxp with eat
初始化叠加
在类初始化的时候叠加特质
trait run{
println("wow he can run so fast")
}
trait eat {
println("wow he can eat so much")
}
class likexiao extends run with eat{
println("I am Likexiao")
}
//初始化叠加
val likexiao = new likexiao
功能叠加
利用super关键字叠加功能
trait run{
println("wow he can run so fast")
//功能叠加
}
trait eat {
println("wow he can eat so much")
}
trait duzi extends eat{
println("so he have a big duzi")
}
trait thin extends run{
println("so he has a thin shencai")
}
class zhangsan extends thin with duzi{
println("I am Zhangsan")
}
val zhangsan = new zhangsan