第6章 面向对象

第6章 面向对象

6.1. Scala包

第6章 面向对象_第1张图片

  1. 包的命名

    第6章 面向对象_第2张图片

  2. 包的导入

    • Scala中基本的import导入语法和Java完全一致

      import java.util.List
      import java.util._ // Scala中使用下划线代替Java中的星号
      
    • Java中import导入的语法比较单一,Scala对此进行扩展,Scala中的import语法可以在任意位置使用

      object ScalaImport{
          def main(args: Array[String]): Unit = {
              import java.util.ArrayList
              new ArrayList()
          }
      }
      
      
    • Scala中可以导包,而不是导类

      object ScalaImport{
      
          def main(args: Array[String]): Unit = {
              import java.util
              new util.ArrayList()
          }
      
      }
      
    • Scala中可以在同一行中导入多个类,简化代码

      import java.util.{List, ArrayList}
      
    • Scala中可以屏蔽某个包中的类

      import java.util._
      import java.sql.{ Date=>_, Array=>_, _ }
      
    • Scala中可以给类起别名,简化使用

      import java.util.{ArrayList=>AList}
      
      object ScalaImport{
          def main(args: Array[String]): Unit = {
              new AList()
          }
      }
      
    • Scala中可以使用类的绝对路径而不是相对路径

      import _root_.java.util.ArrayList
      
    • 默认情况下,Scala中会导入如下包和对象

      import java.lang._
      import scala._
      Import scala.Predef._
      

6.2 类和对象

  1. 类和对象

    package chapter06
    
    import scala.beans.BeanProperty
    
    object Test03_Class {
      def main(args: Array[String]): Unit = {
        val student = new Student()
    
    //    println(student.name) // 不能访问private属性
        println(student.age)
        println(student.sex)
        student.sex = "male"
    
    
        println(student.sex)
    
      }
    
    }
    
    // 定义一个类
    class Student{
      // 定义属性
    
      // 生成get和set方法
      private var name: String = "Alice"
    
      // 初值为空, 0,必须定义var
      @BeanProperty
      var age: Int = _
    
      // 初值为空, null,必须定义var
      @BeanProperty
      var sex: String = _
    
    }
    
    
  2. 封装

    第6章 面向对象_第3张图片

  3. 访问权限

    第6章 面向对象_第4张图片

    package chapter06
    
    import scala.beans.BeanProperty
    
    object Test04_Access {
      def main(args: Array[String]): Unit = {
        // 创建对象
        val person = new Person()
    //    person.idCard // error
    //    person.name // error
        println(person.sex)
        println(person.age)
        person.printInfo()
    
        val worker = new Worker()
        //    worker.idCard // error
        //    worker.name // error
        println(worker.sex)
        println(worker.age)
        worker.printInfo()
      }
    
    }
    
    // 定义一个子类
    class Worker extends Person {
      override def printInfo(): Unit = {
        println(s"Worker:")
    //    println($idCard) // error
        name = "bob"
        age = 25
        sex = "male"
        println(s"Worker: $name ${sex} $age")
      }
    }
    
    
    package chapter06
    
    object Test04_ClassForAccess {
    
    }
    
    // 定义一个父类
    class Person {
      // 只能在当前类访问和伴生对象访问
      private var idCard: String = "123456"
      // 只能在当前类和子类访问
      protected var name: String = "Alice"
      var sex: String = "female"
      private[chapter06] var age: Int = 18
    
      def printInfo() = {
        println(s"Person: $idCard $name ${sex} $age")
      }
    }
    
    
  4. 构造器

    和类名一样的方法

    第6章 面向对象_第5张图片

    package chapter06
    
    
    object Test05_Constructor {
      def main(args: Array[String]): Unit = {
        val student1 = new Student1()
        student1.Student1()
    
        val student2 = new Student1("scc")
        student2.Student1()
        val student3 = new Student1("zyy", 18)
        student3.Student1()
      }
    
    }
    
    // 定义一个类
    class Student1() {
      var name: String = _
      var age: Int = _
      println(s"1. 主构造方法被调用 $name $age")
    
      // 声明辅助构造方法
      def this(name: String) = {
        this() // 直接调用主构造器
        println(s"2. 辅助构造方法一被调用 $name $age")
        this.name = name
        println(s"name: $name age: $age")
      }
    
      def this(name: String, age: Int) = {
        this(name) // 直接调用辅助构造器一
        println(s"3. 辅助构造方法二被调用 $name $age")
        this.name = name
        this.age = age
        println(s"name: $name age: $age")
      }
    
      // 此处不是构造方法
      def Student1() = {
        println(s"一般方法被调用")
      }
    
    }
    
    1. 主构造方法被调用 null 0
    一般方法被调用
    1. 主构造方法被调用 null 0
    2. 辅助构造方法一被调用 scc 0
    name: scc age: 0
    一般方法被调用
    1. 主构造方法被调用 null 0
    2. 辅助构造方法一被调用 zyy 0
    name: zyy age: 0
    3. 辅助构造方法二被调用 zyy 18
    name: zyy age: 18
    一般方法被调用
    
  5. 构造器参数

    第6章 面向对象_第6张图片

    package chapter06
    
    object Test06_ConstructorParams {
      def main(args: Array[String]): Unit = {
    
        val student2 = new Student2
        student2.name = "Alice"
        student2.age = 18
        println(s"student2 name: ${student2.name}, age: ${student2.age}")
    
        val student3 = new Student3("scc", 18)
        println(s"student3 name: ${student3.name}, age: ${student3.age}")
    
        val student4 = new Student4("bob", 29)
        println(s"student4 name: ${student4.name}, age: ${student4.age}")
    
        val student6 = new Student6("bob", 29,"南京理工")
        student6.printInfo
        println(s"student6 name: ${student6.name}, age: ${student6.age}")
      }
    
    }
    
    // 定义一个类
    // 无参构造器
    class Student2() {
      // 单独定义属性
      var name: String = _
      var age: Int = _
    }
    
    // 主构造器参数有var修饰,上面定义等价于,name和age为属性,不需要new和单独赋值,推荐这种写法
    class Student3(var name: String, var age: Int)
    
    
    // 主构造器参数无修饰,此时_name和_age为形参
    // 非常不推荐
    class Student4(_name: String, _age: Int) {
      var name = _name
      var age = _age
    }
    
    
    // val 属性值不能修改
    class Student5(val name: String, val age: Int)
    
    
    // 主构造器有参数
    class Student6(var name: String, var age: Int) {
    
      var school: String = _
    
      def this(name: String, age: Int, school: String) = {
        // 先调用主构造器有参数
        this(name, age)
        // 先调用辅助构造器有参数
        this.school = school
    
      }
    
      def printInfo = {
        println(s"student6 name: ${this.name}, age: ${this.age}, school: ${this.school}")
      }
    
    }
    
  6. 继承

    第6章 面向对象_第7张图片

    package chapter06
    
    object Test07_Inherit {
      def main(args: Array[String]): Unit = {
        /**
         * 1. 父类的主构造器调用
         * 2. 父类的辅助构造器调用
         * 3. 子类的主构造器被调用
         */
        val student1 = new Student7("scc", 18)
        /**
         * 1. 父类的主构造器调用
         * 2. 父类的辅助构造器调用
         * 3. 子类的主构造器被调用
         * 4. 子类的辅助构造器被调用
         */
        val student2 = new Student7("scc", 18, "0001")
      }
    
    }
    
    // 定义一个父类
    class Person7() {
      var name: String = _
      var age: Int = _
      println("1. 父类的主构造器调用")
    
      def this(name: String, age: Int) = {
        this()
        println("2. 父类的辅助构造器调用")
        this.name = name
        this.age = age
    
      }
    
      def printInfo = {
        println(s"Person7: $name $age")
      }
    
    }
    
    // 定义一个子类
    // name和age为构造器参数,不是属性
    // extends Person7(name, age) 和 extends Person7不一样,后者不会调用辅助构造器
    class Student7(name: String, age: Int) extends Person7(name, age) {
      var studentNum: String = _
      println("3. 子类的主构造器被调用")
    
      def this(name: String, age: Int, studentNum: String) = {
        // 调用主构造器,先调用父类构造器,再调用子类构造器
        this(name, age)
        println("4. 子类的辅助构造器被调用")
        this.studentNum = studentNum
    
      }
    
      override def printInfo: Unit = {
        println(s"Student7: $name $age $studentNum")
      }
    
    }
    
  7. 多态

    定义:一种接口,可以有多种实现方式

    通过运行时,动态绑定手段,实现多态

    scala属性和方法都是动态绑定的

    第6章 面向对象_第8张图片

  8. 抽象类

    第6章 面向对象_第9张图片

    第6章 面向对象_第10张图片

    第6章 面向对象_第11张图片

    package chapter06
    
    object Test09_Abstract {
      def main(args: Array[String]): Unit = {
        val student = new Student9
        student.eat()
        student.sleep()
      }
    }
    
    // 定义抽象类
    abstract class Person9() {
      //非抽象属性
      val name: String = "person"
      // 抽象属性
      var age: Int
    
      // 非抽象方法
      def eat(): Unit = {
        println("person eat")
      }
    
      // 抽象方法
      def sleep(): Unit
    
    }
    
    // 定义具体的实现子类
    class Student9 extends Person9 {
      // 实现抽象属性和方法
      override var age: Int = 18
    
      override def sleep(): Unit = {
        println("student sleep")
      }
    
      //实现非抽象属性和方法,此时name在父类中是val类型
      override val name: String = "student"
    
      override def eat(): Unit = {
        super.eat()
        println("student eat")
      }
    }
    
    
  9. 匿名子类

    package chapter06
    
    // 匿名子类
    object Test10_AnnoymousSubClass {
      def main(args: Array[String]): Unit = {
        val person: Person10 = new Person10 {
          override var name: String = "scc"
    
          override def eat(): Unit = {
            println(s"${name} eat!")
          }
        }
    
        println(person.name)
        person.eat()
      }
    
    }
    
    // 定义抽象类
    abstract class Person10 {
      var name: String
    
      def eat(): Unit
    
    }
    
    
  10. 单例对象/伴生对象

    第6章 面向对象_第12张图片

    第6章 面向对象_第13张图片

    package chapter06
    
    object Test11_Object {
      def main(args: Array[String]): Unit = {
        // 1. private 构造方法私有化时,下面语句会报错
        //    val student = new Student11("alice", 18)
        //    student.printInfo()
    
        val student1: Student11 = Student11.newStudents("alice", 19)
        student1.printInfo()
    
        val student2: Student11 = Student11.apply("scc", 19)
        student2.printInfo()
    
        // 调用时,可以直接省略apply
        val student3: Student11 = Student11("zyy", 19)
        student3.printInfo()
      }
    
    }
    
    // 定义类,private 构造方法私有化
    class Student11 private(val name: String, val age: Int) {
      def printInfo(): Unit = {
        println(s"student name: ${name}, age: ${age}, school: ${Student11.school}")
      }
    }
    
    // 定义伴生对象
    object Student11 {
      val school: String = "atguigu"
    
    
      // 定义一个类的对象实例的创建方法或者工厂方法
      def newStudents(name: String, age: Int): Student11 = {
        new Student11(name, age)
      }
    
      // 定义一个特殊的方法,此方法有个特殊用法,调用时,可以直接省略apply
      def apply(name: String, age: Int): Student11 = {
        new Student11(name, age)
      }
    }
    
    
  11. 单例设计模式

    饿汉式和懒汉式

    package chapter06
    
    
    object Test12_Singleton {
      def main(args: Array[String]): Unit = {
        val student1 = Student12.getInstance()
        student1.printInfo()
    
        // 真的只有一份吗?不信,再执行一遍
        val student2 = Student12.getInstance()
        student2.printInfo()
    
        println(student1)
        println(student2)
        println(student1.eq(student2))
    
      }
    
    }
    
    
    // 定义类,private 构造方法私有化
    class Student12 private(val name: String, val age: Int) {
      def printInfo(): Unit = {
        println(s"student name: ${name}, age: ${age}, school: ${Student11.school}")
      }
    }
    
    // 定义伴生对象
    // 单例设计模式,饿汉式,低效
    //object Student12 {
    //  private val student: Student12 = new Student12("alice", 18)
    //
    //  def getInstance():Student12={
    //    student
    //  }
    //}
    
    // 定义伴生对象
    // 单例设计模式,懒汉式,高效,不存在时,创建,对象存在时,不创建,
    object Student12 {
      private var student: Student12 = _
    
      def getInstance(): Student12 = {
        if (student == null) {
          // 如果没有对象实例,则创建一个
          student = new Student12("alice", 18)
        }
        student
      }
    
    }
    
  12. 特质(trait)

    第6章 面向对象_第14张图片

    第6章 面向对象_第15张图片

  13. 特质

    package chapter06
    
    object Test13_Trait {
      def main(args: Array[String]): Unit = {
        val student = new Student13()
        student.sayHello()
        student.dating()
        student.study()
        student.play()
    
        /**
         * hello from student
         * hello from student student
         * student student is dating
         * student student is study
         * young people student is playing
         */
    
      }
    
    }
    
    
    // 定义一个父类
    class Person13 {
      val name: String = "person"
      var age: Int = 18
    
      def sayHello(): Unit = {
        println("hello from " + name)
      }
    }
    
    // 定义一个特质
    trait Young {
      // 声明抽象和非抽象属性
      var age: Int
      val name: String = "young"
    
      // 声明抽象和非抽象方法
      def play(): Unit = {
        println(s"young people ${name} is playing")
      }
    
      def dating(): Unit
    }
    
    class Student13 extends Person13 with Young {
      // 重写冲突的属性
      override val name = "student"
    
      // 实现抽象方法
      override def dating(): Unit = {
        println(s"student ${name} is dating")
      }
    
      // 定义具体方法
      def study(): Unit = println(s"student ${name} is study")
    
      override def sayHello(): Unit = {
        // 就近原则
        super.sayHello()
        println(s"hello from student ${name}")
      }
    
    }
    
  14. 特质的混入

    package chapter06
    
    object Test14_TraitMixin {
      def main(args: Array[String]): Unit = {
        val student = new Student14
    
        /**
         * student student is study
         * student student konwledge is increase 1
         */
        student.study()
        student.increase()
    
        /**
         * young people student is playing
         * student student konwledge is increase 2
         */
    
        student.play()
        student.increase()
    
        /**
         * student student is dating
         * student student konwledge is increase 3
         */
    
        student.dating()
        student.increase()
      }
    }
    
    
    // 再定义一个特质
    trait Knowledge {
      var amount: Int = 0
    
      def increase(): Unit
    }
    
    
    class Student14 extends Person13 with Young with Knowledge {
      // 重写冲突的属性
      override val name = "student"
    
      // 实现抽象方法
      override def dating(): Unit = {
        println(s"student ${name} is dating")
      }
    
      // 定义具体方法
      def study(): Unit = println(s"student ${name} is study")
    
      override def sayHello(): Unit = {
        // 就近原则
        super.sayHello()
        println(s"hello from student ${name}")
      }
    
    
      // 实现特质中的抽象方法
      override def increase(): Unit = {
        amount += 1
        println(s"student ${name} konwledge is increase ${amount}")
      }
    
    }
    
    
  15. 特质的叠加+钻石问题,从右到左叠加

    package chapter06
    
    object Test15_TraitOverlying {
      def main(args: Array[String]): Unit = {
        val student = new Student15
    
        /**
         * konwledge increased
         */
        student.increase()
    
        //钻石问题特征叠加
        /**
         * my ball is a red-foot-ball
         */
        val myFootBall = new MyFootBall
        println(myFootBall.describe())
      }
    
    }
    
    
    // 再定义一个特质
    trait Knowledge15 {
      var amount: Int = 0
    
      def increase(): Unit = {
        println(s"konwledge increased")
      }
    }
    
    // 再定义一个特质
    trait Talent15 {
      def singing(): Unit
    
      def dancing(): Unit
    
      def increase(): Unit = {
        println(s"talent increased")
      }
    }
    
    // 首先调用最后一个特质的方法
    class Student15 extends Person13 with Talent15 with Knowledge15 {
      override def singing(): Unit = {
        println("student is singing")
      }
    
      override def dancing(): Unit = {
        println("student is dancing")
      }
    
      override def increase(): Unit = super.increase()
    }
    
    
    // 定义一个球类
    trait Ball {
      def describe(): String = {
        "ball"
      }
    }
    
    // 定义颜色特征
    trait ColorBall extends Ball {
      val color: String = "red"
    
      override def describe(): String = {
        color + "-" + super.describe()
      }
    }
    
    // 定义种类特征
    trait CategoryBall extends Ball {
      val category: String = "foot"
    
      override def describe(): String = {
        category + "-" + super.describe()
      }
    }
    
    // 定义一个自定义球类
    class MyFootBall extends CategoryBall with ColorBall {
      override def describe(): String = "my ball is a " + super.describe()
    
    }
    
    
  16. 钻石问题的特质叠加

    第6章 面向对象_第16张图片

    第6章 面向对象_第17张图片

    第6章 面向对象_第18张图片

    第6章 面向对象_第19张图片​​

  17. 特质和抽象类的区别

    第6章 面向对象_第20张图片

  18. 类型转换和转换

    第6章 面向对象_第21张图片

    package chapter06
    
    object Test17_Extends {
      def main(args: Array[String]): Unit = {
        //1. 类型的转化和检测
        val student = new Student17("alice", 18)
    
        /**
         * hi from student alice
         * student alice is study
         */
        student.sayHi()
        student.study()
    
        /**
         * hi from student alice
         */
        val person: Person17 = new Student17("alice", 18)
        person.sayHi()
    
        /**
         * 类型判断
         * student is Student17: true
         * student is Person17: true
         * person is Person17: true
         * person is Student17: true
         */
        println("student is Student17: " + student.isInstanceOf[Student17])
        println("student is Person17: " + student.isInstanceOf[Person17])
        println("person is Person17: " + person.isInstanceOf[Person17])
        // 体现多态
        println("person is Student17: " + person.isInstanceOf[Student17])
    
    
        val person2: Person17 = new Person17("alice", 18)
    
    
        /**
         * person is Person17: true
         * person is Student17: false
         */
        println("person is Person17: " + person2.isInstanceOf[Person17])
        println("person is Student17: " + person2.isInstanceOf[Student17])
    
    
        // 类型转换
        if (person.isInstanceOf[Student17]) {
          val newStudent: Student17 = person.asInstanceOf[Student17]
          newStudent.study()
        }
    
        println(classOf[Student17])
    
    
      }
    
    }
    
    class Person17(val name: String, val age: Int) {
      def sayHi(): Unit = {
        println(s"hi from person $name")
      }
    }
    
    class Student17(name: String, age: Int) extends Person17(name = name, age = age) {
      override def sayHi(): Unit = {
        println(s"hi from student $name")
      }
    
      def study(): Unit = {
        println(s"student $name is study")
      }
    }
    
    

你可能感兴趣的:(scala,scala,开发语言,后端)