• Scala之面向对象


    1. Scala基础练习

    1. 不使用str.toLong,str.toInt/Integer.valueOf()/Long.valueOf/Integer.parseInt()等,将字符串"123456789" 转化成数字123456789

      def method3(): Unit = {
         val str = "123456789"
         var sum = 0L
         for(ch <- str) {//字符串本身就是一个字符数组
             sum = sum * 10 + (ch - '0')
        }
         println(sum)

         str.toCharArray.map(ch => ch - '0').reduce((v1, v2) => v1 * 10 + v2)
      }
    2. 使用scala完成选择排序

         def main(args: Array[String]): Unit = {
            val array = Array(1, 5, 3, 5, 6, 7, 2, 9)
            println("排序前的数组:" + array.mkString("[", ", ", "]"))
            selectSort(array)
            println("排序后的数组:" + array.mkString("[", ", ", "]"))
        }
        /**选择排序
          *
          */
        def selectSort(arr:Array[Int]): Unit = {
            for(i <- 0 until arr.length) {
                for (j <- i until arr.length) {
                    if(arr(i) > arr(j)) {
                        swap(arr, i, j)
                    }
                }
            }
        }
        /*
            位运算 ^ 相同为0,反之为1
            a=3 b=5
            a=0011
            b=0101
            a= a^b =0110
                    0101
            b= a^b =0011=3
                    0110
            a= a^b= 0101=5
            这里没有使用第三方变量完成两个数字的交换,其中使用^与那孙效率最高
         */
        def swap(arr:Array[Int], i:Int, j:Int): Unit = {
            /*arr(i) = arr(i) ^ arr(j)
            arr(j) = arr(i) ^ arr(j)
            arr(i) = arr(i) ^ arr(j)*/
            arr(i) = arr(i) + arr(j)
            arr(j) = arr(i) - arr(j)
            arr(i) = arr(i) - arr(j)
        }
    3. 使用scala完成二分查找

      在一个有序数组中找到某一个值,如果存在,返回索引,没有返回-1或者返回如果存在,应该在的位置
      def binarySearch(arr:Array[Int], key:Int):Int = {
            var start = 0
            var end = arr.length - 1
            while(start < end) {
                val mid = (start + end) / 2
                if (key < arr(mid)) {
                    //左边
                    end = mid - 1
                } else if (key > arr(mid)) {
                    //又变
                    start = mid + 1
                } else {
                    return mid
                }
            }
            return -(start + 1)
        }

       

    2. scala面向对象

    2.1. 类的基本操作

    2.1.1. 类的创建与对象的构造

    * 定义scala中的类使用关键字class
    *     1、定义scala中的任意一种结构,都不可以使用public关键字修饰,因为scala中没有public关键字
    *         不加任何访问权限修饰符就相当于java中的public
    *     2、类中可以定义成员信息
    *         成员变量
    *         成员方法
    *     3、创建类的实例--对象
    *         在scala中和java中是一样,都使用关键字new来构建类的实例
    object ClassOps {
       def main(args: Array[String]): Unit = {
           val p:Person = new Person()
           p.name = "刘梦男"
           p.age = 18
           p.show()
      }
    }

    class Person {
       var name:String = _
       var age:Int = _

       def show(): Unit = {
           println(s"name: ${name} age: ${age}")
      }
    }

    2.1.2. 成员变量的封装getter和setter

    *     4、scala没法直接为成员变量提供getter和setter方法,只能自己编写
    *         scala做了一种尝试,通过注解(@BeanProperty)的方式来给成员变量提供getter和setter,
    *         前提是该getter或者setter不能被private修饰,此时数据的安全性无法得到保证
    *
    *     5、这个getter和setter的的使用其实javabean中的规范,javabean的主要作用是什么?
    *         封装、传递数据
    *         javaee
    *             dao
    *             service
    *             web
    *             domain
    *                 Person
    *                 Order
    *                 Cat
    *                 OrderItem
    *                 Category
    object ClassOps {
       def main(args: Array[String]): Unit = {
           val p:Person = new Person()
    //       p.name = "liumengn"
    //       p.age = 18

           p.setName("liwei")
           p.setAge(-2)
           p.setSalary(123.0f)
           p.show()
      }
    }

    class Person {
       private var name:String = _
       private var age:Int = _

       @BeanProperty var salary:Float = _
       def setName(n:String) = {
           name = n //单行函数
      }

       def getName = name

       def setAge(a:Int) = {
           if(a < 0) {
               throw new RuntimeException("what are you fucking 赋值!")
          }
           age = a
      }

       def getAge = age

       def show(): Unit = {
           println(s"name: ${name} age: ${age}")
      }
    }

    2.1.3. case class模拟javabean

    /*
        在scala中一般不用这些普通的class类进行封装数据、传递数据,那用什么呢?
     *         case class样例类
     *             作用就相当于java bean
     *   case class的定义非常简单,在class关键字的前面加上另外一个关键字case即可
     *  
     *   样例类的定义必须要有一个参数列表---->构造器,
     *   case class的应用是非常广泛的,但凡数据的传递,一般都用case class
    */
    object _02CaseClassOps {
       def main(args: Array[String]): Unit = {
    val category = Category(1, "手机")
           println(category.id)
           println(category.name)
      }
    }
    //定义了一个case class Category
    case class Category(id:Int, name:String)

    2.1.4. scala类的构造器

    *  2、构造器:
    *     按照java中的知识,val stu = new Student是使用Student类的无参构造器创建对象
    *     在一个类中,如果局部变量和成员变量名发生冲突,便通过给成员变量加this关键字进行区分
    *  3、如何定义构造器:
    *        尝试使用def Student(name:String, age:Int)定义构造器,
    *        调用的时候:
    *         new Student("陈达", 20) too many arguments to constructor报错
    *         所以该方法就不是scala中的构造器
    *  4、scala的构造,分为主构造器和辅助构造器,
    *     主构造器的定义和类的定义交织在一起,如何去定义一个主构造器
    *     class Xxx(参数列表) {
    *     }
    *     类名后面的内容就是主构造器,如果参数列表为空的话,()可以省略
    *     主构造器的函数体,就是类体的内容,所以如果我们使用主构造器创建对象
    *  5、scala的类有且仅有一个主构造器,要想提供更加丰富的构造器,就需要使用辅助构造器
    *     def this(参数列表)
    *     scala中的辅助构造器,在函数体的第一行,必须以调用其它辅助构造器或者主构造器开始
    *     也就是说要使用this(参数列表)去调用其它构造器
    *     但是归根到底,一个辅助构造器最终还是要从主构造器的调用开始
    *  6、scala和java的构造器的区别
    *     java的构造器没有主构造器和辅助构造器之分,但是有默认的无参构造器和有参构造器之分
    *     scala中默认的构造器就是类名后面的构造器,被称之为主构造器,同时还拥有辅助构造器
    *     java的构造器名称和类名一直,而scala中的构造器名称就是this,其余和java一模一样
    class Student(n:String, a:Int) {

       private var name:String = _
       private var age:Int = _

       def Student(name:String, age:Int): Unit = {
           this.name = name
           this.age = age
      }
       //辅助构造器
       def this() {
           this("张钟方", 18)
           println("---辅助构造器def this()-----")
      }

       def this(age:Int) {
           this()
           this.age = age
           println("---辅助构造器def this(age:Int)-----")
      }

       def show(): Unit = {
           println(s"name: ${n} age: ${a}")
      }
       println("如果这是构造器的方法体的话,这句话应该会被调用!")
    }

    2.1.5. 嵌套类

    scala中称之为嵌套类,在java中称之为内部类

    java中的成员内部类实例

    public class InnerClassOps {
       public static void main(String[] args) {
           Outer.Inner oi = new Outer().new Inner();
           oi.show();
      }
    }
    class Outer {
       class Inner {
           public void show() {
               System.out.println("inner show");
          }
      }
    }

    为啥要有内部类?

    从业务逻辑上理解,定义复杂是否在外部类内部定义更加合理,这样便有了内部类,比如,定义一个类Person,类有心脏,Heart优势一个复杂的抽象事物,显然应该把Heart定义在Person内部更加的准确与合理。

    scala的内部类如何定义

    object _03InnerOps {
       def main(args: Array[String]): Unit = {
           val outer = new Outer
           val inner = new outer.Inner()
           inner.show()
      }
    }

    class Outer { oo => //外部类的引用
       var x = 5
       class Inner {
           var x = 6
           def show(): Unit = {
               var x = 7
               println("Inner: x=" + x)//7
               println("Inner: x=" + this.x)//6
               println("Inner: x=" + Outer.this.x)//5
               println("Inner: x=" + oo.x)//5 简写方式
          }
      }
    }

    2.1.6. 对象object

    scala并没有像java中的静态,所以按照java中的观点的话,主函数是没有办法被执行public static void main(xxx)

    scala为了来模拟java中的static这个关键字,设计出了object这一结构,它是和class平级。

    在object定义的方法我们可以理解为函数,class中的行为称之为方法,而且在object中定义的变量和函数都是可以当做java中的静态来进行调用。

    object _04ObjectOps {
      def main(args: Array[String]): Unit = {
          val ret = Tool.add(13, 14)//相当于java的静态方法
      }
    }
    object Tool {
      val x = 5
      def add(a:Int, b:Int) = a + b
    }

    如何在scala中去定义单例对象呢?

    java中的单例(必须掌握)

    /**
    * 单例
    *     恶汉式
    *     懒汉式
    * 一个类只能创建一个对象,
    * 定义的步骤:
    *   恶汉式:
    *     1、私有构造器
    *     2、提供一个public的static的返回值为本类引用的方法
    *     3、为了给第2步中提供实例,创建一个private的static的成员变量
    *   懒汉式:
    *     1、私有构造器
    *     2、创建一个private的static的成员变量,没有初始化
    *     3、提供一个public的static的返回值为本类引用的方法
    */

    恶汉式:

    class Singleton {//恶汉式
       private Singleton(){}
       //成员位置
      {//构造代码块

      }
       private static Singleton instance = new Singleton();
    //   static {
    //       instance = new Singleton();
    //   }

       public static Singleton getInstance() {
           return instance;
      }
    }

    懒汉式:

    class Singleton {
       private Singleton(){}
       private static Singleton instance;

       public static Singleton getInstance() {
           if(instance == null) {
               synchronized (Singleton.class) {
                   if(instance == null)
                       instance = new Singleton();
              }
          }
           return instance;
      }
    }

    scala中的单例

    object _05SingletonOps {
       def main(args: Array[String]): Unit = {
           val s1 = Singleton
           val s2 = Singleton
           println("s2.x=" + s2.x)//1
           s1.x = 5
           println("s1 == s2? " + (s1 == s2))//true 单例
           println("s2.x=" + s2.x)//5
      }
    }
    object Singleton {
       var x = 1
    }

    2.1.7. 伴生对象和伴生类

    为什么要有伴生对象?

    我们都知道,在scala中是没有静态这个概念,而在java中一个类是既可以有非静态的成员,也可以有静态成员,表达非常丰富。scala由于没有静态的概念,类只能拥有非静态成员。所以scala为了弥补这个缺憾,定义这么一个和该类同名的object结构,而且该object结构必须要和该类在同一个.scala源文件中被定义

    这样我们就可以让该类拥有了静态和非静态的成员。

    把这个和类同名的object称之为该类的伴生对象,反过来,该类称之为该object的伴生类。

    object _06CompanionOps {
       def main(args: Array[String]): Unit = {
           val worker = new Worker("old李", 38)
           worker.show()
           println("-----------------------------")

           val w1 = Worker()
           w1.show()
           println("静态属性:" + Worker.x)
           val w2 = Worker("蔡金廷", 13)
           w2.show()

    //       val arr = new Array[Int](5)
    //       val arr1 = Array(1, 2, 3, 4)
      }
    }

    class Worker /*private ()*/ {
       private var name:String = _
       private var age:Int = _

       def this(name:String, age:Int) {
           this()
           this.name = name
           this.age = age
      }

       def show(): Unit = {
           println(s"name:${name}, age:${age}")
      }
    }

    object Worker {
       var x = 123
       //apply方法必须要重写
       def apply(): Worker = new Worker()

       def apply(name: String, age: Int): Worker = new Worker(name, age)
    }

    2.1.8 没有main函数如何执行scala程序

    object _07AppOps extends App {
       /*def main(args: Array[String]): Unit = {
           println("xxxxxx")
       }*/
       println(args.mkString("[", ",", "]"))
       println("yyyyyyyyyyyy")
    }
    extends:扩展
    trait:特质

     

  • 相关阅读:
    POJ 1984
    剑指offer 7. 斐波那契数列 & leetcode 剑指 Offer 10- I. 斐波那契数列
    剑指offer 60. 把二叉树打印成多行
    数据库的范式(建表的原则)
    剑指offer 59. 按之字形顺序打印二叉树
    力扣142.环形链表II & 剑指offer 55. 链表中环的入口结点
    GET 和 POST 的区别
    理解Cookie和Session的区别及使用
    基本排序算法代码实现,以及使用场景推荐
    The Castle OpenJ_Bailian
  • 原文地址:https://www.cnblogs.com/123hll/p/11013328.html
Copyright © 2020-2023  润新知