Scala面向对象
面向对象编程OOP:
	  Scala  vs Java   都有这三特性
		    封装:把属性、方法封装到类中
		          Person:
		                 int id, String name, Date birthday....   需要getter/setter
                        eat、sleep....
		    
    继承:父类和子类之间的关系  override重写
		          User extends Person
		              exam......   //即可以继承别的类,也可以有自己的属性
		
    多态:*****级别,父类引用指向子类对象    精髓所在  开发框架的基石。
		          Person person = new Person();
		          User user = new User();
		          Person person = new User();
            
类的定义和使用:
object SimpleObjectApp {
      def main(args: Array[String]): Unit = {
            val perosn = new People();
            person.name = "Messi"
            println(person.name + " .. " + person.age)    
        
            person.printInfo()
      }
}
定义一个类:
class People {
      //定义属性
      var name:String = ""
      val age:Int = 10
    
      private [this] val gender = "male"     //private 表示只在本类里生效,出了本类就失败。
    
      def printInfo(): Unit = {
            println("gender:"  + gender)    
      }    
    
      //定义方法
      def eat():String = {
            name + "eat..."    
      }
    
      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", 30)   
            println(person.name + " : " + person.age + " : " + "person.school") 
        
            val person2 = new Person("lisi", 18, "M")   
            println(person2.name + " : " + person2.age + " : " + "person2.school" + " : " + person2.gender) 
      }
}	
// 主构造器 (val name:String, val age:Int)
class Person(val name:String, val age:Int) {
      println("Person Constructor enter...." )
      val school = "ustc"
      var gender:String = _
    
  //附属构造器
      def this(name:String, age:Int, gender:String) {
            this(name,age) //附属构造器的第一行代码必须要调用主构造器或者其他附属构造器
            this.gender = gender
      }    
    
      println("Person Constructor leave...." )
}
 
继承:
object ConstructorApp {
      def main(args: Array[String]): Unit = {
            val student = new Student("xiaochun", 18, "Math")   
            println(student.name + " : " + student.gender) 
      }
}	
class Student(name:String, age:Int, var major:String) extends Person(name,age) {        //extends 关键字,继承。
      println("Person Student enter...." )
    
      println("Person Student leave...." )
}


注意:当我们子类去继承父类的时候,如果父类有的属性,子类不用写val或var。例如上面的name:String和age:Int。 但是major:String参数是父类里没有的,所以必须写var或val。
重写: 
  使用override可以对子类继承父类的属性或者方法改写的。
比如修改上面的学校名:必须加override关键字
override val school = "peking"
  override def toString: String = "Person: override def toString :" + school
  
抽象类:
      如果在父类中,有某些方法无法立即实现,而需要依赖不同的子类来覆盖,重写实现不同的方法。
      此时,可以将父类中的这些方法编写成只含有方法签名,不含方法体的形式,这种形式就叫做抽象方法。
    
      一个类中,如果含有一个抽象方法或抽象field,就必须使用abstract将类声明为抽象类,该类是不可以被实例化的;在子类中覆盖抽象类的抽象方法时,可以不加override关键字。
object AbstractApp {
      def main(args: Array[String]): Unit = {
            val student = new Student2()
            println(student.name)
            student.speak    
      }
}
/**
      *   类的一个或者多个方法没有完整的实现 (只有定义,没有实现)
  */
//抽象类
abstract class Person2 {
  //抽象方法
      def speak
    
      //抽象字段
      val names:String
      val age:Int
}
//抽象类实现类
class Student2 extends Person2 {
      override def speak: Unit = {
            println("speak")    
      }
    
      override val name: String = "xiaochun"
      override val age: Int = 18
}
伴生类和伴生对象:
object ApplyApp {
}
//伴生类和伴生对象: class ApplyTest是object ApplyTest的伴生类,反之object ApplyTest是 class ApplyTest的伴生对象。两个是同名的。
class ApplyTest{
}
object ApplyTest{
}
apply方法:
object ApplyApp {
      def main(args: Array[String]): Unit = {
            for(i <- 1 to 10) {
                  ApplyTest.incr
            } 
        
            println(ApplyTest.count)  //10  说明object本身就是一个单例对象
        
            var b = ApplyTest()  // ==> 这句话调用的是Object里的apply方法
            println("~~~~~~~~")
            var c = new ApplyTest() // ==> 这句话调用的是class里的apply方法
            println(c)
            c() 
        
            //类名()  ==> Object.apply
            //对象() ==>  Class.apply
      }
}
class ApplyTest{
      def apply() = {
            println("class ApplyTest apply....")    
      }
}
object ApplyTest{
      println("Object ApplyTest enter....")
      var count = 0
      def incr = {
            count = count + 1    
      }
    
      //最佳实践: 在Object的apply方法中去new Class
      def apply() = {
            println("Object ApplyTest apply....")  
            //在object中的apply中new class 
            new ApplyTest 
      }
      println("Object ApplyTest leave....")
}
case class:
//通常用在模式匹配里面
object CaseClassApp {
      def main(args: Array[String]): Unit = {
           println(Dog("wangcai").name)
      }
}
//case class 不用new,直接使用就行。
case class Dog(name:String)
trait:   xxx extends Atrait with BTrait
class SparkConf(loadDefaults: Boolean)
      extends Cloneable
      with Logging
      with Serializable  
      ...
      ...
//这两个with的东西都是用 trait Logging和 trait Serializable
trait Partition extends Serializable {
      def index: Int
      override def hashCode(): Int = index
      override def equals(other: Any): Boolean = super.equals(other) 
}
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号