第六章 面向对象
1、定义类
object $01_ClassDefined {
class Person
/**
* java定义类: [访问修饰符] class 类名{....}
* java中创建对象: new 类名(...)
*
* scala定义类: [访问修饰符] class 类名{...}
* scala中创建对象: new 类名(...)
*/
def main(args: Array[String]): Unit = {
val person = new Person
println(person)
}
}
2、class内定义属性
注意两点:1、scala中var修饰的属性可以使用_赋予初始值,使用_赋予初始值的时候必须指定属性的类型。
2、private[包名] 修饰符代表只能在指定包中使用,其他包无法使用
object $02_FieldAndMethod {
var name = "jack"
var age =20
private var phone =123
//scala用空格+下划线,赋默认初始值
var address:Boolean= _
def main(args: Array[String]): Unit = {
println(address)
println(phone) //在object内可以使用
val s1 = new student
println(s1.address)
println(s1.age)
//println(s1.phone) phone为私有属性,只有student内部能用
//s1.m1(1,2) m1私有方法无法调用
s1.m2(1,2)
println(s1.admin)
}
}
class student{
var name = "jack"
var age =20
//TODO private[包名] 修饰符代表只能在指定包中使用,其他包无法使用
private[chapter06] val admin = "role"
//scala默认支持public,private只有在本类中用
private var phone =123
//scala用空格+下划线,赋默认初始值
var address:Boolean= _
//定义私有方法
private def m1(x:Int,y:Int) = x + y
def m2(x:Int,y:Int) = x * y
}
3、class内构造器(主构造器+辅助构造器)
辅助构造器必须与其他辅助构造器与或者构造器
注意的点:
1、主构造器中属性使用val/var修饰与不使用val/var修饰的区别:
val/var修饰的非private的属性可以在class内部外部都可以访问
不使用val/var修饰的属性默认其实就是private,只能在class内部访问**
2、主构造器定义位置:class后面跟上括号
3、副构造器定义位置:class内部
4、class内部的私有属性对外部提供获取方法
5、如果只调用副构造器,那么副构造器内部必须调用主构造器给其他属性初始化
object $03_1 {
//主构造
class Person1(val name:String,
var agend:String,
age:Int,
address:String){
var col:String= _
//辅助构造器this,必须调用主构造器或者其他辅助构造器
def this(col:String){
//调用主构造器,如果单传一个col,必须调用主构造器给其他属性初始化
this(name="jack",agend="man",age=10,address="china")
this.col = col
}
def getAddress() = this.address
def getAge() = this.age
}
def main(args: Array[String]): Unit = {
//这里不传主构造器的参数,实际上是副构造器起了作用,副构造器已经将值传给了person
val person = new Person1("red")
println(person.name)
// println(person.age) 私有属性
println(person.getAge())
println(person.getAddress())
println(person.col)
println("--------------------------------")
val person1 = new Person1("zhang","man",20,"sshanghai")
println(person1.col)
println(person1.agend)
println(person1.name)
println(person1.getAge())
println(person1.getAddress())
}
}
4、scala使用@BeanProperties
注意的两点:
1、scala为了兼容java,提供了一个注解@BeanProperty注解,该注解能够自动生成java的set/get方法。
2、@BeanProperty注解不能用于private修饰的属性上
object $04_BeanTest {
class Person{
@BeanProperty
var name:String = "lisi"
@BeanProperty
var age:Int = 20
}
def main(args: Array[String]): Unit = {
val person = new Person
person.setAge(5)
person.setName("kkk")
println(person.getName)
println(person.getAge)
//对象转json字符串
val json = JSON.toJSONString(person, null.asInstanceOf[Array[SerializeFilter]])
println(json)
//json转对象
val js = """{"name":"xxx","age":200}"""
val person2 = JSON.parseObject(js,classOf[Person])
println(person2.name)
}
5、object
注意:
1、object是单例的,只有唯一的对象,通过打印结果可以知道,地址值是一样的
2、object中所有的属性和方法都是类似java static修饰的,可以通过 object名称.成员名 的方式调用
3、class中所有的属性和方法都是类似java 非static修饰的,可以通过 对象.成员名 的方式调用
object $05_object {
val name = "sss"
class test{
val name1 = "test"
}
def main(args: Array[String]): Unit = {
println($05_object)
println($05_object)
println(name)
// println(name1)
val test = new test
println(test.name1)
}
}
6、伴生类(class) 伴生对象(object)(重点)
注意点:
1、伴生之间的关系是private属性可以互相访问
2、伴生类[class]与伴生对象[object]
1、class与object名称必须一样
2、class与object必须在同一个.scala源文件中
3、 apply方法: 必须定义在object中,
主要用于简化对象的创建有了apply方法之后,
可以使用 object名称.apply(…) / object名称(…) 创建class的对象
object $06_Object_Class_together {
def main(args: Array[String]): Unit = {
val person = new Person
//person对象调用自己的方法
println(person.getName())
//Person内调用apply方法创建Person对象
println(Person.apply().getName())
//object的Person类名调用获取电话的方法,
// 由于getphone调用了new Person进行,所以会创建对象,并且将class内走一遍,
// 导致println(Person.gender)
println(Person.getPhone())
}
}
object Person {
private var name ="jack"
private var gender ="man"
//伴生对象调用半生类的私有属性
def getPhone() ={
new Person().phone
}
//方便object来创建Person,直接调用class Person内的属性、方法
def apply() = new Person()
}
class Person {
private var phone ="123456"
// 伴生类调用伴生对象的私有属性
println(Person.gender)
def getName()={
Person.name
}
}
7、类型转换
方法
1、classOf[类]: 获取该类的全类名
2、对象.getClass: 获取对象的全类名
3、将对象强制转换成某个类型: 对象.asInstanceOf[类型]
4、判断对象是否属于某个类型: 对象.isInstanceOf[类型]
object $07_TypeCheck {
class Animal
class Dog extends Animal{
val color = "red"
}
class Pig extends Animal{
val weight = 20
}
def getAnimal() = {
val index = Random.nextInt(10)
if(index%2==0){
new Pig
}else{
new Dog
}
}
/**
* java中判断对象是否属于某个类型: 对象 instanceof 类型
* java中将对象强制转换成某个类型: (类型)对象
* java中获取对象的class形式: 对象.getClass
* java中获取类的class形式: 类名.class
*
* scala中判断对象是否属于某个类型: 对象.isInstanceOf[类型]
* scala中将对象强制转换成某个类型: 对象.asInstanceOf[类型]
* scala中获取对象的class形式: 对象.getClass
* scala中获取类的class形式: classOf[类名]
*/
def main(args: Array[String]): Unit = {
val animal: Animal = getAnimal()
println(classOf[Pig])
println(classOf[Dog])
println(animal.getClass)
if(animal.isInstanceOf[Pig]) {
val pig = animal.asInstanceOf[Pig]
println(pig.weight)
}else{
val dog = animal.asInstanceOf[Dog]
println(dog.color)
}
}
}