1.类和对象
scala是支持面向对象的,也有类和对象的概念,我们可以基于scala来开发面向对象的程序
用法:
- 使用class来定义一个类
- 使用new来创建对象
示例:
创建一个Person类,并创建它的对象
参考代码
package scala.demo
object Demo01 {
class Person{}
def main(args: Array[String]): Unit = {
val person = new Person()
println(person)
}
}
用法:
- 如果类是空的,没有任何成员,可以省略 {}
- 如果构造器的参数为空,可以省略()
示例
使用简写方式创建Person类和对象
参考代码
package scala.demo
object Demo01 {
//省略花括号
class Person
def main(args: Array[String]): Unit = {
//省略括号
val person = new Person
println(person)
}
}
2.定义和访问成员变量
一个类会有自己的属性,例如:人有自己的姓名和年龄
用法
- 在类中使用var/val来定义成员变量
- 对象之间使用成员变量名称来访问成员变量
示例
- 定义一个Person类,包含一个姓名和年龄字段
- 创建一个名为"张三",年龄为20岁的对象
- 在main方法中创建Person对象,设置成员变量为"张三",20
- 打印对象的名字和年龄
参考代码
package scala.demo
object Demo02 {
class Person(){
var name:String=""
var age:Int=0
}
def main(args: Array[String]): Unit = {
val person = new Person()
person.name="张三"
person.age=20
println(person.name+"...."+person.age)
}
}
3.使用下划线初始化成员变量
scala中有一个更加简洁的初始化成员变量的方式,可以让代码看起来更加的简洁
用法
- 在定义 var 类型的成员变量的时候,可以使用_ 来初始化赋值
- val 类型的成员变量,必须自己手动的进行初始化
示例
- 定义一个Person,包含一个姓名和年龄字段
- 创建一个名为"张三",年龄为20的对象
- 打印对象的姓名和年龄
参考代码
package scala.demo
object Demo03 {
class Person{
var name:String=_
var age:Int=_
}
def main(args: Array[String]): Unit = {
val person = new Person
person.name="张三"
person.age=20
println(person.name+"..."+person.age)
}
}
4.定义成员方法
类可以有自己的行为,scala中也可以通过定义成员方法来定义类的行为
定义
在scala的类中,通过def来定义成员方法
示例
- 创建一个Customer类
- 创建一个该类的对象,并调用printHello方法
参考代码
package scala.demo
object Demo04 {
class Customer{
var name:String=_
var sex:String=_
def printHello(msg:String)=println(msg)
}
def main(args: Array[String]): Unit = {
val customer = new Customer
customer.name="张三"
customer.sex="男"
customer.printHello(s"你好:${customer.name},${customer.sex}")
}
}
5.访问修饰符
和java一样,scala也可以通过访问修饰符,来控制成员变量和成员方法是否可以被访问
定义:
Java中的访问控制,同样适用于scala,可以在成员前添加private/protected关键字来控制成员的可见性,但是在scala中是没有public关键字的,任何没有被标记为private或者protected的成员都是公共的
示例
- 定义一个Person (+ 代表public - 代表private)
- 在main方法创建该类的对象,测试是否能访问到私有成员
参考代码
package scala.demo
object Demo05 {
class Person{
private var name:String=_
private var age:Int=_
def setName(name:String)=this.name=name
def getName=name
def setAge(age:Int)=this.age=age
def getAge=age
private def getNameAndAge={name->age}
}
def main(args: Array[String]): Unit = {
val person = new Person
person.setName("张三")
person.setAge(20)
println(person.getName)
println(person.getAge)
//调用私有方法,编译时报错
// println(person.getNameAndAge())
}
}
6.类的构造器
创建类对象的时候,会自动调用类的构造器
语法:
class 类名(var/val 参数名:类型 = 默认值, var/val 参数名:类型 = 默认值){
// 构造代码块
}
- 主构造器的参数列表是直接定义在类名后面的,添加了var/val表示直接通过主构造器定义成员变量
- 构造器参数列表可以指定默认值
- 创建实例,调用构造器可以指定字段进行初始化
- 整个class中除了字段定义和方法定义的代码都是构造代码
示例
- 定义一个Person类,通过主构造器参数列表定义姓名和年龄字段,并且设置它们的默认值
- 在主构造器中输出"调用主构造器"
- 创建"张三"对象(姓名为张三,年龄为20),打印对象的姓名和年龄
- 创建"空"对象,不给构造器传入任何的参数,打印对象的姓名和年龄
- 创建"man40"对象,不传入姓名参数,指定年龄为40,打印对象的姓名和年龄
参考代码
package scala.demo
object Demo06 {
class Person(var name:String="",var age:Int=0){
println("调用主构造器")
}
def main(args: Array[String]): Unit = {
val p = new Person("张三",20)
println(p.name+"..."+p.age)
val person = new Person
println(p.name+"..."+p.age)
val man40 = new Person(age=40)
println(man40.name+"..."+man40.age)
}
}
在scala中,除了定义主构造器外,还可以根据需求定义辅助构造器,例如:允许通过多种方式,来创建对象,除了主构造器之外的构造器都是辅助构造器
语法
- 定义辅助构造器与定义方法一样,也使用def 关键字来定义
- 这个方法的名字叫this
def this(参数名:类型, 参数名:类型) {
// 第一行需要调用主构造器或者其他构造器
// 构造器代码
}
注意:辅助构造器的第一行代码,必须要调用主构造器或者其他辅助构造器
示例
- 定义一个Customer类,包含一个姓名和地址字段
- 定义Customer类的主构造器(初始化姓名和地址)
- 定义Customer类的辅助构造器,该辅助构造器接收一个数组参数,使用数组参数来初始化成员变量
- 使用Person类的辅助构造器来创建一个"zhangsan"对象
- 姓名为张三
- 地址为北京
- 打印对象的姓名、地址
参考代码
package scala.demo
object Demo07 {
class Customer(var name:String="",var address:String=""){
def this(arr:Array[String]){
this(arr(0),arr(1))
}
}
def main(args: Array[String]): Unit = {
val customer = new Customer(Array("张三","北京"))
println(customer.name+"..."+customer.address)
}
}
7.单例对象
scala中没有Java的静态成员,要想定义Java中的sataic变量,方法,需要使用到scala中的单例对象----object
单例对象表示全局仅有一个对象(类似于 Java Statc概念)
- 定义单例对象和定义类很像,就是把class换为object
- 在object中定义的成员变量类似于Java中的静态变量
- 可以使用object直接引用成员变量
示例
- 定义一个Person单例对象,保存人有几只手
- 在main中打印结果
参考代码
package scala.demo
object Demo08 {
object Person{
var HADN=2
}
def main(args: Array[String]): Unit = {
println(Person.HADN)
}
}
在object中定义的成员方法类似于Java中的静态方法
示例
- 设计一个单例对象,定义一个能打印分割线的方法
- 在main方法调用该方法,打印分割线
参考代码
package scala.demo
object Demo09 {
object PrintUtil{
def printSpliter=println("-"*15)
}
def main(args: Array[String]): Unit = {
PrintUtil.printSpliter
}
}
示例:
- 编写一个DateUtil工具类专门用来格式化日期
- 定义一个方法,用于将日期(Date)转换为年月日字符串
参考代码
package scala.demo
import java.text.SimpleDateFormat
import java.util.Date
object Demo10 {
object DateUtils{
private val sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss E")
def format(date:Date) = sdf.format(date)
}
def main(args: Array[String]): Unit = {
println(DateUtils.format(new Date()))
}
}
8.main方法
scala和Java一样,如果要运行一个程序,必须有一个main方法,而在Java中main方法是静态的,而在scala中没有静态方法,在scala中,main方法必须放在一个单例对象中
main方法
def main(args:Array[String]):Unit = {
// 方法体
}
示例:
- 创建一个单例对象,打印"hello scala"
参考代码
object Demo10 {
def main(args: Array[String]): Unit = {
println("hello,scala")
}
}
创建一个object,继承自App Trait(特质),然后将需要编写在main方法中的代码,卸载object的构造方法中
object 单例对象名 extends App {
// 方法体
}
示例
- 继承App特质,来实现一个入口,同样输出"hello,scala"
参考代码
object Demo10 extends App{
println("hello,scala")
}
9.伴生对象
在java中,经常会有一些类,同时有实例成员又有静态成员,在scala中,要实现类似的效果,可以使用伴生对象来实现,还可以使用伴生对象来快速的创建对象,例如
// 无需使用new就可以快速来创建对象
val a = Array(1,2,3)
val b = Set(1,2,3)
一个class和object具有同样的名字,这个object成为伴生对象,这个class成为伴生类
- 伴生对象必须要和伴生类一样的名字
- 伴生对象和伴生类在同一个scala源文件中
- 伴生对象和伴生类可以相互访问private的属性
示例:
- 编写一个CustomerService类,有一个save方法,打印"服务类名称:保存客户"
- 编写一个CustomerService伴生对象,定义一个私有变量,用于保存服务类名称
- 创建CustomerService对象,调用save方法
参考代码
package scala.demo
object Demo11 {
class CustomerServie{
def save()=println(s"${CustomerServie.msg}:保存客户")
}
object CustomerServie{
private val msg="CustomerService"
}
def main(args: Array[String]): Unit = {
val servie = new CustomerServie()
servie.save()
}
}
如果某个成员的权限设置为private[this],表示只能在当前类中访问,伴生对象也不可访问
示例:
- 定义一个Person类,包含一个name字段
- 定义Person类的伴生对象,定义printPerson方法
- 测试伴生对象是否能访问private[this]权限的成员
参考代码
package scala.demo
object Demo12 {
//当在name前加上private[this]之后,伴生对象会报编译时期异常
//所有当private[this]修饰之后的成员,伴生对象也不能访问
class Person(private[this] var name:String)
object Person{
def printPerson(person: Person)=println(person.name)
}
}
可以通过伴生对象的apply方式来创建对象,这种写法不需要new对象
定义apply方法
object 伴生对象名 {
def apply(参数名:参数类型, 参数名:参数类型...) = new 类(...)
}
创建对象
伴生对象名(参数1, 参数2...)
示例
- 定义一个Person类,它包含两个字段:姓名和年龄
- 重写apply方法,使用Person类名就可以创建对象
- 在main方法中创建该类的对象,并打印姓名和年龄
参考代码
object Demo13 {
class Person(var name:String="",var age:Int=0)
object Person{
def apply(name:String,age:Int)=new Person(name,age)
}
def main(args: Array[String]): Unit = {
val per = Person("张三",20)
println(per.name+"---"+per.age)
}
}
10.继承
scala语言是支持面向对象编程的,可以使用scala来实现继承,通过继承减少复用代码
语法:
class/object 子类 extends 父类 {
..
}
参考代码:
object Demo14 {
class Person{
var name="super"
def getName=this.name
}
class Student extends Person
def main(args: Array[String]): Unit = {
val person = new Person
val student = new Student
student.name="张三"
println(student.name)
}
}
和Java语言一样,可以在子类中使用override需要来重写父类的成员,可以使用super来引用父类
用法:
- 子类要覆盖父类中的一个方法,必须使用override关键字
- 使用override来重写一个val字段
- 使用super关键字来访问父类的成员方法
示例:
- 定义一个Person类,包含
- 姓名字段(不可重新赋值)
- 获取姓名方法
- 定义一个Student类
- 重写姓名字段
- 重写获取姓名方法,返回"hello, " + 姓名
- 创建Student对象示例,调用它的getName方法
参考代码
object Demo16 {
class Person{
val name:String=""
def getName=name
}
class Student extends Person{
override val name:String ="child"
override def getName: String = "hello,"+super.getName
}
def main(args: Array[String]): Unit = {
println(new Student().getName)
}
}