zoukankan      html  css  js  c++  java
  • Scala的基本语法(四):面向对象基本

    面向对象基本

    类与对象

    面试题

    java scala的区别

    ​ 1) Java是面向对象的编程语言,由于历史原因,Java中还存在着非面向对象的内容:基本类型(int,float…) ,null,静态方法等(object 替代)。

    ​ 2) Scala语言来自于Java,所以天生就是面向对象的语言,而且Scala是纯粹的面向对象的语言,即在Scala中,一切皆为对象。

    Scala对象创建对象流程分析

    ​ 1) 加载类的信息(属性信息和方法信息)
    ​ 2) 在内存中(堆)给对象开辟空间
    ​ 3) 使用父类的构造器(主构造器/辅助构造器)完成父类的初始化 (多个父类)
    ​ 4) 使用本类的主构造器完成初始化( age = 90 name = “null”)
    ​ 5) 使用本类的辅助构造器继续初始化(age =20,name = “小倩”)
    ​ 6) 将对象在内存中的地址赋给 p 这个引用

    总结

    • scala 中的object是单例对象,相当于java中的工具类,可以看成是定义静态的方法的类。object不可以传参数。另:Trait不可以传参数
    • 类不能声明为public,默认就是public
    • 属性的定义类型可以为任意类型,包含值类型或引用类型,属性必须显示的初始化。若暂时不赋值,也可以必须给定数据类型,使用符号_(下划线),让系统分配默认值
    • 如果赋值为null,则一定要加类型,因为不加类型, 那么该属性的类型就是Null类型
    • scala中的class类默认可以传参数,默认的传参数就是默认的构造函数。重写构造函数的时候,必须要调用默认的构造函数。
    • 使用object时,不用new,使用class时要new ,并且new的时候,class中除了方法不执行,其他都执行。
    • 如果在同一个文件中,object对象和class类的名称相同,则这个对象就是这个类的伴生对象,这个类就是这个对象的伴生类。可以互相访问私有变量。
    • 伴生对象的功能特性并不在类的作用域内,如类无法直接使用伴生对象的方法 必须加类名

    构造器

    • Scala构造器作用是完成对新对象的初始化,构造器没有返回值,会执行除方法外的所有语句

    • 多个辅助构造器通过不同参数列表进行区分, 在底层就是构造器重载,辅助构造器无论是直接或间接,最终都一定要调用主构造器

    • 如果想让主构造器变成私有的,可以在()之前加上private,这样用户不能直接通过主构造器来构造对象了class C private(){}

    • <父类如果没有空参构造方法 子类继承时要传入参数,如自定义Spark数据源receiver

    • 构造器

      class Person2(name: String) {
      public Person2(String name) {}  //在底层实现 
      }
      
    • 可以把主构造器设置为有参 辅助构造器为def this()空参,在定义中调用有参主构造器,这样子类继承时可以继承空参的父类。

    • 可以将子类参数传递给继承的父类构造器

      class Emp (name:String) extends Person(name){}//class Person(name:String)是父类构造器,子类又可以继承父类的name
      
    构造器参数
    1. 如果Scala类的主构造器的形参未用任何修饰符修饰,这个参数将升级为字段(或局部变量),如果没有方法使用,则没有改字段。

    2. 如果参数使用val关键字声明,那么Scala会将参数作为类的私有的只读属性使用

    3. 如果参数使用var关键字声明,那么那么Scala会将参数作为类的成员属性使用,并会提供属性对应的xxx()[类似getter]/xxx_$eq()[类似setter]方法,即这时的成员属性是私有的,但是可读写。


    修饰符

    • 没有修饰符的var变量,在编译时会被声明为private类型,但提供公共的get和set方法,即name,name_=

    • 没有修饰符的val变量,在编译时会被声明为private类型,但只提供公共的get方法

    • 使用private修饰的var变量.只有私有的get与set,如需访问,需要自定义get与set

    • 使用private[this]修饰的var变量,为对象所私有,同一个类的不同对象不能相互访问该属性,也就是对象隔离级

    • @BeanProperty 生成java风格的get与set 以及默认的

      scala 访问控制底层实际只用了两种修饰符: private public 。不管变量是否是private ,scala先将其定义成private属性,如果允许外界访问(如未定义private var),getter setter方法就会被设置成public,否则(如加了private var或者作为主构造器的参数)getter setter被设置为private 或者没有getter(private val)等。(protect例外 即便底层是public)

    • 虽然scala的变量定义是底层都是private修饰的, 但如果父类private def修饰的的方法及public的getter setter方法,子类仍然可以通过调用父类的getter setter,来获取修改继承自父类的private修饰的属性。

    val 变量

    private final int val_val = 18;
    public int val_val() { return this.val_val; }
    

    var 变量

     private String var_var = "coder";
     public String var_var() { return this.var_var; } 
     public void var_var_$eq(String x$1) { this.var_var = x$1; } 
    

    private val 变量

     private final int age;  // final修饰
     private int age() { return this.age; } 
    

    private var 变量

     private String pri_var = "private var";
     private String pri_var() { return this.pri_var; }      //pri_var
     private void pri_var_$eq(String x$1) { this.pri_var = x$1; }   //pri_var._方法
    

    @BeanProperty val

     private final String BeanP_val = "@BeanProperty val";   //得到2个方法
     public String BeanP_val() { return this.BeanP_val; } 
     public String getBeanP_val() { return BeanP_val(); }
    

    @BeanProperty var

    //@BeanProperty var adress="beijing"   //得到4个方法 
     private String adress = "beijing";
     public String adress() { return this.adress; } 
     public void adress_$eq(String x$1) { this.adress = x$1; } 
     public void setAdress(String x$1) { this.adress = x$1; } 	//setter
     public String getAdress() { return adress(); }		//getter
    

    无任何修饰的参数 无方法引用 class Person(name:String,age:Int)

    class Person(name:String,age:Int)
    --------------------------------------------------
    public Person(String name, int age){}  //源码中升级为字段 如果没有方法使用,则没有该字段
    

    无任何修饰的参数 有方法引用

     class Person(name:String,age:Int) def sellHello: Unit ={println(name+Int)  } //以默认public方法为例
    --------------------------------------------------
     private final String name; //因为是final 子类无法继承
     public void sellHello() { 
     Predef..MODULE$.println(new StringBuilder().append(this.name).append(Int..MODULE$).toString());
    }
    

    包的使用

    1. 包也可以像嵌套类那样嵌套使用(包中有包), 这个在前面的第三种打包方式已经讲过了,在使用第三种方式时的好处是:程序员可以在同一个文件中,将类(class / object)、trait 创建在不同的包中,这样就非常灵活了。[案例+反编译] / 案例参考前面的即可。

    2. 作用域原则:可以直接向上访问。即: Scala中子包中直接访问父包中的内容, 大括号体现作用域。(提示:Java中子包使用父包的类,需要import)。在子包和父包 类重名时,默认采用就近原则,如果希望指定使用某个类,则带上包名即可。

    3. 父包要访问子包的内容时,需要import对应的类等

    4. 可以在同一个.scala文件中,声明多个并列的package(建议嵌套的pakage不要超过3层)

    5. 包名可以相对路径也可以绝对路径,比如,访问BeanProperty的绝对路径是:
      root. scala.beans.BeanProperty ,在一般情况下:我们使用相对路径来引入包,只有当包名冲突时,使用绝对路径来处理

    引入包

    import语句可以出现在任何地方,import语句的作用一直延伸到包含该语句的块末尾。这种语法的好处是:在需要时在引入包,缩小import 包的作用范围,提高效率

    1. Java中如果想要导入包中所有的类,可以通过通配符*,Scala中采用下 _

    2. 如果不想要某个包中全部的类,而是其中的几个类,可以采用选取器,使用{} 括起来即可。

    3. 如果引入的多个包中含有相同的类,那么可以将类进行重命名进行区分,这个就是重命名。

    包对象

    ​ 包可以包含类、对象和特质trait,但不能包含函数/方法或变量的定义。这是Java虚拟机的局限。为了弥补这一点不足,scala提供了包对象的概念来解决这个问题。

    1)每个包都可以有一个包对象。你需要在父包中定义它。

    1. 包对象名称需要和包名一致,一般用来对包的功能补充

    2. 当属性访问权限为默认时,从底层看属性是private的,但是因为提供了xxx_$eq()[类似setter]/xxx()[类似getter] 方法,因此从使用效果看是任何地方都可以访问)

    3. 当方法访问权限为默认时,默认为public访问权限

    4. private为私有权限,只在类的内部和伴生对象中可用 【案例演示】

    5. protected为受保护权限,scala中受保护权限比Java****中更严格,只能子类访问同包无法访问 (编译器从语法层面控制)

    6. 在scala中没有public关键字,即不能用public显式的修饰属性和方法。【案演】

    7. scala设计者将访问的方式分成三大类:

    ​ (1) 处处可以访问public (2) 子类和伴生对象能访问protected (3) 本类和伴生对象访问 private

    1. 包访问权限(表示属性有了限制。同时包也有了限制),这点和Java不一样,体现出Scala包使用的灵活性。 当然,也可以将可见度延展到上层包private[atguigu] val description="zhangsan"说明:private也可以变化,比如protected[atguigu], 非常的灵活.

    在这里插入图片描述


  • 相关阅读:
    springmvc
    POJ 3683 Priest John's Busiest Day
    POJ 3678 Katu Puzzle
    HDU 1815 Building roads
    CDOJ UESTC 1220 The Battle of Guandu
    HDU 3715 Go Deeper
    HDU 3622 Bomb Game
    POJ 3207 Ikki's Story IV
    POJ 3648 Wedding
    HDU 1814 Peaceful Commission
  • 原文地址:https://www.cnblogs.com/successok/p/14737327.html
Copyright © 2011-2022 走看看