美文网首页
scala面向对象

scala面向对象

作者: 初夏时的猫 | 来源:发表于2021-12-12 11:56 被阅读0次

    一.包嵌套
    ( 1)一个源文件中可以声明多个 package
    ( 2)子包中的类可以直接访问父包中的内容,而无需导包
    ( 3)包对象:在 Scala 中可以为每个包定义一个同名的包对象, 定义在包对象中的成员, 作为其对
    应包下所有 class 和 object 的共享变量, 可以被直接访问。
    ( 4)导包说明

    图片.png

    (1)scala里的setget: @BeanPropetry

        class Person {
          var name: String = "bobo" //定义属性
          var age: Int = _ // _表示给属性一个默认值
          //Bean 属性( @BeanProperty)
          @BeanProperty var sex: String = "男"
          //val 修饰的属性不能赋默认值,必须显示指定
        }
    

    封装

    一.概念
    Scala 中的 public 属性,底层实际为 private,并通过 get 方法( obj.field())和 set 方法
    ( obj.field_=(value))对其进行操作。所以 Scala 并不推荐将属性设为 private,再为其设置
    public 的 get 和 set 方法的做法。但由于很多 Java 框架都利用反射调用 getXXX 和 setXXX 方
    法,有时候为了和这些框架兼容,也会为 Scala 的属性设置 getXXX 和 setXXX 方法(通过
    @BeanProperty 注解实现)

    二.访问权限

    ( 1) Scala 中属性和方法的默认访问权限为 public,但 Scala 中无 public 关键字。
    ( 2) private 为私有权限,只在类的内部和伴生对象中可用。
    ( 3) protected 为受保护权限, Scala 中受保护权限比 Java 中更严格,同类、子类可以
    访问,同包无法访问

    ( 4) private[包名]增加包访问权限,包名下的其他类也可以使用

    对象

    1.自动推导变量类型不能多态,所以多态需要显示声明(?)

    2.构造器:Scala包括主构造器和辅助构造器。
    注:辅助构造器不能直接构建对象,必须直接或间接调用主构造方法。

    3.构造器里的三种参数设置

    class Test(name:String,var age:Int,val sex:String) {
      /*
      * name:局部变量
      * age:成员变量
      * sex:只读成员变量
      * */
      var name1:String = name
    }
    

    继承和多态

    1.scala中属性和方法都是动态绑定

          class a{
            val name:String = "a"
            def hello(): Unit = {
              println("hello a")
            }
          }
          class aSon extends a{
            override val name:String = "aSon"
            override def hello(): Unit = println("hello b")
          }
          object Test{
            def main(args: Array[String]): Unit = {
              var aa = new aSon
              println(aa.name)
              aa.hello()
            }
          }
    

    输出是:aSon ,hello b。如果是java,输出是a,hello b

    抽象类

    1.重写非抽象方法需要用 override 修饰,重写抽象方法则可以不加 override
    2.子类中调用父类的方法使用 super 关键字
    3.子类对抽象属性进行实现,父类抽象属性可以用 var 修饰;子类对非抽象属性重写,父类非抽象属性只支持 val 类型,而不支持 var。
    因为 var 修饰的为可变变量,子类继承之后就可以直接使用,没有必要重写(但是写var不会报错)

    匿名子类

                    //Person是抽象类
        val person = new Person {
        override val name: String = "teacher"
        override def hello(): Unit = println("hello teacher")
    

    单例对象(伴生对象)

    Scala语言是完全面向对象的语言, 所以并没有静态的操作( 即在Scala中没有静态的概
    

    念) 。但是为了能够和Java语言交互(因为Java中有静态概念),就产生了一种特殊的对象
    来模拟类对象, 该对象为单例对象。若单例对象名与类名一致,则称该单例对象这个类的伴
    生对象,这个类的所有“静态” 内容都可以放置在它的伴生对象中声明。

    说明

    ( 1)单例对象采用 object 关键字声明

    ( 2)单例对象对应的类称之为伴生类,伴生对象的名称应该和伴生类名一致。

    ( 3)单例对象中的属性和方法都可以通过伴生对象名(类名)直接调用访问。

    **apply方法**
    

    ( 1)通过伴生对象的 apply 方法, 实现不使用 new 方法创建对象。

    ( 2)如果想让主构造器变成私有的,可以在()之前加上 private。

    ( 3) apply 方法可以重载。

    ( 4) Scala 中 obj(arg)的语句实际是在调用该对象的 apply 方法,即 obj.apply(arg)。用
    以统一面向对象编程和函数式编程的风格。

    ( 5)当使用 new 关键字构建对象时,调用的其实是类的构造方法,当直接使用类名构
    建对象时,调用的其实时伴生对象的 apply 方法。

    特质(接口)

    基础
    1.所有的 Java 接口都可以当做 Scala 特质使用
    2.动态混入:可灵活的扩展类的功能

        val t2 = new Teacher with SexTrait {
                      override var sex: String = "男"
        }
        println(t2.sex)
    

    特质叠加
    第一种,一个类( Sub)混入的两个 trait( TraitA, TraitB)中具有相同的具体方法,且两个 trait 之间没有任何关系,解决这类冲突问题,直接在类( Sub)中重写冲突方法

    图片.png

    第二种,一个类( Sub)混入的两个 trait( TraitA, TraitB)中具有相同的具体方法,且两个 trait 继承自相同的 trait( TraitC),及所谓的“钻石问题”,解决这类冲突问题, Scala采用了特质叠加的策略。


    图片.png

    注:特质叠加顺序

    图片.png

    特质自身类型

    使用_:Name(with Name)=>this:Name(with Name)=> 将Name类/接口/特质注入

    class User(val name: String, val age: Int)
    class Dao {
      def insert(user: User) = {
        println("insert into database :" + user.name)
      }
    }
    trait APP {
      _: Dao =>
      def login(user: User): Unit = {
        println("login :" + user.name)
        insert(user)
      }
    }
    object MyApp extends Dao with APP{
      def main(args: Array[String]): Unit = {
        login(new User("bobo", 11))
    
      }
    }
    

    特质和抽象类的区别

    1.优先使用特质。一个类扩展多个特质是很方便的,但却只能扩展一个抽象类。

    2.如果你需要构造函数参数,使用抽象类。因为抽象类可以定义带参数的构造函数,
    而特质不行( 有无参构造)

    **类型检查和转换
    ( 1) obj.isInstanceOf[T]:判断 obj 是不是 T 类型。
    ( 2) obj.asInstanceOf[T]:将 obj 强转成 T 类型。
    ( 3) classOf 获取对象的类名。

    val pClass: Class[Person] = classOf[Person]
    

    枚举类和应用类

    // 枚举类
    object Color extends Enumeration {
    val RED = Value(1, "red")
    val YELLOW = Value(2, "yellow")
    val BLUE = Value(3, "blue")
    }
    // 应用类
    object test extends App {
    //不用main方法就能执行
    println(Color.RED)
    }
    

    type定义类型
    就是给原有类型换个名

      type S = String
      var v:S = "aa"
       //true
      println(v.isInstanceOf[String])
      var v1:String = "aa"
    //true
     println(v1.isInstanceOf[S])
    

    相关文章

      网友评论

          本文标题:scala面向对象

          本文链接:https://www.haomeiwen.com/subject/avulfrtx.html