一、面向对象三大特征
封装:将属性和方法封装到类中,只对外开放一个接口,用于外部调用,不需要具体的实现细节
继承:子类继承父类
多态:父类引用指向子类对象。子类通过override来重写父类抽象类,可以实现多种形态
二、 类的定义和使用
object SimpleObjectApp {
def main(args: Array[String]): Unit = {
val person = new People
person.name = "Messi"
person.age = 18
println(person.name+":"+person.age)
println("invoke eat method:" + person.eat())
person.watchFootball("Barcelona")
}
}
class People {
// 定义属性
var name: String = _
var age: Int = 10
// private [this] 修饰的变量只能在当前类中访问
private [this] val gender = "male"
def printInfo(): Unit ={
println("gender: " + gender)
}
// 定义方法
def eat(): String = {
name + " is eating..."
}
def watchFootball(teamName: String): Unit ={
println(name + " is watching match of " + teamName)
}
}
三、主构造器和附属构造器 、继承、重写
object ConstructorApp {
def main(args: Array[String]): Unit = {
val person = new Person("zhangsan", 10)
println(person.name + " : " + person.age + " : " + person.school)
val person2 = new Person("lisi", 23, "M")
println(person2.name + " : "
+ person2.age + " : "
+ person2.school + " : "
+ person2.gender)
val student = new Student("wangwu", 20, "PE")
println(student.name + " : " + student.age + " : " + student.major)
}
}
// 主构造器
class Person(val name: String, val age: Int) {
println("Person Constructor enter...")
val school = "bj"
var gender: String = _
// 附属构造器
def this(name: String, age: Int, gender: String) {
this(name, age) // 附属构造器的第一行要代码必须调用主构造器或者其他附属构造器
this.gender = gender
}
println("Person Constructoer leave...")
}
// 继承
class Student(name: String, age: Int, var major: String) extends Person(name, age) {
println("Person student enter...")
println("Person student leave...")
}
四、抽象类
/**
* @description 子类实现抽象类
*/
object AbstractApp {
def main(args: Array[String]): Unit = {
val student = new Student2()
println(student.name)
student.speak
}
}
/**
* 类的一个或者多个方法没有完整的实现(只有定义,没有实现)
*/
abstract class Person2 {
def speak
val name:String
val age:Int
}
class Student2 extends Person2{
override def speak: Unit = {
println("speak")
}
override val name = "zhangsan"
override val age = 18
}
五、伴生类和伴生对象
object ApplyApp {
def main(args: Array[String]): Unit = {
// for (i <- 1 to 10) {
// ApplyTest.incr
// }
// println(ApplyTest.count) // 10 说明object本身就是一个单例对象
val b = ApplyTest() // 调用的是Object.apply
println("~~~~~~~~~~~~~~~~~~~")
val c = new ApplyTest()
println(c)
c()
// 类名() ==> 调用 Object.apply
// 对象() ==> 调用 Class.apply
}
}
/**
* 伴生类和伴生对象
* 如果有一个class,还有一个与class同名的object
* 那么就称这个object是class的伴生对象,class是object的伴生类
*/
class ApplyTest {
def apply() = {
println("class ApplyText apply...")
// 在object中的apply中new class
new ApplyTest
}
}
object ApplyTest {
println("Object ApplyText enter...")
var count = 0
def incr = {
count = count + 1
}
// 最佳实践:在Object的apply方法中去new Class,在使用的时候就可以直接使用不需要再new
def apply():ApplyTest = {
println("Object ApplyText apply...")
// 在object中的apply中new class
new ApplyTest
}
println("Object ApplyText leave...")
}
六、case class
// 通常用在模式匹配,目前自己在使用中有点像bean
object CaseClassApp {
def main(args: Array[String]): Unit = {
println(Dog("wangcai").name)
}
}
// case class不用new
case class Dog(name:String)
七、trait
trait ATrait // trait 修饰一个抽象类
作为接口使用: XXX extends ATrait with BTrait
class SparkConf(loadDefaults: Boolean) extends Cloneable with Logging with Serializable