当前位置: 首页> 汽车> 时评 > 中央人民政府网韦其瑗_西安专业网站建设_cpc广告点击日结联盟_郑州网站制作公司哪家好

中央人民政府网韦其瑗_西安专业网站建设_cpc广告点击日结联盟_郑州网站制作公司哪家好

时间:2025/7/11 14:46:41来源:https://blog.csdn.net/m0_74021449/article/details/144969060 浏览次数: 1次
中央人民政府网韦其瑗_西安专业网站建设_cpc广告点击日结联盟_郑州网站制作公司哪家好
3.3类继承
3.3.1Scala中的类继承

为了节省代码量和反映实际各种类之间的联系,通常采取两种策略,包含和继承。包含是说明一个类中包含另一个类的对象,但两者之间没有必然联系。继承是从一个宽泛的类派生出更具体的类的过程,

被继承的类称为“超类”或“父类”,而派生出来的类称为“子类”,如果继承层次较深,最顶层的类通常也叫“基类”。通过在类的参数列表后面加上关键字extends和被继承类的类名,就完成了继承的过程。

scala> class A {| val a = "Class A"| }
// defined class Ascala> class B extends A {| val b = "Class B inherits from A"| }
// defined class Bscala> val x = new B
val x: B = B@611587f7scala> x.a
val res0: String = Class Ascala> x.b
val res1: String = Class B inherits from A
3.3.2调用超类的构造方法

在以上的例子中,A没有参数,当A有参数时B应该如何调用呢?在构造某个类的对象时,应该先构建超类对象的组件,再构造子类的其他组件。也就是说,类B应当调用类A的构造方法。语法是:

class 子类(子类对外接收的参数) extends 超类(子类给超类的参数)

Scala只允许主构造方法调用超类的构造方法。示例如下:

scala> class A(val a: Int)
// defined class Ascala> class B(giveA:Int, val b : Int) extends A(giveA)
// defined class Bscala> val x = new B(10,20)
val x: B = B@7fd3fd06scala> x.a
val res2: Int = 10scala> x.b
val res3: Int = 20scala> x.giveA
-- [E173] Reference Error: ---------------------------------------------------------------------------------------------
1 |x.giveA|^^^^^^^|value giveA cannot be accessed as a member of (x : B) from object rs$line$15.|  private value giveA can only be accessed from class B.
1 error found
3.3.3重写超类的成员

不被继承的成员

一般情况下,超类的成员都会被子类继承,但有两种不会被继承,一是超类中用private修饰的私有成员,二是被子类重写的成员。重写超类的成员时,应该再定义的开头加上关键字override。之前的toString函数就是使用这种方法重写的。

不可重写的成员

如果超类成员在开头用关键字final修饰,则子类只能继承,不能重写。使用final修饰class,则这个类禁止被其他类继承。

无参方法与字段

无参方法在调用时可以省略空括号,因此对于用户代码而言,调用无参方法和调用同名字段没有什么不同,Scala允许超类的无参方法被子类重写为字段,但是字段不能反过来被重写为方法,而且方法返回的类型必须与字段的类型一致。

字段与方法的区别在于,字段一旦被初始化,就会被保存在内存中,以后每次调用都只需要读取内存,而方法不会占用内存空间,但每次调用都需要执行一遍程序段,速度更慢。

Scala只有两种命名空间,值——字段、方法、包、单例对象;类型——类、特质

因为字段和方法同处一个命名空间,所以字段可以重写无参方法。在同一个域中不允许同时出现同名的字段、无参方法和单例对象。

3.3.4子类型多态与动态绑定

类型为超类的变量可以指向子类的对象,称为子类型多态。但是对于方法而言,尽管变量的类型是超类,但方法的版本是动态绑定的。调用的方法要允许哪个版本,是由变量指向的对象来决定的。

scala> class A {| def display() = "I'm A."| }
// defined class Ascala> class B extends A {| override def display() = "I'm B."| }
// defined class Bscala> val x: A = new B
val x: A = B@1fd35a92scala> x.display()
val res4: String = I'm B.

上面的程序中,声明了一个类型为A的变量,创建B的对象赋值给它,它调用方法时调用的是B类的方法。

3.3.5抽象类

如果类中包含没有初始化的字段或没有函数体的方法,那么这个类是抽象类,必须用abstract修饰。抽象类无法通过new来构造实例对象。抽象类确实的成员定义,可以由抽象类的子类补充,即抽象类声明了抽象成员,但没有定义。如果子类补全了相关定义,称子类“实现”了超类的抽象成员。此时override可写可不写。

scala> abstract class A {| val a: Int| }
// defined class Ascala> class B(val b: Int) extends A {| val a = b * 2| }
// defined class Bscala> val y = new B(1)
val y: B = B@58486debscala> y.a
val res5: Int = 2scala> y.b
val res6: Int = 1

抽象类常用于定义基类,基类会派生出很多不同的子类,基类只需要声明公共成员,让子类实现它们各自期望的版本。

3.3.6多重继承

Scala没有多重继承,这让一些特性变得非常简洁。Scala设计了“特质”来实现相同的功能,并且它的规则更加简单明了。

3.3.7Scala类的层次结构

Scala所有的类,包括已有的类和自定义的类,都不是毫无关联的,如下图所示,箭头表示属于指向的类的子类:
在这里插入图片描述
最顶部的是抽象类Any,它是所有类的超类。
在这里插入图片描述
Any有两个子类,即AnyValAnyRef,所有类被分为两大部分,值类和引用类。值类之间存在隐式转换,就是从Byte到Doubel的转换。除了9个值类,也可以自定义值类,但必须显式继承自AnyVal,否则都认为是AnyRef的子类。

另外,Nothing是所有类的子类,表示空值或空引用。Null类是空引用,Scala中可以把各种类型打包成一个特殊的可选值,为了表示空,没有这个特殊的概念,以及兼容各种自定义、非自定义的值和引用类,所以这个特殊的可选值就是把Nothing类进行打包。

关键字:中央人民政府网韦其瑗_西安专业网站建设_cpc广告点击日结联盟_郑州网站制作公司哪家好

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: