一.面向对象编程基础
1.1 包
1)声明包:常用命名方式 域名反写+项目名称+模块名+程序类型名称
2)基本语法:和java类似
package cn.leaf.demo03
3)Scala在基础语法上进行了扩展,功能更加强大
- package关键字嵌套声明
package cn{
package leaf{
package demo03{
object Scala_Object{
def main(args: Array[String]): Unit = {
println("demo")
}
}
}
}
}
- Scala中包和类的物理路径没有关系
- 子包可以直接访问父包内容,不需要import导入
示例
package cn{
package leaf{
class Test{
def fun(): Unit ={
println("test")
}
}
package demo03{
object Scala_Object{
def main(args: Array[String]): Unit = {
// 直接使用父包中的Test类
val t = new Test()
t.fun()
}
}
}
}
}
1.2 导入import
1)基本语法和Java一致
2)Scala同样对import进行扩展
- import 可以在任意位置使用
object Scala_Object{
def main(args: Array[String]): Unit = {
import java.util.ArrayList
new ArrayList[String]()
}
}
- Scala中import可以在同一行导入多个类
import java.util.{List, ArrayList}
- 屏蔽包
import java.sql.{ Date=>_, Array=>_}
- 给包起别名
import java.util.{Date=>UtilDate}
1.3 类
Scala中没有static成员存在,但是Scala可以通过某种方式达到使用static成员的目的,这个就是伴生机制。
在语法层面上,把static成员和非static成员用不同的表达方式,就是class和object。
class在编译时只会产生当前类的class文件,其作用就是修饰普通的类。
object在编译时会产生两个类文件,一个是当前类的文件,另一个是单例的类文件,object中的属性和方法都可以通过类名直接访问,类似静态语法。
一般将object声明的类称之为伴生类,对应的单例文件称之为伴生对象。
但通常将相同名称的class、object声明的类进行区分:
使用class声明的类为伴生类
使用object声明的类为伴生对象
1.4 属性
示例
object Scala_Object{
def main(args: Array[String]): Unit = {
// 类中声明的属性等同于类中声明局部变量,使用var和val声明
val person1 = new Person
person1.name = "张三"
person1.age = 18
person1.addr = "Beijing"
}
}
class Person{
var name:String = _ // 下划线表示默认初始化
var age:Int = _
var addr:String = _
val heigh = 0 // 如果使用val声明,则需要显示赋值,同时使用val声明的属性也不能修改。
}
Scala类中声明的属性:
1)编译时,类中声明的属性都是private
然后同时提供公共方法进行访问
2)编译生成的方法为:
类似java中Bean对象的get方法,用于返回属性的值
类似java中Bean对象的set方法,用于设定属性的值
3)在使用时
因为属性是私有,所以给属性赋值,等同于调用set方法
因为属性是私有,所以获取属性值,等同于调用get方法
4)使用val声明的属性
编译时,属性会被final修饰,使用过程中不提供set方法
5)Scala编译生成get、set方法并不遵循bean规范,这导致在很多框架中无法使用,为了兼容其他框架,可以采用注解@BeanProperty。
@BeanProperty
var name:String = _
构建对象:
1) 使用class声明的类,可以直接使用new的方式
object Scala_Object{
def main(args: Array[String]): Unit = {
// new 对象,构造方法无参,则小括号可省略
val person1 = new Person
}
}
class Person{
}
2)使用apply构建对象,一般用于object伴生对象中构建对象。
示例
object Scala_Object{
def main(args: Array[String]): Unit = {
val person = Person()
val person2 = Person("张三")
}
}
class Person{
}
object Person{
// apply方法可以重载
def apply(): Person = new Person()
def apply(name:String): Person = {
println("Person name==>"+name)
new Person
}
}
1.5 访问权限
Scala中有4种访问权限:
- private: 私有权限,同类中访问
- private[包名]:包私有权限,同类或同包中访问
- protected: 受保护的权限,同类中访问或者子类中访问
- (default) : 公共权限,任意位置,注意Scala中没有public关键字
1.6 方法
Scala中类的方法就是函数,声明方式完全一样,但Scala中的方法具有重载和重写机制,同时调用方法必须通过对象。
1.7 构造方法
当使用new关键字创建对象时,就在调用类的构造方法。
Scala中构造方法有两种类型:
1)主构造方法:在类名后的构造方法
2)辅助构造方法:为完成类的初始化提供的构造方法
class Person(){ // 主构造方法
var person_name:String = _
def this(name:String){ // 辅助构造方法
this()
person_name = name
}
}
含有参数的主构造方法
class Person(name:String){ // 主构造方法可以有参数
// name参数是作为局部变量存在,不能通过对象在外部访问
// person_name 同样是局部变量,但同时也是类的属性,可以通过对象在外部调用
// 如果我们需要通过对象访问name属性,那传参时,可以使用val name:String,如下边类Person2
val person_name:String = name
}
class Person2(val name:String){
}
二. 面向对象编程进阶
2.1 继承
这个跟Java没有多少区别,同样是单继承,使用extends关键字
class Person{
}
class Student extends Person{
}
不同之处,如果子类要重写父类的非抽象方法,则必须使用overwrite关键字。
子类重写父类方法后,如果在子类中调用父类的被重写的方法,使用super关键字。
class Person{
def speak(): Unit ={
println("Person")
}
}
class Stu extends Person{
override def speak(): Unit = {
super.speak()
println("Student")
}
}
2.2 封装
面向对象编程,封装大同小异,跟没有多少差异。
2.3 抽象
1)抽象类
在父类中,有某些方法没有实现,子类继承时,需要重写来实现,这类方法就是抽象方法。
而含有抽象方法的类,就是抽象类,需要使用abstract声明,跟Java类似。
抽象类不能实例化。
abstract class Car {
def car_color():Unit
}
class BaoMa extends Car{
override def car_color(): Unit = {
println("red")
println("blue")
}
}
2)抽象属性
抽象属性,就是说属性只有声明,而没有初始化
类中存在抽象属性,那么这个类也是抽象类。
抽象属性在编译时,不会产生类的属性,而是产生属性的get、set方法,且都是抽象的。
重写抽象属性,等同于重写普通属性的声明:get、set方法
子类重写父类的抽象属性,那么只需要将属性声明补充完整即可。
子类重写父类的常规属性,则需要使用overwrite关键字修饰。
Scala中类的属性编译时,自动生成私有属性和对应的set、get方法,这点通过反编译可以查到。
示例
abstract class Car {
// 抽象属性
var car_height:Int
// 常规属性
@BeanProperty
val car_weight:Int = 20
}
class BaoMa extends Car{
var car_height: Int = 30
@BeanProperty
override val car_weight: Int = 30
}
2.4 特质
Scala没有接口的概念,也就没有interface关键字。
但是Scala提供Trait作为接口来使用,也就是特质。
简单来说,就是Scala能够从多个类中将相同的特征抽离出来,形成特殊的语法结构。
Java中所有的接口都可以当做特质来使用。
1)特质可以看做Interface,类混入特质,就等同于实现接口interface。
示例
// 使用trait关键字声明特质
trait DemoTrait{
def hello(info:String)
}
// 类使用extends关键字混入特质
class Person extends DemoTrait{
def hello(info: String): Unit = {
println("hello"+info)
}
2)特质中除了定义抽象方法外,还能定义具体方法
示例
object Scala_Object{
def main(args: Array[String]): Unit = {
// 声明实例对象,使用with关键字混入特质
val person = new Person with DemoTrait
person.hello("world")
}
}
// 使用trait关键字声明特质
trait DemoTrait{
def hello(info:String):Unit = {
println("hello:"+info)
}
}
class Person{
}