包的命名
包的导入
Scala中基本的import导入语法和Java完全一致
import java.util.List
import java.util._ // Scala中使用下划线代替Java中的星号
Java中import导入的语法比较单一,Scala对此进行扩展,Scala中的import语法可以在任意位置使用
object ScalaImport{
def main(args: Array[String]): Unit = {
import java.util.ArrayList
new ArrayList()
}
}
Scala中可以导包,而不是导类
object ScalaImport{
def main(args: Array[String]): Unit = {
import java.util
new util.ArrayList()
}
}
Scala中可以在同一行中导入多个类,简化代码
import java.util.{List, ArrayList}
Scala中可以屏蔽某个包中的类
import java.util._
import java.sql.{ Date=>_, Array=>_, _ }
Scala中可以给类起别名,简化使用
import java.util.{ArrayList=>AList}
object ScalaImport{
def main(args: Array[String]): Unit = {
new AList()
}
}
Scala中可以使用类的绝对路径而不是相对路径
import _root_.java.util.ArrayList
默认情况下,Scala中会导入如下包和对象
import java.lang._
import scala._
Import scala.Predef._
类和对象
package chapter06
import scala.beans.BeanProperty
object Test03_Class {
def main(args: Array[String]): Unit = {
val student = new Student()
// println(student.name) // 不能访问private属性
println(student.age)
println(student.sex)
student.sex = "male"
println(student.sex)
}
}
// 定义一个类
class Student{
// 定义属性
// 生成get和set方法
private var name: String = "Alice"
// 初值为空, 0,必须定义var
@BeanProperty
var age: Int = _
// 初值为空, null,必须定义var
@BeanProperty
var sex: String = _
}
封装
访问权限
package chapter06
import scala.beans.BeanProperty
object Test04_Access {
def main(args: Array[String]): Unit = {
// 创建对象
val person = new Person()
// person.idCard // error
// person.name // error
println(person.sex)
println(person.age)
person.printInfo()
val worker = new Worker()
// worker.idCard // error
// worker.name // error
println(worker.sex)
println(worker.age)
worker.printInfo()
}
}
// 定义一个子类
class Worker extends Person {
override def printInfo(): Unit = {
println(s"Worker:")
// println($idCard) // error
name = "bob"
age = 25
sex = "male"
println(s"Worker: $name ${sex} $age")
}
}
package chapter06
object Test04_ClassForAccess {
}
// 定义一个父类
class Person {
// 只能在当前类访问和伴生对象访问
private var idCard: String = "123456"
// 只能在当前类和子类访问
protected var name: String = "Alice"
var sex: String = "female"
private[chapter06] var age: Int = 18
def printInfo() = {
println(s"Person: $idCard $name ${sex} $age")
}
}
构造器
和类名一样的方法
package chapter06
object Test05_Constructor {
def main(args: Array[String]): Unit = {
val student1 = new Student1()
student1.Student1()
val student2 = new Student1("scc")
student2.Student1()
val student3 = new Student1("zyy", 18)
student3.Student1()
}
}
// 定义一个类
class Student1() {
var name: String = _
var age: Int = _
println(s"1. 主构造方法被调用 $name $age")
// 声明辅助构造方法
def this(name: String) = {
this() // 直接调用主构造器
println(s"2. 辅助构造方法一被调用 $name $age")
this.name = name
println(s"name: $name age: $age")
}
def this(name: String, age: Int) = {
this(name) // 直接调用辅助构造器一
println(s"3. 辅助构造方法二被调用 $name $age")
this.name = name
this.age = age
println(s"name: $name age: $age")
}
// 此处不是构造方法
def Student1() = {
println(s"一般方法被调用")
}
}
1. 主构造方法被调用 null 0
一般方法被调用
1. 主构造方法被调用 null 0
2. 辅助构造方法一被调用 scc 0
name: scc age: 0
一般方法被调用
1. 主构造方法被调用 null 0
2. 辅助构造方法一被调用 zyy 0
name: zyy age: 0
3. 辅助构造方法二被调用 zyy 18
name: zyy age: 18
一般方法被调用
构造器参数
package chapter06
object Test06_ConstructorParams {
def main(args: Array[String]): Unit = {
val student2 = new Student2
student2.name = "Alice"
student2.age = 18
println(s"student2 name: ${student2.name}, age: ${student2.age}")
val student3 = new Student3("scc", 18)
println(s"student3 name: ${student3.name}, age: ${student3.age}")
val student4 = new Student4("bob", 29)
println(s"student4 name: ${student4.name}, age: ${student4.age}")
val student6 = new Student6("bob", 29,"南京理工")
student6.printInfo
println(s"student6 name: ${student6.name}, age: ${student6.age}")
}
}
// 定义一个类
// 无参构造器
class Student2() {
// 单独定义属性
var name: String = _
var age: Int = _
}
// 主构造器参数有var修饰,上面定义等价于,name和age为属性,不需要new和单独赋值,推荐这种写法
class Student3(var name: String, var age: Int)
// 主构造器参数无修饰,此时_name和_age为形参
// 非常不推荐
class Student4(_name: String, _age: Int) {
var name = _name
var age = _age
}
// val 属性值不能修改
class Student5(val name: String, val age: Int)
// 主构造器有参数
class Student6(var name: String, var age: Int) {
var school: String = _
def this(name: String, age: Int, school: String) = {
// 先调用主构造器有参数
this(name, age)
// 先调用辅助构造器有参数
this.school = school
}
def printInfo = {
println(s"student6 name: ${this.name}, age: ${this.age}, school: ${this.school}")
}
}
继承
package chapter06
object Test07_Inherit {
def main(args: Array[String]): Unit = {
/**
* 1. 父类的主构造器调用
* 2. 父类的辅助构造器调用
* 3. 子类的主构造器被调用
*/
val student1 = new Student7("scc", 18)
/**
* 1. 父类的主构造器调用
* 2. 父类的辅助构造器调用
* 3. 子类的主构造器被调用
* 4. 子类的辅助构造器被调用
*/
val student2 = new Student7("scc", 18, "0001")
}
}
// 定义一个父类
class Person7() {
var name: String = _
var age: Int = _
println("1. 父类的主构造器调用")
def this(name: String, age: Int) = {
this()
println("2. 父类的辅助构造器调用")
this.name = name
this.age = age
}
def printInfo = {
println(s"Person7: $name $age")
}
}
// 定义一个子类
// name和age为构造器参数,不是属性
// extends Person7(name, age) 和 extends Person7不一样,后者不会调用辅助构造器
class Student7(name: String, age: Int) extends Person7(name, age) {
var studentNum: String = _
println("3. 子类的主构造器被调用")
def this(name: String, age: Int, studentNum: String) = {
// 调用主构造器,先调用父类构造器,再调用子类构造器
this(name, age)
println("4. 子类的辅助构造器被调用")
this.studentNum = studentNum
}
override def printInfo: Unit = {
println(s"Student7: $name $age $studentNum")
}
}
多态
定义:一种接口,可以有多种实现方式
通过运行时,动态绑定手段,实现多态
scala属性和方法都是动态绑定的
抽象类
package chapter06
object Test09_Abstract {
def main(args: Array[String]): Unit = {
val student = new Student9
student.eat()
student.sleep()
}
}
// 定义抽象类
abstract class Person9() {
//非抽象属性
val name: String = "person"
// 抽象属性
var age: Int
// 非抽象方法
def eat(): Unit = {
println("person eat")
}
// 抽象方法
def sleep(): Unit
}
// 定义具体的实现子类
class Student9 extends Person9 {
// 实现抽象属性和方法
override var age: Int = 18
override def sleep(): Unit = {
println("student sleep")
}
//实现非抽象属性和方法,此时name在父类中是val类型
override val name: String = "student"
override def eat(): Unit = {
super.eat()
println("student eat")
}
}
匿名子类
package chapter06
// 匿名子类
object Test10_AnnoymousSubClass {
def main(args: Array[String]): Unit = {
val person: Person10 = new Person10 {
override var name: String = "scc"
override def eat(): Unit = {
println(s"${name} eat!")
}
}
println(person.name)
person.eat()
}
}
// 定义抽象类
abstract class Person10 {
var name: String
def eat(): Unit
}
单例对象/伴生对象
package chapter06
object Test11_Object {
def main(args: Array[String]): Unit = {
// 1. private 构造方法私有化时,下面语句会报错
// val student = new Student11("alice", 18)
// student.printInfo()
val student1: Student11 = Student11.newStudents("alice", 19)
student1.printInfo()
val student2: Student11 = Student11.apply("scc", 19)
student2.printInfo()
// 调用时,可以直接省略apply
val student3: Student11 = Student11("zyy", 19)
student3.printInfo()
}
}
// 定义类,private 构造方法私有化
class Student11 private(val name: String, val age: Int) {
def printInfo(): Unit = {
println(s"student name: ${name}, age: ${age}, school: ${Student11.school}")
}
}
// 定义伴生对象
object Student11 {
val school: String = "atguigu"
// 定义一个类的对象实例的创建方法或者工厂方法
def newStudents(name: String, age: Int): Student11 = {
new Student11(name, age)
}
// 定义一个特殊的方法,此方法有个特殊用法,调用时,可以直接省略apply
def apply(name: String, age: Int): Student11 = {
new Student11(name, age)
}
}
单例设计模式
饿汉式和懒汉式
package chapter06
object Test12_Singleton {
def main(args: Array[String]): Unit = {
val student1 = Student12.getInstance()
student1.printInfo()
// 真的只有一份吗?不信,再执行一遍
val student2 = Student12.getInstance()
student2.printInfo()
println(student1)
println(student2)
println(student1.eq(student2))
}
}
// 定义类,private 构造方法私有化
class Student12 private(val name: String, val age: Int) {
def printInfo(): Unit = {
println(s"student name: ${name}, age: ${age}, school: ${Student11.school}")
}
}
// 定义伴生对象
// 单例设计模式,饿汉式,低效
//object Student12 {
// private val student: Student12 = new Student12("alice", 18)
//
// def getInstance():Student12={
// student
// }
//}
// 定义伴生对象
// 单例设计模式,懒汉式,高效,不存在时,创建,对象存在时,不创建,
object Student12 {
private var student: Student12 = _
def getInstance(): Student12 = {
if (student == null) {
// 如果没有对象实例,则创建一个
student = new Student12("alice", 18)
}
student
}
}
特质(trait)
特质
package chapter06
object Test13_Trait {
def main(args: Array[String]): Unit = {
val student = new Student13()
student.sayHello()
student.dating()
student.study()
student.play()
/**
* hello from student
* hello from student student
* student student is dating
* student student is study
* young people student is playing
*/
}
}
// 定义一个父类
class Person13 {
val name: String = "person"
var age: Int = 18
def sayHello(): Unit = {
println("hello from " + name)
}
}
// 定义一个特质
trait Young {
// 声明抽象和非抽象属性
var age: Int
val name: String = "young"
// 声明抽象和非抽象方法
def play(): Unit = {
println(s"young people ${name} is playing")
}
def dating(): Unit
}
class Student13 extends Person13 with Young {
// 重写冲突的属性
override val name = "student"
// 实现抽象方法
override def dating(): Unit = {
println(s"student ${name} is dating")
}
// 定义具体方法
def study(): Unit = println(s"student ${name} is study")
override def sayHello(): Unit = {
// 就近原则
super.sayHello()
println(s"hello from student ${name}")
}
}
特质的混入
package chapter06
object Test14_TraitMixin {
def main(args: Array[String]): Unit = {
val student = new Student14
/**
* student student is study
* student student konwledge is increase 1
*/
student.study()
student.increase()
/**
* young people student is playing
* student student konwledge is increase 2
*/
student.play()
student.increase()
/**
* student student is dating
* student student konwledge is increase 3
*/
student.dating()
student.increase()
}
}
// 再定义一个特质
trait Knowledge {
var amount: Int = 0
def increase(): Unit
}
class Student14 extends Person13 with Young with Knowledge {
// 重写冲突的属性
override val name = "student"
// 实现抽象方法
override def dating(): Unit = {
println(s"student ${name} is dating")
}
// 定义具体方法
def study(): Unit = println(s"student ${name} is study")
override def sayHello(): Unit = {
// 就近原则
super.sayHello()
println(s"hello from student ${name}")
}
// 实现特质中的抽象方法
override def increase(): Unit = {
amount += 1
println(s"student ${name} konwledge is increase ${amount}")
}
}
特质的叠加+钻石问题,从右到左叠加
package chapter06
object Test15_TraitOverlying {
def main(args: Array[String]): Unit = {
val student = new Student15
/**
* konwledge increased
*/
student.increase()
//钻石问题特征叠加
/**
* my ball is a red-foot-ball
*/
val myFootBall = new MyFootBall
println(myFootBall.describe())
}
}
// 再定义一个特质
trait Knowledge15 {
var amount: Int = 0
def increase(): Unit = {
println(s"konwledge increased")
}
}
// 再定义一个特质
trait Talent15 {
def singing(): Unit
def dancing(): Unit
def increase(): Unit = {
println(s"talent increased")
}
}
// 首先调用最后一个特质的方法
class Student15 extends Person13 with Talent15 with Knowledge15 {
override def singing(): Unit = {
println("student is singing")
}
override def dancing(): Unit = {
println("student is dancing")
}
override def increase(): Unit = super.increase()
}
// 定义一个球类
trait Ball {
def describe(): String = {
"ball"
}
}
// 定义颜色特征
trait ColorBall extends Ball {
val color: String = "red"
override def describe(): String = {
color + "-" + super.describe()
}
}
// 定义种类特征
trait CategoryBall extends Ball {
val category: String = "foot"
override def describe(): String = {
category + "-" + super.describe()
}
}
// 定义一个自定义球类
class MyFootBall extends CategoryBall with ColorBall {
override def describe(): String = "my ball is a " + super.describe()
}
钻石问题的特质叠加
特质和抽象类的区别
类型转换和转换
package chapter06
object Test17_Extends {
def main(args: Array[String]): Unit = {
//1. 类型的转化和检测
val student = new Student17("alice", 18)
/**
* hi from student alice
* student alice is study
*/
student.sayHi()
student.study()
/**
* hi from student alice
*/
val person: Person17 = new Student17("alice", 18)
person.sayHi()
/**
* 类型判断
* student is Student17: true
* student is Person17: true
* person is Person17: true
* person is Student17: true
*/
println("student is Student17: " + student.isInstanceOf[Student17])
println("student is Person17: " + student.isInstanceOf[Person17])
println("person is Person17: " + person.isInstanceOf[Person17])
// 体现多态
println("person is Student17: " + person.isInstanceOf[Student17])
val person2: Person17 = new Person17("alice", 18)
/**
* person is Person17: true
* person is Student17: false
*/
println("person is Person17: " + person2.isInstanceOf[Person17])
println("person is Student17: " + person2.isInstanceOf[Student17])
// 类型转换
if (person.isInstanceOf[Student17]) {
val newStudent: Student17 = person.asInstanceOf[Student17]
newStudent.study()
}
println(classOf[Student17])
}
}
class Person17(val name: String, val age: Int) {
def sayHi(): Unit = {
println(s"hi from person $name")
}
}
class Student17(name: String, age: Int) extends Person17(name = name, age = age) {
override def sayHi(): Unit = {
println(s"hi from student $name")
}
def study(): Unit = {
println(s"student $name is study")
}
}