类和对象
创建类和对象
- main方法必须放在Object中
- 如果类是空的,没有任何成员,可以省略{}
- 如果构造器的参数为空,可以省略()
object demo01 {
//创建类。省略花括号
class Person
def main(args: Array[String]): Unit = {
//创建对象。省略括号
val person = new Person
println(person)
}
}
定义和访问成员变量
object demo01 {
class Person {
//定义成员变量
var name = ""
var age = 0
}
def main(args: Array[String]): Unit = {
//创建Person对象
val person = new Person
person.name = "zhangsan"
person.age = 20
//获取变量的值
println(person.name)
println(person.age)
}
}
使用下划线初始化成员变量
- 在定义var类型的成员变量时,可以使用_来初始化成员变量
- val类型的变量,必须要自己手动初始化
object demo01 {
class Person {
//使用下划线进行初始化
var name:String = _
var age:Int = _
}
def main(args: Array[String]): Unit = {
val person = new Person
println(person.name)
println(person.age)
}
}
定义成员方法
object demo01 {
class Customer {
var name:String = _
var sex:String = _
//定义成员方法
def sayHi(msg:String) = {
println(msg)
}
}
def main(args: Array[String]): Unit = {
val customer = new Customer
customer.name = "zhangsan"
customer.sex = "male"
customer.sayHi("hello")
}
}
成员访问修饰符
- 可以在成员前面添加private/protected关键字
- scala中没有public
- 任何没有被标为private或protected的成员都是公共的
object demo01 {
class Person {
//定义私有成员变量
private var name:String = _
private var age:Int = _
def getName() = name
def setName(name:String) = this.name = name
def getAge() = age
def setAge(age:Int) = this.age = age
//定义私有成员方法
private def getNameAndAge = name -> age
}
def main(args: Array[String]): Unit = {
val person = new Person
person.setName("zhangsan")
person.setAge(10)
println(person.getName())
println(person.getAge())
}
}
构造器
主构造器
- 主构造器的参数列表直接定义在类名后面
- 添加了var/val表示直接通过主构造器定义成员变量
- 构造器参数列表可以指定默认值
- 创建实例,调用构造器可以指定字段进行初始化
- 整个class中除了字段定义和方法定义的代码,都是构造代码
object demo01 {
//定义类的主构造器,并指定默认值
class Person(var name:String = "", var age:Int = 0){
println("调用主构造器")
}
def main(args: Array[String]): Unit = {
//不传入任何参数
val empty = new Person
//给构造器传入参数
val zhangsan = new Person("zhangsan", 20)
//指定字段进行初始化
val man = new Person(age = 40)
}
}
辅助构造器
- 辅助构造器的第一行代码,必须要调用主构造器或者其他辅助构造器
object demo01 {
class Customer(var name:String = "", var address:String = ""){
//定义辅助构造器
def this(array: Array[String]) = {
this(array(0), array(1))
}
}
def main(args: Array[String]): Unit = {
val zhangsan = new Customer(Array("zhangsan", "beijing"))
println(zhangsan.name)
println(zhangsan.address)
}
}
单例对象
- scala中没有中java的静态成员,要想定义类似于Java的static变量、static方法
- 就要使用到scala中的单例对象——object
单例对象
object demo01 {
//定义一个单例对象
object Dog {
val LEG_NUM = 4
}
def main(args: Array[String]): Unit = {
println(Dog.LEG_NUM)
}
}
在单例对象中定义成员方法
object demo01 {
object PrintUtil {
def printSpliter() = {
print("-" * 10)
}
}
def main(args: Array[String]): Unit = {
PrintUtil.printSpliter()
}
}
工具类案例
import java.text.SimpleDateFormat
import java.util.Date
object demo01 {
object DateUtils {
val s = new SimpleDateFormat("yyyy-MM-dd HH:mm")
def format(date:Date) = s.format(date)
}
def main(args: Array[String]): Unit = {
println(DateUtils.format(new Date()))
}
}
main方法
- main方法是静态的,必须放在一个单例对象中
- 除了使用main方法,还可以使用App Trait来定义入口
object demo01 extends App {
println("hello world")
}
伴生对象
- 有一些类,既有实例成员又有静态成员,可以使用伴生对象来实现
- 一个object和class具有同样的名字,则个object称为伴生对象,这个类称为伴生类
- 伴生对象和伴生类必须要同名
- 伴生对象和伴生类在同一个scala源文件中
- 伴生对象和伴生类可以互相访问private属性
伴生对象
object demo01 {
class CustomerService {
def save() = {
println(s"${CustomerService.SERVICE_NAME} + 保存客户")
}
}
//CustomerService的伴生对象
object CustomerService {
private val SERVICE_NAME = "CustomerService"
}
def main(args: Array[String]): Unit = {
val service = new CustomerService
service.save()
}
}
private[this]访问权限
- 如果某个成员的权限设置为private[this],表示只能在当前类中访问,伴生对象也不能访问
object demo01 {
class Person(private[this] var name:String, var age:Int)
object Person {
def printPerson(person: Person) = {
println(person.age)
}
}
def main(args: Array[String]): Unit = {
val person = new Person("zhangsan", 20)
Person.printPerson(person)
}
}
伴生对象 apply方法
object demo01 {
class Person(var name:String = "", var age:Int = 0)
object Person {
//定义apply方法,接收两个参数
def apply(name:String, age:Int) = new Person(name, age)
}
def main(args: Array[String]): Unit = {
//使用伴生对象名称来创建对象
val zhangsan = Person("zhangsan", 20)
println(zhangsan.name)
println(zhangsan.age)
}
}
继承(extends)
单例对象继承
object demo01 {
class Person {
private var name = "super"
def getName = this.name
}
object Student extends Person
def main(args: Array[String]): Unit = {
println(Student.getName)
}
}
override 和 super
- 使用override来重写一个val字段
- 使用super关键字来访问父类的成员方法
object demo01 {
class Person {
val name = "super"
def getName = this.name
}
class Student extends Person {
//重写val字段
override val name:String = "child"
//重写getName方法
override def getName: String = "hello " + super.getName
}
def main(args: Array[String]): Unit = {
println(new Student().name)
println(new Student().getName)
}
}
类型判断
-
isInstanceOf
判断对象是否为指定类的对象
-
asInstanceOf
将对象转换为指定类型
object demo01 {
class Person
class Student extends Person
def main(args: Array[String]): Unit = {
val s:Person = new Student
if(s.isInstanceOf[Person]){
val s1 = s.asInstanceOf[Student]
println("是Person类型")
} else {
println("是Student类型")
}
}
}
getClass 和 classOf
- isInstanceOf只能判断对象是否为指定类及其子类的对象
- 而不能精确的判断出对象就是指定类的对象
- 可以使用getClass和classOf精确判断
object demo01 {
class Person
class Student extends Person
def main(args: Array[String]): Unit = {
val s:Person = new Student
println(s.getClass == classOf[Person])
println(s.getClass == classOf[Student])
}
}
抽象类
抽象类
object demo01 {
//定义形状抽象类
abstract class Shape {
def area:Double
}
//创建正方形类
class Square(var length: Double) extends Shape {
override def area: Double = length * length
}
//创建圆形类
class Circle(var radius:Double) extends Shape {
override def area: Double = Math.PI * radius * radius
}
def main(args: Array[String]): Unit = {
val square = new Square(2)
val circle = new Circle(2)
println(square.area)
println(circle.area)
}
}
抽象字段
object demo01 {
abstract class Person {
val WHO_AM_I:String
}
class Student extends Person {
override val WHO_AM_I: String = "学生"
}
class Policeman extends Person {
override val WHO_AM_I: String = "警察"
}
def main(args: Array[String]): Unit = {
val student = new Student
val policeman = new Policeman
println(student.WHO_AM_I)
println(policeman.WHO_AM_I)
}
}
匿名内部类
object demo01 {
abstract class Person {
def sayHello
}
def main(args: Array[String]): Unit = {
val p = new Person {
override def sayHello: Unit = println("这是一个匿名内部类")
}
p.sayHello
}
}
特质(trait)
- scala中没有java中的接口interface,替代的是特质trait
特质作为接口使用
object demo01 {
trait MessageSender {
def sender(msg:String)
}
trait MessageReceive {
def receive():String
}
class MessageWorker extends MessageSender with MessageReceive {
override def sender(msg: String): Unit = println(s"发送消息:$msg")
override def receive(): String = "接收到了消息"
}
def main(args: Array[String]): Unit = {
val worker = new MessageWorker
worker.sender("hello world")
println(worker.receive())
}
}
object demo01 {
trait Logger {
def log(message:String)
}
object ConsoleLogger extends Logger {
override def log(message: String): Unit = println("控制台消息:" + message)
}
def main(args: Array[String]): Unit = {
ConsoleLogger.log("hello world")
}
}
特质中定义具体方法
object demo01 {
trait Logger {
def log(msg:String) = println(msg)
}
class UserService extends Logger {
def add() = log("hello world")
}
def main(args: Array[String]): Unit = {
val service = new UserService
service.add()
}
}
特质定义具体字段和抽象字段
object demo01 {
trait Logger {
val format = new SimpleDateFormat("yyyy-MM-dd HH:mm")
def log(msg:String)
}
class ConsoleLogger extends Logger {
override def log(msg: String): Unit = {
val info = s"${format.format(new Date())}:控制台消息:${msg}"
println(info)
}
}
def main(args: Array[String]): Unit = {
val logger = new ConsoleLogger
logger.log("hello world")
}
}
实现模板模式
object demo01 {
trait Logger {
def log(msg:String)
def info(msg:String) = log("INFO" + msg)
def warn(msg:String) = log("WARN" + msg)
}
class ConsoleLogger extends Logger {
override def log(msg: String): Unit = println(msg)
}
def main(args: Array[String]): Unit = {
val logger = new ConsoleLogger
logger.info("信息日志")
logger.warn("警告日志")
}
}
对象混入trait
object demo01 {
trait Logger {
def log(msg:String) = println(msg)
}
class UserService
def main(args: Array[String]): Unit = {
val service = new UserService with Logger
service.log("混入了log")
}
}
调用链
object demo01 {
trait HandlerTrait {
def handle(data:String) = println("处理数据...")
}
trait DataValidHandler extends HandlerTrait {
override def handle(data: String): Unit = {
println("验证数据...")
super.handle(data)
}
}
trait SignatureValidHandlerTrait extends HandlerTrait {
override def handle(data: String): Unit = {
println("校验签名...")
super.handle(data)
}
}
class PayService extends DataValidHandler with SignatureValidHandlerTrait {
override def handle(data: String): Unit = {
println("准备支付...")
super.handle(data)
}
}
def main(args: Array[String]): Unit = {
val service = new PayService
service.handle("支付参数")
}
}
trait构造机制
- trait也有构造代码,但是和类不一样,特质不能有构造器参数
- 每个特质只有一个无参构造器
- 一个类继承另一个类,以及多个trait,当创建该类的实例时,它的构造顺序如下
- 先执行父类的构造器
- 从左到右依次执行trait的构造器
- 如果trait有父trait,先构造父trait
- 如果多个trait有同样的父trait,则只初始化一次
- 执行子类构造器
trait继承class
- trait也可以继承class,特质会将class中的成员都继承下来
object demo01 {
class MyUtil {
def printMessage(msg:String) = println(msg)
}
trait Logger extends MyUtil {
def log(msg:String) = printMessage("Logger:" + msg)
}
class Person extends Logger {
def sayHello() = log("hello")
}
def main(args: Array[String]): Unit = {
val person = new Person
person.sayHello()
}
}