[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简要: 继承
- 7.scala:继承
- Scala学习第十五天 Scala多重继承、多重继承构造器执行顺序及AOP实现
- Scala多重继承、多重继承构造器执行顺序及AOP实现
- [置顶] 【scala 的类】Scala的类:变量/方法/构造方法/继承
- Scala class的构造方法与继承
- Scala学习教程笔记二之函数式编程、Object对象、伴生对象、继承、Trait、
- scala------ 继承
- scala中的面向对象定义类,构造函数,继承
- scala类_继承
- scala学习笔记(七) 继承
- scala 继承覆写使用示例
- Scala继承
- Scala继承彻底实战和Spark源码鉴赏
- Scala学习(八)---Scala继承
- Scala:基于trait的多重继承构造器的执行顺序、基于trait的AOP实践
- scala 第12讲 继承 构造
- 第10课:Scala继承彻底实战和Spark源码鉴赏
- scala学习笔记2(类,继承,抽象类)
- scala 学习笔记(06) OOP(下)多重继承 及 AOP