本文介绍Scala中的类class。
1、基本知识
类Classes是一个静态的模版,任何的对象object都可以在执行的时候初始化一个类实例。
就是说类只是一个模版,它要在object中调用实例才会被执行。
class的实例化使用关键字new。
2、class类的定义方法
2.1 通过关键字class来定义类。
类中变量的声明和初始化通过关键字 val /var,这是一样的。
类中方法的定义也是通过关键字 def。
类中方法的重写通过关键字 override def 。
//in scala
/** 定义一个class,声明变量,写方法,重写方法*/
class Student(val m1:Int,val m2:Int) {
var total:Int = m1 + m2
var ma1:Int = m1
var ma2:Int = m2
def calculateTotal(ma1:Int,ma2:Int) {
total = ma1 + ma2
println("Total is :"+total)
}
override def toString(): String = "(" + total + ")";
}
2.2 类的实例化
//in scala
object Test {
def main(args:Array[String]) {
val student = new Student(72,65); //类的实例化使用关键字 new
student.calculateTotal(72,65); //类中方法的调用
println(student) //注意这里调用的方法和生成的结果
}
}
3、类的扩展(或方法重写)
类class是可以扩展的(使用关键字extends 进行扩展),但有两个约束条件:首先,只有子类的主构造函数可以将参数传递给父类的构造函数,其次,必须指定override关键字。
(注:关于子类、父类,有的语言中叫做派生类、基类,虽然叫法不同但表述的都是同一个内容。)
3.1 子类重写父类中的方法
注意在子类的主构造函数中 多了两个变量m3,m4,另外子类中的变量m1,m2前面加上了 override方法用于将参数传递给父类的构造函数。
//in scala
class CollegeStudent(override val m1:Int,override val m2:Int,val m3:Int,val m4:Int) extends Student(m1,m2) {
var ma3:Int = m3
var ma4:Int = m4
var tot:Int = 0;
override def calculateTotal( ma1:Int, ma2:Int) {
tot = ma1 * ma2
println("Total is :"+tot)
} //calculateTotal 这个方法名字、参数都与父类中的方法一样,但计算方法是重写的,可以用override关键字
override def toString():String = "(" + tot + ")"; //这也是一个重写的方法
}
object Test {
def main(args:Array[String]) {
val total = new CollegeStudent(72,65,85,60);
total.calculateTotal(72,65);
println("Grand Total Marks of the Student is"+total)
}
}
3.2 子类继承父类中的方法
//in scala
class CollegeStudent(override val m1:Int,override val m2:Int,val m3:Int,val m4:Int) extends Student(m1,m2) {
var ma3:Int = m3
var ma4:Int = m4
var tot:Int = 0;
//calculateTotal 这个方法是子类中重写的
override def calculateTotal( ma1:Int, ma2:Int) {
tot = ma1 * ma2
println("Total is :"+tot)
}
//override def toString():String = "(" + tot + ")"; //删掉这条重写的方法,直接继承父类的方法
}
object Test {
def main(args:Array[String]) {
val total = new CollegeStudent(72,65,85,60);
total.calculateTotal(72,65); //注意这里的方法是重新写过的,调用该方法会生成一个乘法的 tot
println("Grand Total Marks of the Student is"+total) //注意这里的方式是父类中的,调用该方法生成的是一个加法的 tot
}
}
注意:子类 CollegeStudent 中的方法 calculateTotal( ma1:Int, ma2:Int) 是父类中方法的继承,它们具有完全相同的方法名、参数个数。
所以,如果要重写该方法必须要加上关键字override,否则会报错。
只要保持方法名、参数个数和参数类型跟父类一致,即使你更改了参数名,也是一样会报错,提示你必须使用override关键字。
如果你想使用跟父类中相同的方法名,但使用不同的参数个数、或者相同的参数个数但参数类型不同,这样子类中的方法就会变成跟父类中方法名一样,但却不同的方法。
这样就可以不使用override关键字。这在下面中进行介绍。
3.3 在子类中写父类中没有的方法
在子类中写父类中没有的方法,一般认为是写具有不同名字的方法,这是最常见常规的。
当然也可以使用父类中已有方法的名字,那么既然要是不同于父类的方法,那就要求 要么变量的个数是不同的、要么变量的类型是不同,这样才会成为不同的方法函数。
否则如果方法名、参数个数和命名等都相同,那就直接override重写就是了。
//in scala
class CollegeStudent(override val m1:Int,override val m2:Int,val m3:Int,val m4:Int) extends Student(m1,m2) {
var ma3:Int = m3
var ma4:Int = m4
var tot:Int = 0;
// calculateTotal 这个方法虽然名字与父类中的方法一样,但是却不是父类中方法的扩展,即不能加关键词override,因为方法的参数不同,他们是不同的两个方法
def calculateTotal( ma1:Int, ma2:Int, ma3:Int, ma4:Int) {
tot = ma1 + ma2 + ma3+ ma4
println("Total is :"+tot)
}
override def toString():String = "(" + tot + ")";
}
object Test {
def main(args:Array[String]) {
val total = new CollegeStudent(72,65,85,60);
total.calculateTotal(72,65,85,60); //注意这里传入的参数的个数
println("Grand Total Marks of the Student is"+total)
}
}
注意:子类 CollegeStudent 中的方法 calculateTotal( ma1:Int, ma2:Int, ma3:Int, ma4:Int) 不是父类中方法的继承或重写,它是完全不一样的方法,因为他们的参数个数不同。
如果我只因为它们使用了相同的方法名就认为是方法的重写,而在其前面加上 override关键字,这是会报错的。