91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Scala2.11.7學習筆記(六)類和對象

發布時間:2020-07-15 20:39:26 來源:網絡 閱讀:550 作者:luchunli1985 欄目:大數據

魯春利的工作筆記好記性不如爛筆頭



1、擴展類    

    extends是Scala中實現繼承的保留字;

class week extends month{......}

    week類繼承了month類所有非私有成員;

    week類是month類的子類,month類是week類的超類;

    子類能重寫超類的成員(字段、方法);

class week(val num : Int) extends month(val num : Int) {......}

    單例對象同樣能從類中繼承,與類的繼承語法相同:object day extends week {......}

重寫

    Scala中使用override保留字進行方法、字段重寫

class week extends month {
    override def firstday () {......}
}

    override保留字聲明其后的字段或方法是對超類的重寫,也可以寫在類定義參數中。

class week (override val lastday : String) extends month(val lastday : String)

    重新定義的字段和方法不可重寫(override),方法不同(參數類型或個數)不可重寫。

scala> class month {
     |     def secondary(m : String) {
     |         println("secondary is " + m);
     |     }
     | }
defined class month
 
scala>
 
scala> class week extends month {
     |     override def secondary(m : String) {    // 重寫該方法
     |         println("secondary is " + m);
     |     }
     | }
defined class week

2、重寫規則

   重寫def

    用val:利用val能重寫超類沒有參數的方法;

    用def:子類方法與超類成員重名;

    用var:同時重寫getter、setter方法,只重寫getter方法報錯。

   重寫val:

    用val:子類的一個私有字段與超類的字段重名,getter方法重寫超類的getter方法

   重寫var:

    用var:當超類的var是抽象的才能被重寫,否則超類的var都會被繼承。

// 新建文件month.scala,內容為:
abstract class month {
    val zero : Int;
    val one = 25;         // 可在子類中用val重寫
    var two = 15;         // 不可在子類中用var重寫,因為不是抽象的
    var three : Int;
    def firstday ;        // 可在子類中用val重寫
    def now ;             // 可在子類中用var重寫
    def now_ ;        
    def lastday(m : Char) = {}    // 可在子類中用def重寫
}

// 通過scalac命令編譯該文件
D:\LuclAppServ\scala-SDK\source>scalac month.scala

D:\LuclAppServ\scala-SDK\source>javap.exe -private month.class
// 通過javap命令查看生成的文件
Compiled from "month.scala"
public abstract class month {
  // val變量且被初始化了
  private final int one;
  // var變量且被初始化了
  private int two;
  // val變量但為抽象的,直接生成了getter方法
  public abstract int zero();
  // 只有getter方法
  public int one();
  // 同時具有getter和setter方法(=被轉義為$eq)
  public int two();
  public void two_$eq(int);
  // var變量但為抽象的,直接生成了getter和setter方法
  public abstract int three();
  public abstract void three_$eq(int);
  // 其他抽象的方法
  public abstract void firstday();
  public abstract void now();
  public abstract void now_();
  // 具有方法體,非抽象方法
  public void lastday(char);
  // 構造函數
  public month();
}

    通過IDE工具生成的week.scala代碼如下

/**
 * @author lucl
 */
class week extends month {
  override val zero : Int = 10;

  override var three : Int = 3;

  override def firstday : Unit = {
    println("method of  firstday.");
  }

  override def now : Unit = {
    println("method of now.");
  }

  override def now_ : Unit = {
    println("method of now_.");
  }
  
}

object week {
  def main (args : Array[String]) {
    var w = new week();
    println(w.zero + "\t" + w.now);
  }
}

    查看生成的week子類代碼

D:\LuclAppServ\workspaces\scala\scalaproj\bin>javap -private week.class
Compiled from "week.scala"
public class week extends month {
  private final int zero;
  private int three;
  
  public int zero();
  
  public int three();
  public void three_$eq(int);
  
  public void firstday();
  
  public void now();
  public void now_();
  
  public week();
  
  public static void main(java.lang.String[]);
}

D:\LuclAppServ\workspaces\scala\scalaproj\bin>javap -private week$.class
Compiled from "week.scala"
public final class week$ {
  public static final week$ MODULE$;
  public static {};
  public void main(java.lang.String[]);
  private week$();
}

說明:

    子類構造器運行在超類構造器之后,在超類的構造器調用的子類被重寫后,返回值可能不正確。

/**
 * @author lucl
 */
class A {
  val num = 31;
  val days = new Array[Int](num);
  println("When invoke Class A the length of days is " + days.length + ".");
  def dayLength = {
    println("Class A : the length of days is " + days.length + ".")
  }
}

/**
 * @author lucl
 */
object B extends A {
  override val num = 7;
  
  def main (args : Array[String]) {
    dayLength;
    println("The finally value of num is " + num);
  }
}

    運行結果:

Scala2.11.7學習筆記(六)類和對象

    構造B對象前先執行A的構造器,num被初始化為31,days被初始化為Array數組;

    Array數組初始化時需要調用num,但num被子類重寫了,但此時B的構造器還未被調用,num被初始化為0,days被初始化為長度為0的數組;

    A的構造器執行完畢,執行B的構造器,num被初始化為7,但此時A中days已初始化過不會再更新其初始化信息,days的數組長度為0。

    解決方法:

        將超類的val聲明為final(不可再被子類重寫);

        將超類的val聲明為lazy;

        在子類中使用提前定義語法。

    a. final

        當A類中的num聲明為final val num : Int = 7,則子類中不可再重寫該字段;

    b. lazy

/**
 * @author lucl
 */
class A {
  lazy val num = 31;   // 通過lazy標注
  val days = new Array[Int](num);
  println("When invoke Class A the length of days is " + days.length + ".");
  def dayLength = {
    println("Class A : the length of days is " + days.length + ".")
  }
}

/**
 * @author lucl
 */
object B extends A {
  override lazy val num = 7;
  
  def main (args : Array[String]) {
    dayLength;
    println("The finally value of num is " + num);
  }
}

    運行結果

Scala2.11.7學習筆記(六)類和對象   

    c. 提前定義

    把需要提前定義的語句塊放在extends與超類之間,并后接with保留字。
    class B extends {override val num = 7; } with A {......}

/**
 * @author lucl
 */
object B extends {override val num = 7; } with A {
  def main (args : Array[String]) {
    dayLength;
    println("The finally value of num is " + num);
  }
}

    執行結果:

Scala2.11.7學習筆記(六)類和對象

    

3、抽象類

    不能被實例的類叫做抽象類,用保留字abstract標記;

    抽象類的某個或某幾個成員沒有被完整定義,這些沒有被完整定義的成員為抽象字段或方法。

/**
 * @author lucl
 */
abstract class year {
  val name : Array[String];  // 抽象的val,帶有一個抽象的getter方法
  var num : Int;             // 抽象的var,帶有抽象的getter/setter方法
  def sign;                  // 沒有方法體/函數體,是一個抽象方法
}

    只要類中有任意一個抽象成員,必須使用abstract標記;

    重寫抽象方法、抽象字段不需要使用override保留字。

保護

    當一個類不希望被集成、拓展時,可在類聲明前加上final保留字

final class year {......}

    當一個類的某些成員不希望被重寫時,可在成員聲明前加上final保留字

class year {final def sign {......}}


    當超類中的某些成員需要被子類繼承,又不想對子類以外成員可見時,在成員聲明前加上protected保留字;

    protected[this],將訪問限定于當前對象(子類也不可訪問),類似于private[this];

/**
 * @author lucl
 * 只要類中有一個成員是抽象的,則類就需要聲明為抽象類
 */
abstract class Human {
  var name : String;      // 抽象字段
  def sleep() : String;   // 抽象方法
  def info (address : String);
}

/**
 * 
 */
abstract class Teacher (tname : String, age : Int) extends Human {
  println(tname + "\t" + age);
  
  override var name : String = tname;
  
  // 若將類聲明為def sleep = "8 hours",在下面調用super.sleep()的位置會提示返回的為Unit
  override def sleep() : String = "8 hours.";
  
  def info (address : String);
}

/**
 * Worker繼承Teacher時有兩個參數name和age需要從Worker中傳遞參數
 * Worker的的參數名字需要與Teacher中一致,否則IDE會提示錯誤
 */
class Worker(tname : String, age : Int, salary : Int) extends Teacher (tname, age) {
  override def info (address : String) {
    println(tname + "' home is in " + address);
    println(tname + "'s age is " + age + ", earn ¥" + salary + ".");
  }
  
  override def toString = {
    tname + " is a worker, sleep " + super.sleep;
  }
}

object AbstractClassOps {
  def main(args : Array[String]) {
    val w = new Worker ("zhangsan", 25, 3000);
    w.info("BeiJing");
    println(w);
  }
}

/**
  zhangsan  25
  zhangsan' home is in BeiJing
  zhangsan's age is 25, earn ¥3000.
  zhangsan is a worker, sleep 8 hours.
*/


4、類的private屬性

/**
 * @author lucl
 */
// 默認是public類型的
class Person {
  // age必須賦值,否則該類必須為abstract的
  private var age : Int = 0;  
  
  // 沒有private修飾默認是public的
  // 無參的方法可以省略(),調用時可以省略();
  def increment() = age += 1;
  // 若聲明的方法不帶(),則調用時不可帶()
  def current = age;
  
  // 類可以直接訪問伴生對象的私有屬性
  def speak = Person.sayHello;
}

class Student {
  /**
   * 聲明為private類型的參數,只能通過當前類的函數來訪問
   */
  private var privateAge : Int = 0;
  // 僅限于類的當前實例對象訪問,其他傳入的對象(如下面的other)將不可訪問private[this]修飾的變量
  private [this] val name : String = "";
  
  // 自定義的getter/setter方法 ,用來操作私有字段 
  def age = privateAge;
  
  def age_ (newAge : Int) {
    privateAge = newAge;
  }
  
  /**
   * this對象的使用,表示調用該方法的當前對象
   */
  def sameStudent (other : Student) = {  
    // 上面的等號表示有返回結果,否則最后的true會提示:
    // a pure expression does nothing in statement position; 
    // you may be omitting necessary parentheses
    if (this.privateAge != other.privateAge) {
      false;
    }
    /**
     *  此時通過other將無法訪問該name對象
     *  value name is not a member of Student
     */
    /*if (this.name != other.name) {
      false;
    }*/
    true;
  }
  
  // 在student中則不可通過Person類直接訪問sayHello方法,提示:
  // method sayHello in object Person cannot be accessed in object Person
  // def speak = Person.sayHello;
  // 但可以通過如下方式訪問:
  var p = new Person;
  p.speak;  // 這里會直接執行
}

/**
 * 對象為類的伴生對象,類為對象的伴生類
 */
object Person {
  def main (args : Array[String]) {
    var p = new Person();
    println("age is : " + p.age);    // 可以訪問到私有屬性
    p.increment;
    println("age is : " + p.age);
    println("current is : " + p.current);
    
    // 帶有()則提示“Int does not take parameters”
    // p.current();
    
    val s = new Student();
    // variable privateAge in class Student cannot be accessed in Student
    // s.privateAge;
    println(s.age);
    s.age_(20);
    println(s.age);
  }
  private def sayHello () {
    println("Singleton object Person to say.");
  }
}

/**
 // 輸出結果
  age is : 0
  age is : 1
  current is : 1
  Singleton object Person to say.
  0
  20
*/


5、嵌套類

    Scala允許任何語法結構中嵌套任何語法結構,因此能在類中定義類,類似于Java中的內部類。

    內部類中可以訪問外部類的成員,利用外部類.this或指針實現。

scala> class HelloWorld {pointto =>
    val value2 = "HelloWorld";
    class HI {
        var value3 = HelloWorld.this.value2;
        var value4 = pointto.value2;
    }
} 

scala> var one = new HelloWorld;
one: HelloWorld = HelloWorld@4b134f33

scala> one.value2;
res52: String = HelloWorld

scala> class Family (val hname : String, val wname : String) {
    class Husband (var name : String) {
        println("Husband is : " + name);
    }
    
    class Wife (var name : String) {
        println("Wife is " + name);
    }
    
    def info () {
        var husband = new Husband(hname);
        var wife = new Wife(wname);
        println("This family holds husband " + husband.name + ", wife " + wife.name);
    }
}

scala> val f = new Family("Tom", "Jerry");
f: Family = Family@62de96e8

scala> f.info();
Husband is : Tom
Wife is Jerry
This family holds husband Tom, wife Jerry


Java內部類:內部類是屬于外部類的;

/**
 * 
 * @author lucl
 * Java內部類示例
 * 說明:Java內部類是從屬于外部類的
 */
public class JavaOuter {
    private String name;
    public JavaOuter (String name) {
        this.name = name;
    }
    /**
     * 內部類
     */
    // 一旦用static修飾內部類,它就變成靜態內部類了。
    class Inner {
        private String name;
        public Inner (String name) {
            this.name = name;
        }
        public void foo (Inner inner) {
            System.out.println("\t" + JavaOuter.this.name + "\t" + inner.name);
        }
    }
    
    public void foo () {
        System.out.println("Outer : " + this.name);
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        JavaOuter outer1 = new JavaOuter("Spark");
        JavaOuter outer2 = new JavaOuter("Hadoop");
        
        JavaOuter.Inner inner1 = outer1.new Inner("scala");
        JavaOuter.Inner inner2 = outer2.new Inner("java");
        
        outer1.foo();
        inner1.foo(inner1);

        outer2.foo();
        inner2.foo(inner2);
        
        outer1.foo();
        inner1.foo(inner2);    // 在這里inner1可以調用inner2
    }
}

/**
     // 輸出結果
    Outer : Spark
            Spark    scala
    Outer : Hadoop
            Hadoop    java
    Outer : Spark
            Spark    java
*/

Scala內部類:內部類是屬于外部類的對象的;

/**
 * @author lucl
 * Scala內部類示例
 * 說明:Scala內部類是從屬于外部類的對象的
 */
class ScalaOuter(val name : String) {outer =>
  /**
   * 內部類
   */
  class Inner (val name : String) {
    def foo (inner : Inner) {
      println("\t" + outer.name + "\t" + inner.name + ".");
    }
  }
  
  def foo () {
    println("Outer : " + outer.name);
  }
}

object OOPInScala {
    /**
   * main方法
   */
  def main (args : Array[String]) {
    val outer1 = new ScalaOuter ("Spark");
    val outer2 = new ScalaOuter ("Hadoop");
   
    val inner1 = new outer1.Inner("scala");
    val inner2 = new outer2.Inner("java");
    outer1.foo;
    inner1.foo(inner1);
    
    outer2.foo;
    inner2.foo(inner2);
    
    // 對于scala來說,這inner1調用foo方法傳遞參數時,是不可以將inner2作為參數傳遞的
    // IDE提示:type mismatch; found : outer2.Inner required: outer1.Inner
    // inner1.foo(inner2);
  }
}

/**
    // 輸出結果
    Outer : Spark
          Spark scala.
    Outer : Hadoop
          Hadoop  java.
*/


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

广河县| 西城区| 武乡县| 丽江市| 高淳县| 延边| 平陆县| 田东县| 承德县| 巴彦淖尔市| 卢氏县| 淮南市| 宣化县| 华蓥市| 临城县| 滦南县| 彰化县| 石棉县| 禄劝| 衡阳市| 紫阳县| 安化县| 三亚市| 万年县| 林周县| 泗阳县| 仪陇县| 胶南市| 漳浦县| 新田县| 尖扎县| 康乐县| 汶川县| 望谟县| 招远市| 嘉祥县| 广饶县| 济宁市| 普兰店市| 金山区| 托里县|