scala
1.extends
Scala中,让子类继承父类,与Java一样,也是使用extends关键字
继承就代表,子类可以从父类继承父类的field和method;然后子类可以在自己内部放入父类所没有,子类特有的field和method;使用继承可以有效复用代码
class Person {private var name = "leo"def getName = name}class Student extends Person {private var score = "A"def getScore = score}
子类可以覆盖父类的field和method;但是如果父类用final修饰,则该类是无法被继承的,field和method用final修饰,field和method是无法被覆盖的
final class Person { //final embellish class Person it not be extendsprivate var name = "leo"def getName = name}class Student extends Person { //errorprivate var score = "A"def getScore = score}
eg:
scala> final class Person {
| private var name = "leo"
| def getName = name
| }
defined class Person
scala> class Student extends Person {
| private var score = "A"
| def getScore = score
| }
<console>:8: error: illegal inheritance from final class Person
class Student extends Person {
override 父类final修饰的字段 方法
class Person {private var name = "leo"final val age = 10; //final embellish field age it not be override by child classdef getName = name}class Student extends Person {private var score = "A"def getScore = scoreoverride val age = 20 //erroroverride def getName = "my name is" + super.getName}
eg:
scala> class Person {
| private var name = "leo"
| final val age = 10; //final embellish field age it not be override by child class
| def getName = name
| }
defined class Person
scala> class Student extends Person {
| private var score = "A"
| def getScore = score
| override val age = 20 //error
| override def getName = "my name is" + super.getName
| }
<console>:11: error: overriding value age in class Person of type Int(10);
value age cannot override final member
override val age = 20 //error
2.isInstanceOf 和 asInstanceOf
如果我们创建了子类的对象,但是又将其赋予了父类类型的变量。则在后续的程序中,我们又需要将父类类型的变量转换为子类类型的变量,应该如何做?
首先,需要使用isInstanceOf判断对象是否是指定类的对象,如果是的话,则可以使用asInstanceOf将对象转换为指定类型 注意,如果对象是null,则isInstanceOf一定返回false,asInstanceOf一定返回null 注意,如果没有用isInstanceOf先判断对象是否为指定类的实例,就直接用asInstanceOf转换,则可能会抛出异常
class Personclass Student extends Personval p: Person = new Studentvar s: Student = null //note:isInstanceOf and asInstanceOf use[] instead of ()if (p.isInstanceOf[Student]) s = p.asInstanceOf[Student]
eg:
scala> print(p.isInstanceOf[Student]) true scala> print(p.isInstanceOf[Person]) true scala>
3.getClass 和 classOf
对象.getClass可以精确获取对象的类,classOf[类]可以精确获取类,然后使用==操作符即可判断
class Personclass Student extends Personval p: Person = new Studentp.isInstanceOf[Person]p.getClass == classOf[Person]p.isInstanceOf[Student]p.getClass == classOf[Student]
eg:
scala> p.getClass == classOf[Person] res20: Boolean = false scala> p.getClass == classOf[Student] res21: Boolean = true
4.使用匹配模式来进行类型判断
使用模式匹配,功能性上来说,与isInstanceOf一样,也是判断主要是该类以及该类的子类的对象即可,不是精准判断的
class Personclass Student extends Personval p: Person = new Studentp match {case per: Person => println("it's Person's object")case _ => println("unknown type")}
3.protected
还可以使用protected[this],则只能在当前子类对象中访问父类的field和method,无法通过其他子类对象访问父类的field和method
class Person {protected var name: String = "leo"protected[this] var hobby: String = "game"}class Student extends Person {def sayHello = println("Hello, " + name)def makeFriends(s: Student) { //this s is not be current instance objectprintln("my hobby is " + hobby + ", your hobby is " + s.hobby)// error}}
eg1: error
scala> class Person {
| protected var name: String = "leo"
| protected[this] var hobby: String = "game"
| }
defined class Person
scala> class Student extends Person {
| def sayHello = println("Hello, " + name)
| def makeFriends(s: Student) {
| println("my hobby is " + hobby + ", your hobby is " + s.hobby)
| }
| }
<console>:15: error: value hobby is not a member of Student
println("my hobby is " + hobby + ", your hobby is " + s.hobby)
eg2:
scala> class Person {
| protected var name: String = "leo"
| protected var hobby:String = "game"
| }
defined class Person
scala> class Student extends Person {
| def sayHello = println("Hello, " + name)
| def makeFriends(s: Student) { //this s is not be current instance object
| println("my hobby is " + hobby + ", your hobby is " + s.hobby)
| }
| }
defined class Student
4.调用父类的constructor
注意!如果是父类中接收的参数,比如name和age,子类中接收时,就不要用任何val或var来修饰了,否则会认为是子类要覆盖父类的field
class Person(val name: String, val age: Int)class Student(name: String, age: Int, var score: Double) extends Person(name, age) {def this(name: String) {this(name, 0, 0)}def this(age: Int) {this("leo", age, 0)}}
5.匿名内部类
匿名子类,也就是说,可以定义一个类的没有名称的子类,并直接创建其对象,然后将对象的引用赋予一个变量。之后甚至可以将该匿名子类的对象传递给其他函数。
class Person(protected val name: String) {def sayHello = "Hello, I'm " + name}val p = new Person("leo") {//p is a anonymity child class's objectoverride def sayHello = "Hi, I'm " + name}def greeting(p: Person { def sayHello: String }) {println(p.sayHello)}greeting(p)//use anonymity class's object as a method parameter
6.抽象类 abstract class and abstract field
如果在父类中,有某些方法无法立即实现,而需要依赖不同的子类来覆盖,重写实现自己不同的方法实现。此时可以将父类中的这些方法不给出具体的实现,只有方法签名,这种方法就是抽象方法。
在子类中覆盖抽象类的抽象方法时,不需要使用override关键字
abstract class Person(val name: String) {def sayHello: Unit}class Student(name: String) extends Person(name) {def sayHello: Unit = println("Hello, " + name)}
子类必须覆盖field,以定义自己的具体field,并且覆盖抽象field,不需要使用override关键字
abstract class Person {val name: String}class Student extends Person {val name: String = "leo"}