zoukankan      html  css  js  c++  java
  • Scala面向对象

    补充:Scala中class和object区别

    (一)class

    calss scala编译器会字段帮我们生产一个私有字段和2个公有方法get和set

    scala 中没有 static 关键字,所以 对于一个class来说,所有的方法和成员变量在实例被 new 出来之前都是无法访问的

    因此在class中的main方法没什么用了

    (二)object

    scala 的object 中所有成员变量和方法默认都是 static 的

    所以可以直接访问main方法

    一:类的定义

    注意:默认变量时public,但是只能写private和protected两种修饰符

    注意:默认在类中声明变量是,静态变量,需要我们进行初始化操作

    package ClassBase
    
    class UserInfo{
      //对应var变量,可以设置setter和getter
      private var Name:String="aaa"
      private var Age:Int=20;
      //对应val常量,只可以设置getter
      private val Addr:String="china"
      
      def setName(name:String)= this.Name=name
      def getName()= this.Name
      
      def setAge(age:Int)= this.Age=age
      def getAge()= this.Age
      
      def getAddr()= this.Addr
    }
    
    object User {
      def main(args:Array[String]):Unit={
        var user=new UserInfo
        println(user.getName()+"	"+user.getAge()+"	"+user.getAddr())
        
        user.setAge(10)
        user.setName("aggw")
        println(user.getName()+"	"+user.getAge()+"	"+user.getAddr())
      }
    }

    注意:允许类中包含内部类 

    二:类的构造器

    分为两种:主构造器和辅助构造器

    (一)主构造器

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

    //主构造器
    class Stu(var StuName:String,var StuAge:Int){
      
    }
    
    object User {
      def main(args:Array[String]):Unit={
        var s = new Stu("aaa",12)
        println(s.StuName+"	"+s.StuAge);
      }
    }

    (二)辅助构造器

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

    package ClassBase
    
    class UserInfo{
      //对应var变量,可以设置setter和getter
      private var Name:String="aaa"
      private var Age:Int=20
      //对应val常量,只可以设置getter
      private val Addr:String="china"
      
      def setName(name:String)= this.Name=name
      def getName()= this.Name
      
      def setAge(age:Int)= this.Age=age
      def getAge()= this.Age
      
      def getAddr()= this.Addr
    }
    
    //主构造器
    class Stu(var StuName:String,var StuAge:Int){
      private var StuAddr:String=""
      //辅助构造器
      def this(name:String){
        this(name,20)
      }
    }
    
    object User {
      def main(args:Array[String]):Unit={
        //主构造器
        var s = new Stu("aaa",12)
        println(s.StuName+"	"+s.StuAge);
        
        //辅助构造器
        var s_2 = new Stu("ge")
        println(s_2.StuName+"	"+s_2.StuAge);
      }
    }

    三:单例对象

    在Scala中,单例对象分为两种,一种是并未自动关联到特定类上的单例对象,称为独立对象(Standalone Object);

    另一种是关联到一个类上的单例对象,该单例对象与该类共有相同名字,则这种单例对象称为伴生对象(Companion Object),对应类称为伴生类。

    (一)单例对象(独立对象 )

    Scala单例对象是十分重要的,没有像在Java一样,有静态类、静态成员、静态方法,但是Scala提供了object对象,这个object对象类似于Java的静态类,它的成员、它的方法都默认是静态的。

    注意:如果object的静态成员要被外界访问,则该成员不能被private修饰

    object People{
      var users = new ArrayBuffer[String]()
      
      def addUser(user:String){
        println(s"add user ${user}")
        users += user
      }
      
      def getUsers(){
        for(u<-users)println(u)
      }
    }
    
    object ObjTest{
      def main(args:Array[String]):Unit={
        var user1 = People
        var user2 = People
        user1.addUser("aaa")
        user2.addUser("bbb")
        println("--------------")
        user1.getUsers()
        println("--------------")
        user2.getUsers()
      }
    }

    (二)单例对象(伴生对象 )

     如果有同样一个类与该object名字一样,则称该object为该类的伴生对象,相对应,该类为object的伴生类。如果一个类有它的伴生对象,这个类就可通过object的名字访问到所有成员。

    class People{
      var users = new ArrayBuffer[String]()
      //People.newId+=1
      var newId = {
        People.id
      }
      
      def addUser(user:String){
        newId+=1
        println(s"add user ${user}   ${newId}")
        users += s"${user}  ${newId}"
      }
      
      def getUsers(){
        for(u<-users)println(u)
      }
    }
    
    object People{
      private var id = 0
    
      private var obj:People = _  //下划线为默认值,为空
      
      def apply()={
        if(obj==null){
          obj=new People
          obj
        }else{
          obj
        }
      }
    }
    
    object ClassTest{
      def main(args:Array[String]):Unit={
        var p = People()
        var p2=People()
        p.addUser("aaa")
        p2.addUser("ffff")
        p.getUsers()
        p2.getUsers()
      }
    }

    注意:apply方法

    apply是Scala的一种语法,在遇到形如object(arg1,arg2....argN)这样的表达式时,apply方法就会被调用
    apply方法需要定义在伴生对象中

    注意:当object和class同时出现时,会去访问object,而不是去访问class。所以实现的单例模式无歧义

    伴生对象与伴生类在Scala的面向对象编程方法中占据极其重要的位置,例如Scala中许多工具方法都是由伴生对象提供的。

    总之:就是将静态成员和静态方法,全部独立到object,没有其他较大差别

    补充:Scala 中 _ 代表什么

    Scala中“_”代表什么

    四:类继承extends

    Scala跟Java一样,是单继承,所以子类只能有一个父类

    下面的例子中,子类Employee重写了Person类的字段,所以在重写的部分前使用了override关键字,extends后面也加上了重写的字段。同时还重写了父类的sayHello方法,所以在重写的方法前也使用了override关键字.
    而对象p3则是在main方法中通过父类实例化的,这种叫做匿名子类,而且通过重写父类的方法我们可以看到效果

    class Parent(val name:String,val age:Int){
      def say()={
        s"父类调用函数"
      }
    }
    
    class Child(override val name:String,override val age:Int,val addr:String)extends Parent(name,age){
      override def say()={
        s"子类调用函数"
      }
    }
    
    object ClassTest{
      def main(args:Array[String]):Unit={
        var p1:Parent = new Parent("aaa",22)
        println(p1.say())
        
        var p2:Parent = new Child("bbb",3,"g")
        println(p2.say())
        
        var p3:Parent = new Parent("ccc",43){
          override def say()={
            s"匿名子类调用函数"
          }
        }
        println(p3.say())
      }
    }

    五:抽象类abstract

    抽象类包含抽象字段(没有初始值的字段)抽象方法(即没有方法体的方法),且抽象类只能用于继承。子类在继承抽象类的时候,必须实现所继承的类的抽象方法。抽象类可以用来实现简单工厂模式。

    abstract class Animal{
      var Name:String        //成员变量不能初始化
      def getInfo():String   //方法不能实现
    }
    
    class Dog extends Animal{
      var Name:String="dog"  //必须设置一个值
      
      def getInfo():String={
        s"this is a ${Name}"
      }
    }
    
    object ClassTest{
      def main(args:Array[String]):Unit={
        var anm:Animal = new Dog
        println(anm.getInfo())
      }
    }

    六:特质(接口)Trait

    Scala Trait本质上就是抽象类,但Trait支持多继承,相当于Java的接口,但比接口更强大,因为它可以定义抽象方法或方法。
    如果要继承多个特质,只要加上with 特质名就可以了。

    abstract class Animal{
      var Name:String        //成员变量不能初始化
      def getInfo():String   //方法不能实现
    }
    
    trait A{
      def getInfo1():String
    }
    
    trait B{
      def getInfo2():String={
        s"trait B getInfo"
      }
    }
    
    class Dog extends Animal with A with B{
      var Name:String="dog"  //必须设置一个值
      
      def getInfo():String={
        s"this is a ${Name}"
      }
      
      def getInfo1():String={
        s"trait A getInfo"
      }
    }
    
    
    object ClassTest{
      def main(args:Array[String]):Unit={
        var anm:Dog = new Dog
        println(anm.getInfo())
        println(anm.getInfo1())
        println(anm.getInfo2())
      }
    }

    七:包的使用

    Scala的包和Java中的包或者C++中的命名空间的目的是相同的:管理大型程序中的名称
    Scala中的包可以像Java一样使用,包里包含所建立的类,而且Package是可以嵌套的
    Scala中依然使用import作为引用包的关键字,如import com.my.io._可以引用com.my.io下的所有类型,import com.my.io.xxx._可以引用com.my.io.xxx的所有成员
    而且Scala中的import可以写在任意地方,而Java中的import写在最前面
    包可以包含类、对象、特质,但不能包含函数或者变量的定义,这是JVM的限制,而Scala中的包对象可以包含常量、变量、方法、类、对象、特质、包

  • 相关阅读:
    java线程学习之volatile关键字
    java线程学习之yield方法
    java线程学习之join方法
    小程序hideTarBar隐藏TabBar后,获取windowHeight不准确问题
    canvas等base64格式上传到服务端直传到oss
    服务器关于node的注意事项
    node.js连接本地数据库
    小程序(mpvue框架)的总结
    git代码的注意
    js里的实用小技巧
  • 原文地址:https://www.cnblogs.com/ssyfj/p/12452312.html
Copyright © 2011-2022 走看看