伴生类和伴生对象object相当于Java中的" />

Scala 学习之面向对象(3)

发布时间:2019-09-03 09:11:54编辑:auto阅读(1303)

    ==> 类

            ---> 类的定义

    class Student{
        // 定义属性
        private var stuName:String = "Tom"
        private vat stuAge:Int = 18
        
        // 定义方法
        def getStuName():String = stuName
        def setStuName(newName:String) = {
            this.stuName = newName
        }
        
        
    }


            ---> 伴生类和伴生对象    object 相当于 Java 中的 static

                ---- object 对象可以跟类名不一样,如果跟类名一样,这个对象就是该类的伴生对象,反之,这个类就是这个伴生对象的伴生类

            ---> set 和 get 方法  

                ---- Scala 中,会自动给 private 定义的属性生成get和set 方法,使用 val 可以使其只生成 get 方法,而不会生成set 方法

                ---- 在定义变量时使用 this 关键字,可以使其成为此类的私有属性,不会生成 get 和 set 方法,如:

     // 定义正常的属性,可自动生成get 和 set  方法
     private var aaa:String = "hello"
     
     // 定义只可自动生成 get 方法的属性
     private val aaa:String = "hello"
     
     // 使用this 关键字,使其定义的属性成为此类的私有属性,不允许外界访问
     private[this] var aaa:String = "hello"


            ---> 嵌套类(内部类)

                ---- 内部类中的参数可以当做类的参数传递

            ---> 类的构造器

                ---- 主构造器 和类的声明在一起,只能有一个主构造器

    class Student(val stuName: String, val stuAge: Int){
    
    }
    
    object Student{
        def main(args: Array[String]): Unit = {
            var stu = new Student("Tom", 20)
            println(stu.stuName + "\t" + stu.stuAge)
        }
    }


                ---- 辅助构造器  可以有多个辅助构造器,使用 this 关键字

    class Student(val stuName:String, val stuAge:Int){
        // 定义一个辅助构造器
        def this(age:Int){
        // 调用主构造器
        this("No Name", age)
        }
    }
    
    object Student{  // 
        var stu = new Student(22)
        println(stu.stuName + "\t" + stu.stuAge)
    }    // 输出结果为 NoName   22


            ---> Object 对象: 相当于 Java 中的 static 关键字

                ---- 单例模式: 一个类只有一个对象

    // 生成信用卡的卡号
    object CreditCard{
        // 定义变量: 保存信用卡的卡号
        // 该属性只属于该对象 
        private[this] var creditCardNumbe:Long = 0
        
        // 产生卡号
        def generateNewCCNumber():Long = {
            creditCardNumbe += 1
            creditCardNumber
        }
        
        // 测试程序
        def main(args:Array[String]): Unit = {
        // 得到新的卡号
            println(CreditCard.generateNewCCNumber)
            println(CreditCard.generateNewCCNumber)
            println(CreditCard.generateNewCCNumber)
            println(CreditCard.generateNewCCNumber)
        }
    }


                ---- 应用程序对象: App   ----- 可以省略 main 方法

    object testApp extends App {
        // 省略了 main 方法,可以直接将结果输出
        println("hello")
    }

            ---> 类的 apply 方法

                ---- 作用: 创建对象时,省略 new 关键字,需要定义在类的伴生对象中

    class Student(stuName:String){
    
    }
    
    object Student{
        // 定义 apply 方法,必须定义在类的伴生对象中
        def apply(stuName: String) = {
            // 调用主构造器
            new Student(stuName)
        }
        def main(args: Array[String]): Unit = {
            var stu = Student("Tom")
        }
    }

    ==> 继承

            ---> 简单继承

    // 测试
    object DemoExtends{
      def main(args: Array[String]): Unit = {
        // 创建一个 Person 对象
        val p1:Person = new Person("Tom", 20)
        println(p1.sayHello())            // My name is Tom,age is 20
    
        // 创建一个子类
        val p2:Person = new Employee("Marry", 32, 1233)
        println(p2.sayHello())            // 子类中的 sayHello
    
        // 创建一个匿名子类
        val p3:Person = new Person("Jerry", 33){
          override def sayHello(): String = "匿名函数中的 sayHello 方法"
        }
        println(p3.sayHello())            // 匿名函数中的 sayHello 方法
      }
    }
    // 父类
    class Person(val name:String, val age:Int){
      def sayHello():String = "My name is " + name + ",age is " + age
    }
    
    // 子类    如果需要子类的值覆盖父类的值,需要加上 override 参数
    class Employee(override val name:String, override val age:Int, val salary:Int) extends Person(name, age){
      override def sayHello(): String = "子类中的 sayHello"
    }

            ---> 继承抽象类和抽象字段

    object TestExtendsDemo {
      def main(args: Array[String]): Unit = {
        var apple:Fruit = new Apple()
        var orange:Fruit = new Orange()
    
        println(apple.name())        // 结果为 apple
        println(orange.name())        // 结果为 orange
    
      }
    }
    
    abstract class Fruit{
      var id:Int
      def name():String
      
    }
    
    class Apple extends Fruit{
       // 实现抽象字段
       var id:Int = 1
      // 实现抽象方法
      def name():String = {
        "apple"
      }
    
    }
    
    // 可以通过构造方法对抽象字段进行处理
    class Orange() extends Fruit{
      def name:String = {
        "orange"
      }
    
    }

            ---> 特质trait: 有点像接口,也有点像抽象类    支持多重继承,可以定义抽象方和字段,也可以定义完整的方法和字段

    object Demo1 {
    
      def main(args: Array[String]): Unit = {
        var com:Computer = new Computer(1)
        println(com.run())
        println(com.movedown())
      }
    
    }
    
    class Computer(var monitorid:Int) extends Monitor with Mouse with Keyboard {
      def run():String = {
        "running"
      }
    
      def moveup(): String = {
        "moveup"
      }
    
      override def movedown(): String = {
        "movedown"
      }
    
      override def press(): String = {
        "press"
      }
    
    }
    
    trait Monitor{
      var monitorid:Int
      def run():String
    
    }
    
    trait Mouse{
      def moveup():String
      def movedown():String
    }
    
    trait Keyboard{
      def press():String
    }


    ==> 包的定义和使用

            ---> 包的定义:

    // 定义格式一
    package com.mytest
    class Demo{}
    
    // 定义格式二
    package com.mytest{
        class Demo{}
    }


            ---> 包的使用(引入):

    import com.mytest.Demo        // 可以不写Demo 的全路径
    import com.mytest._            // 引入mytest 包下所有的属性
    import com.mytest.Demo._        // 引入 Demo 类中所有的属性


    ==> 包对象

    package object MyPackageDemo{
        // 常量
        val a:Int = 1
        // 变量
        var a:String = "hello"
        // 方法
        def Demo():String = {
            "Demo"
        }
        // 类
        class Demo{
            
        }
        // 对象 object
        object Demo{
        
        }
        // trait(特质)
        trait Demo{
        
        }
    }



关键字