您的位置:首页 > 移动开发

[scala之七]继承

2014-12-21 23:45 183 查看

一、普通 Scala 对象

 
Person
的类定义:

// This is Scala

class Person(val firstName:String, val lastName:String, val age:Int)

{

 def toString = "[Person: firstName="+firstName+" lastName="+lastName+

                        " age="+age+"]"

}

使用 
Person
类型也非常简单:

// This is Scala

object PersonApp

{

 def main(args : Array[String]) : Unit =

 {

   val bindi = new Person("Tabinda", "Khan", 38)

   System.out.println(bindi)

 }

}

 

二、Scala抽象类

// This is Scala

abstract class Person(val firstName:String, val lastName:String, val age:Int)

{

 override def toString = "[Person: firstName="+firstName+" lastName="+lastName+

                         " age="+age+"]"

 

 def doSomething; // note the semicolon, which is still optional

                  // but stylistically I like having it here

}

 

为Person创建一个子类
class Student(firstName:String, lastName:String, age:Int)

 extends Person(firstName, lastName, age)

{

 def doSomething =

 {

   System.out.println("I'm studying hard, Ma, I swear! (Pass the beer, guys!)")

 }

}

 
Scala 将函数视为值,在运行时需要切换功能的时候利用函数值。
// This is Scala   

class Person(val firstName:String, val lastName:String, val age:Int)

{

 var doSomething : (Person) => Unit =

    (p:Person) => System.out.println("I'm " + p + " and I don't do anything yet!");

   

  def work() =

   doSomething(this)

   

  override def toString = "[Person: firstName="+firstName+" lastName="+lastName+

                         " age="+age+"]"

}

 

object App

{

 def main(args : Array[String]) =

 {

   val bindi = new Person("Tabinda", "Khan", 38)

   System.out.println(bindi)

   

    bindi.work()

   

    bindi.doSomething =

     (p:Person) => System.out.println("I edit textbooks")

     

    bindi.work()

   

    bindi.doSomething =

     (p:Person) => System.out.println("I write HTML books")

     

    bindi.work()

 }

}

三、构造函数

在 Scala 中,主构造函数的参数在
class
行传递,但您也可以为这些参数使用
val
修饰符,以便在类本身上轻松引入读值器(对于
var
,则为写值器)。Scala必须实现一种语法,允许继承类调用基类,同时保留允许我们在基类上引入读值器和写值器的语法。
// This is javap

C:\Projects\scala-inheritance\code>javap -classpath classes Person

Compiled from "person.scala"

public abstract class Person extends java.lang.Object implements scala.ScalaObje

ct{

   public Person(java.lang.String, java.lang.String, int);

   public java.lang.String toString();

   public abstract void doSomething();

   public int age();

   public java.lang.String lastName();

   public java.lang.String firstName();

   public int $tag();

}

 

四、语法差异

Scala 并未像 Java 语言那样将字段与方法区分开来,允许 Scala 程序员轻而易举地向使用基类的用户 “隐藏” 字段和方法之间的差异。
// This is Scala

abstract class Person(val firstName:String, val lastName:String, val age:Int)

{

 def doSomething

 

  def weight : Int

   

  override def toString = "[Person: firstName="+firstName+" lastName="+lastName+

                         " age="+age+"]"

}

 

class Student(firstName:String, lastName:String, age:Int, val subject:String)

 extends Person(firstName, lastName, age)

{

 def weight : Int =

   age // students are notoriously skinny

 

 def doSomething =

 {

   System.out.println("I'm studying hard, Ma, I swear! (Pass the beer, guys!)")

 }

}

 

class Employee(firstName:String, lastName:String, age:Int)

 extends Person(firstName, lastName, age)

{

 val weight : Int = age * 4 // Employees are not skinny at all

 

 def doSomething =

 {

   System.out.println("I'm working hard, hon, I swear! (Pass the beer, guys!)")

 }

}

Scala 实际上允许将
weight
定义为一种方法(如
Student
中所示),也允许将其定义为字段/存取器(如
Employee
中所示)。这种句法决策使您在抽象类继承的实现方面有一定的灵活性。

五、override

Java 5 编译器引入了
@Override
注释。
@Override
验证引入继承类的方法实际上已经覆盖了基类方法。在 Scala 中,
override
已经成为语言的一部分,几乎可以忘记它会生成编译器错误。
// This is Scala

class Student(firstName:String, lastName:String, age:Int, val subject:String)

 extends Person(firstName, lastName, age)

{

 def weight : Int =

   age // students are notoriously skinny

 

 def doSomething =

 {

   System.out.println("I'm studying hard, Ma, I swear! (Pass the beer, guys!)")

 }

 

  override def toString = "[Student: firstName="+firstName+

                         " lastName="+lastName+" age="+age+

                         " subject="+subject+"]"

}

六、与java差别

Scala 的类型层次结构与 Java 语言中的对应结构略有不同;从技术上来讲,所有 Scala 类继承的基类(包括
Int
Float
Double
和其他数字类型)都是
scala.Any
类型,这定义了一组核心方法,可在 Scala 内的任意类型上使用:
==
!=
equals
hashCode
toString
isInstanceOf

asInstanceOf
,大多数方法通过名称即可轻松理解。在这里,Scala 划分为两大分支,“原语类型”继承自
scala.AnyVal
;“类类型” 继承自
scala.AnyRe
。(
scala.ScalaObject
又继承自
scala.AnyRef
。)

// This is Scala

class ScalaJavaPerson(firstName:String, lastName:String, age:Int)

 extends JavaPerson(firstName, lastName, age)

{

 val weight : Int = age * 2 // Who knows what Scala/Java people weigh?

 

 override def toString = "[SJPerson: firstName="+firstName+

                         " lastName="+lastName+" age="+age+"]"

}

它继承自
JavaPerson


// This is Java

public class JavaPerson

{

   public JavaPerson(String firstName, String lastName, int age)

   {

       this.firstName = firstName;

       this.lastName = lastName;

       this.age = age;

   }

   

    public String getFirstName()

   {

       return this.firstName;

   }

   public void setFirstName(String value)

   {

       this.firstName = value;

   }

   

    public String getLastName()

   {

       return this.lastName;

   }

   public void setLastName(String value)

   {

       this.lastName = value;

   }

   

    public int getAge()

   {

       return this.age;

   }

   public void setAge(int value)

   {

       this.age = value;

   }

   

    public String toString()

   {

       return "[Person: firstName" + firstName + " lastName:" + lastName +

           " age:" + age + " ]";

   }

   

    private String firstName;

   private String lastName;

   private int age;

}

在编译
ScalaJavaPerson
时,它将照常扩展
JavaPerson
,但按照 Scala 的要求,它还会实现
ScalaObject
接口。并照例支持继承自
JavaPerson
的方法,因为
ScalaJavaPerson
是一种 Scala 类型,我们可以期望它支持
Any
引用的指派,根据 Scala 的规则:

// This is Scala   

    val richard = new ScalaJavaPerson("Richard", "Campbell", 45)

   System.out.println(richard)

   val host : Any = richard

   System.out.println(host)

但在 Scala 中创建
JavaPerson
并将其指派给
Any
引用时会发生什么?

// This is Scala   

    val carl = new JavaPerson("Carl", "Franklin", 35)

   System.out.println(carl)

   val host2 : Any = carl

   System.out.println(host2)

归功于
Any
类型与
java.lang.Object
类型的相似性,几乎可以说,所有扩展
java.lang.Object
的内容都支持存储到
Any
引用之中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  scala 继承 app 编译器