1.类的定义
类是对象的蓝图,一旦定义了类,就可以使用关键字new根据类的蓝图创建对象
2.字段和方法
字段:不管是用var定义还是用val定义,都是指向对象的变量
1)Scala中字段默认是私有字段
2)Scala中方法可以访问该类的所有对象的私有字段
方法:用def定义,包含了可执行的代码
字段和方法的关系:字段保留了对象的状态和数据,而方法使用这些数据执行对象的运算共组
3.getter和setter
1) Scala对每个字段都提供getter方法和setter方法
2) 任何时候都可以重新定义getter和setter方法
3)如果字段是私有的,则getter和setter方法也是私有的
4)如果字段是val,则字段只有getter方法被生成
5)如果不需要getter和setter方法,可以将字段声明为private[this]
6)Scala中不能实现只有setter而没有getter
4.构造器
1)主构造器是类唯一的入口点每个Scala的构造器调用终将结束于对主构造器的调用
2)只有主构造器可以调用超类的构造器
3)如果主构造器不允许调用,则需在主构造器前面用private修饰
4)每个Scala类的每个辅助构造器都是以def this(.......)开头的
5)一个类若没有显示定义主构造器,则默认拥有一个无参的主构造器
//构造器、主构造器、构造器重载
class Teacher{
var name:String=_
private var age=27
private[this] val gender="male" //只属于当前实例
def this(name:String ){
this //默认无参构造器,等于this()
this.name=name
}
def Say(){
println(this.name+" "+this.age+" "+this.gender)
}
}
//带有构造器的类
class Student(val name:String ,val age:Int){
var gender:String=_
println(gender)
def this(name:String ,age:Int,gender:String ){ //构造器的重载
this(name,age)
this.gender=gender
}
def Say(){
println(this.name+" "+this.age+" "+this.gender)
}
}
5.内部类和外部类
内部类隶属于外部类实例本身,不属于类本身
//构造器、主构造器、构造器重载
class Teacher{
var name:String=_
private var age=27
private[this] val gender="male" //只属于当前实例
def this(name:String ){
this //默认无参构造器,等于this()
this.name=name
}
def Say(){
println(this.name+" "+this.age+" "+this.gender)
}
}
//带有构造器的类
class Student(val name:String ,val age:Int){
var gender:String=_
println(gender)
def this(name:String ,age:Int,gender:String ){ //构造器的重载
this(name,age)
this.gender=gender
}
def Say(){
println(this.name+" "+this.age+" "+this.gender)
}
}
//内部类和外部类
class Outer(val name:String){outer=>
class Inner(val name:String){
def foo(b:Inner)=println("outer "+outer.name+" inner "+b.name)
}
}
object OOPInScala {
def main(args:Array[String]){
val teacher=new Teacher
teacher.name="Scala"
teacher.Say()
val studnet=new Student("Spark",5)
studnet.gender="male"
studnet.Say()
val student1=new Student("Hadoop",10,"fmale")
student1.Say()
val outer=new Outer("Scala")
val inner=new outer.Inner("Spark") //内部类隶属于外部类实例本身,不属于类本身
inner.foo(inner)
}
6.类继承
1)子类继承父类的时候,必须填充满父类的所有主构造器
2)子类在覆写父类字段或方法的时候,都要在前面加上override
3)继承的构造顺序是从左往右的
class Person(val name:String,var age:Int){
val school="BjU"
def sleep="8 hours"
override def toString="I am a Person"
}
class Worker(name :String,age:Int,val salary:Long)extends Person(name,age){
override val school="Spark"
override def toString="I am a Worker "+super.sleep
}
object OverrideOperation {
def main(args:Array[String]){
val w=new Worker("Scala",18,100000)
println("school "+w.school)
println("salary "+w.salary)
println("toString "+w.toString)
}
}
7.抽象类
用abstract修饰的类为抽象类
//抽象类,抽象方法,抽象字段
class AbstractClass{
var id:Int=_
}
abstract class SuperTeacher(val name:String){
var id:Int
var age:Int
def teach
}
class MathTeacher(name:String,val sex:String)extends SuperTeacher(name){
override var id=name.hashCode()
override var age=29
override def teach(){
println("teaching")
}
}
object AbstractClass {
def main(args:Array[String]){
val teacher=new MathTeacher("Spark","男")
teacher.teach
println("id "+teacher.id)
println("age "+teacher.age)
println("sex "+teacher.sex)
println("name "+teacher.name)
}
}
8.class和object的关系
1)如果名称相同,则object中的内容都是class的静态内容,也就是说object中的内容class都可以在没有实例的时候直接去调用;正是因为可以在没有类的实例的时候去调用object中的一切内容,所以可以使用object中的特定方法来创建类的实例,而这个特定方法就是apply方法;
2)object中的apply方式是class对象生成的工厂方法,用于控制对象的生成
3) 很多框架的代码一般直接调用抽象类的object的apply方法去生成类的实例对象
a.apply具有类的对象生成的一切生杀大权,抽象类是不可以直接实例化的,在apply方法中可以实例化抽象类的子类,以Spark中的图计算为例,Graph是抽象的class,在object Graph中的apply方法实际上是调用了Graph的子类GraphImpl来构建Graph类型的对象实例的,当然从Spark图计算的源码可以看出,GraphImpl的构造也是使用了object GraphImpl的apply方法
b.这种方式神奇的效应在于更加能够应对代表版本迭代或者修改的变化,这是更高意义的面向接口编程
4)object HelloOOP是class HelloOOP的伴生对象,class HelloOOP可以直接访问object HelloOOP中的一切内容,而class HelloOOP是object HelloOOP的伴生类,object HelloOOP可以直接访问class HelloOOP的一切内容
5)在定义Scala的class的时候可以直接在类名后面()里加入类的构造参数,此时在apply方法中也必须有这些参数
6)scala中可以在object中构造很多apply方法
7)Scala中的很多集合都是使用apply的方式构造的,例如Array:
class HelloOOP(age:Int){
var name = "Spark"
def sayHello = {
println("Hi, My name is " + name)
println("I am " + age + " years old")
}
}
object HelloOOP {
var number = 0
def main(args: Array[String]): Unit = {
println("Hello Scala OOP!!!")
// val helloOOP = new HelloOOP
val helloOOP = HelloOOP()
helloOOP.sayHello
Array(1,2,3,4,5)
}
def apply(): HelloOOP = {
println("My number is : " + number)
number += 1
new HelloOOP(10)
}
def apply(age:Int): HelloOOP = {
println("My number is : " + number)
number += 1
new HelloOOP(age)
}