zoukankan      html  css  js  c++  java
  • scala-类

    ---恢复内容开始---

    随笔记录scala中,有哪些类,如何定义一个类,有哪些注意点。

    一,scala中有哪些类?

    1,简单类 class

    2,单例模式 object

    3,伴生类

    4,case class

    5,trait

    二,如何定义一个类

    import java.io._
    
    class Point(xc: Int, yc: Int) {
       var x: Int = xc
       var y: Int = yc
    
       def move(dx: Int, dy: Int) {
          x = x + dx
          y = y + dy
          println ("x 的坐标点: " + x);
          println ("y 的坐标点: " + y);
       }
    }
    
    object Test {
       def main(args: Array[String]) {
          val pt = new Point(10, 20);
    
          // 移到一个新的位置
          pt.move(10, 10);
       }
    }
    

    上面是最基本的类定义方法,定义类的时候可以选择有参数,也可以选择没有参数,相当于java中的构造方法。

    需要注意的是:1,类的参数可以是具体的类型参数也可以是泛型;2,类的参数默认是不可变的,如果类的参数需要更改可以设定累的参数为var型。代码:

    //这里的类的参数直接使用泛型,我们当然可以把T1,T2换成任意我们想要的类型,比如Int,Double,String,Seq,Map等等。
    class ClassTest[T1,T2,T3](var t1:T1,val t2:T2,t3:T3) {//注意到前两个参数有var、val的标记,第三个没有
      def setT1(st1:T1) = {t1 = st1}
      def setT2(st2:T2) = {t2 = st2}//编译报错,显示"reassignment to val",意为:不可对val进行重赋值
      def setT3(st3:T3) = {t3 = st3}//编译报错,显示"reassignment to val",意为:不可对val进行重赋值
      println(t1.toString)
      println(t2.toString)
      println(t3.toString)
    }
    object ClassTest{
      def main(args: Array[String]): Unit = {
        val ct = new ClassTest(123,"John",1.2345)
    //    ct.setT1(234)
    //    ct.setT2("Joris")
    //    println(ct.t1)
    //    println(ct.t2)
        println("end object")
      }
    }
    

    关于类的构造方法(与Java类比),对于泛型参数类型的说明见后面的注意,简单参数类型类的说明参见:scala的构造方法与继承,下面是对原文的摘录。

    有java背景的人,很清楚java是如何定义构造方法以及继承的。在scala里面,继承和java有些相似。但是构造方法的定义,就不大一样了,应该说是差别还是很大的。在java里面,定义构造方法,就是定义一个没有返回值类型的与类同名的方法。

    如下:

    package com.shihuc;
    
    public class Person  
    {  
        private String lastName; //
        private String firstName; //
        private Person spouse; //配偶的Person对象  
        public Person(String fn, String ln, Person s)  
        {  
            lastName = ln; firstName = fn; spouse = s;  
        }  
        public Person(String fn, String ln)  
        {  
            this(fn, ln, null); //未婚时没有配偶  
        }  
        public String getFirstName()  
        {  
            return firstName;  
        }  
        public String getLastName()  
        {  
            return lastName;  
        }  
        public Person getSpouse()  
        {  
            return spouse;  
        }  
        public void setSpouse(Person p)  
        {  
            spouse = p;  
        }  
        public String introduction()  
        {  
            return "我的名字是," + firstName + " " + lastName +  
                    (spouse != null ?  
                            " 对方的名字是," + spouse.firstName + " " + spouse.lastName + " 。" :  
                            " 。");  
        }  
    }
    View Code

    但是,scala里面,可以看到:

    package lession2
    
    class Person(fn: String, ln: String, s: Person){
      val firstname = fn
      val lastname = ln
      var suporse = s
      
      println("primary constructor")
      
      def this(fn : String, ln : String)  { 
        this(fn, ln, null)
      }
      
      println("I am testing code")
      
      def introduction() : String =  {
        return "我的名字是, " + lastname + " " + firstname +  
          (if (suporse != null) {
            " 对方的名字是, " + suporse.lastname + " " + suporse.firstname + "。"
          }else {
            "。";  
          })      
      }  
    }
    
    object PersonTest{
      def main(args: Array[String]){
        var p = new Person("shihu", "CHENG")
        println(p.introduction())
      }
    }

    虽然scala的写法变得比java简洁了很多,这个是值得表扬的,但是构造函数的定义就有很大的不同。

    1. 先说主构造函数,也就是英文资料中说的primary constructor,它是和类的定义混杂在一起的,即定义类的时候,就指明了这个类的成员变量参数,还有,就是在类中,除了def定义的成员函数之外的所有操作,都可以看作是构造函数的行为组成部分,不管是变量赋值还是函数调用。而java的类定义和构造函数的定义是分开的。

    2. 再说派生的构造函数,即java中可以定义多个构造函数,这点,在java里非常简单,就是方法的重载呗。但是,在scala里面,要定义多个构造方法,就必须直接或则间接的调用主构造函数。而且调用的时候,必须通过关键字this来操作。正如上面scala代码中的辅助构造函数:

    1 def this(fn : String, ln : String) { 
    2   this(fn, ln, null)
    3 }

    需要注意的是,辅助构造函数名必须是this,而且必须调用主构造函数实现参数的传递(直接或则间接,本例子是直接调用,因为只有一个辅助构造函数)。

    3. 在scala中,若有继承,那么,只有主构造函数才能将参数的值传递到父类的构造函数中去。

    4. 在scala中,若子类继承了父类,但是想在子类中重写父类的某个函数,则在子类中必须用关键字override对父类的函数进行改写, 否则会出现语法错误。要想调用父类的同名函数,可以通过super关键字进行,这点与java是一致的。

    注意:我们看到scala中的副构造函数必须调用主构造函数,

  • 相关阅读:
    SQL Server误区30日谈Day15CheckPoint只会将已提交的事务写入磁盘
    SQL Server误区30日谈Day16数据的损坏和修复
    【译】Windows Azure迁移生命周期概览
    【译】实现为Windows Azure制定的迁移计划
    SQL Server误区30日谈Day18有关FileStream的存储,垃圾回收以及其它
    【译】为迁移到Windows Azure制定规划
    SQL Server误区30日谈Day14清除日志后会将相关的LSN填零初始化
    SQL PASS北京用户群成功举办第一次线下活动,性能调优PPT分享
    Windows Azure虚拟机概览
    SQL Pass北京将举办第一次线下活动,欢迎大家报名
  • 原文地址:https://www.cnblogs.com/chen-kh/p/6197983.html
Copyright © 2011-2022 走看看