Scala的ClassObjectTrait
Posted 数据分析
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scala的ClassObjectTrait相关的知识,希望对你有一定的参考价值。
开发环境
ideaIU或ideaIC。
idea的scala插件,File-Setting-Plugins,搜索scala在线安装,或下载后离线安装Install plugin from disk。
加载scala的包,Project Structure,Global Libraries,添加scala-sdk。
基础
scala中,break和continue的实现,
1package com.padluo.spark.scala.basic
2import scala.util.control.Breaks._
3object BreakTest {
4 def main(args: Array[String]): Unit = {
5 // break
6 breakable {
7 for (i <- 1 to 10) {
8 if (i == 2) {
9 break()
10 }
11 println(i)
12 }
13 }
14 // continue
15 for (i <- 1 to 10) {
16 breakable {
17 if (i == 2) {
18 break()
19 }
20 println(i)
21 }
22 }
23 }
24}
0 until 10
和0 to 10
的区别,until是0到9,相当于<,to是0到10,相当于<=。
scala用Java里面的类库,
1package com.padluo.spark.scala.basic
2import java.text.SimpleDateFormat
3import java.util.{Calendar, Date}
4object UseJava {
5 def main(args: Array[String]): Unit = {
6 val sdf:SimpleDateFormat = new SimpleDateFormat("yy-MM-dd")
7 val c = Calendar.getInstance()
8 println(c.getTime)
9 println(sdf.format(c.getTime))
10 // Convert Code from Java,可以直接把Java代码贴到scala文件中来
11 val sdf2: SimpleDateFormat = new SimpleDateFormat("yy-MM-dd")
12 sdf2.format(new Date)
13 }
14}
Class、Object、Trait
类class里无static类型,类里的属性和方法,必须通过new出来的对象来调用,所以有main主函数也没用。
而object的特点是:
可以拥有属性和方法,且默认都是"static"类型,可以直接用object名直接调用属性和方法,不需要通过new出来的对象(也不支持)。
object里的main函数式应用程序的入口。
object和class有很多和class相同的地方,可以extends父类或Trait,但object不可以extends object,即object无法作为父类。
类
构造函数,
一个主构造器(函数),其他是辅助构造器
辅助构造器的实现体里,必须引用(调用)主构造器
主构造器的参数,也会成为类的属性(?正确吗?)
辅助构造函数的名称都是this
辅助构造函数中必须以一个其他辅助构造器或主构造器的调用开始
Bean属性,定义getter和settet方法。
1// TestVo.scala
2package com.padluo.spark.scala.basic
3import scala.beans.BeanProperty
4class TestVo {
5 // class 里的属性默认是private类型,object里的属性默认是static
6 @BeanProperty var id = 10
7 @BeanProperty var name = null
8 @BeanProperty var addr = null
9}
10// TestVoMain.scala
11package com.padluo.spark.scala.basic
12object TestVoMain {
13 def main(args: Array[String]): Unit = {
14 var vo = new TestVo
15 println(vo.getId)
16 }
17}
伴生对象
如何实现同个类既有普通方法又有静态方法?
伴生类和伴生对象可以相互访问彼此的私有成员。
1package com.padluo.spark.scala.basic
2class BanSheng {
3 def add2(a: Int, b: Int): Int = {
4 a + b
5 }
6}
7object BanSheng {
8 def add(a: Int, b: Int): Int = {
9 a + b
10 }
11 def main(args: Array[String]): Unit = {
12 BanSheng.add(1, 2) // 静态函数
13 val banSheng = new BanSheng
14 banSheng.add2(3, 4)
15 }
16}
javap BanSheng.class反编译后,
1public class com.padluo.spark.scala.basic.BanSheng {
2 public static void main(java.lang.String[]);
3 public static int add(int, int);
4 public int add2(int, int);
5 public com.padluo.spark.scala.basic.BanSheng();
6}
伴生对象的apply方法,
1package com.padluo.spark.scala.basic
2class BanSheng(id: Int) {
3 def add2(a: Int, b: Int): Int = {
4 a + b
5 }
6}
7object BanSheng {
8 def apply(id: Int): BanSheng = {
9 println("----apply-----")
10 new BanSheng(id)
11 }
12 def add(a: Int, b: Int): Int = {
13 a + b
14 }
15 def main(args: Array[String]): Unit = {
16 BanSheng.add(1, 2) // 静态函数
17 val banSheng = new BanSheng(1)
18 banSheng.add2(3, 4)
19 val c = BanSheng(200)
20 val cc = BanSheng.apply(200)
21 }
22}
单例模式,
1package com.padluo.spark.scala.basic
2class SingleTon {
3}
4object SingleTon {
5 private var s:SingleTon = null
6 def getInstance():SingleTon = {
7 if(s == null) {
8 new SingleTon()
9 } else {
10 s
11 }
12 }
13 def main(args: Array[String]): Unit = {
14 val singleTon = SingleTon.getInstance()
15 println(singleTon)
16 }
17}
继承
继承关键词extends,多个用with。
某类如果不想被继承,可定义为final类型
用super调用父类的方法或属性
重写方法时必须用override,可以重写字段,不想被重写则定义为final类型
只有主构造器可以调父类的主构造器
Father.scala
1package com.padluo.spark.scala.basic
2class Father(name: String, age: Int) {
3 def doEat(food: String) {
4 println("eatting .." + food)
5 }
6 def printInfo2() {
7 println("name:" + name + ",age:" + age)
8 }
9}
Son.scala
1package com.padluo.spark.scala.basic
2class Son(name: String, age: Int, addr: String) extends Father(name, age) {
3 // 子类把name和age传入到父类中
4 override def doEat(food: String) {
5 println("my eatting .." + food)
6 }
7 def printInfo() {
8 super.printInfo2()
9 println("name:" + name + ",age:" + age + ",addr:" + addr)
10 }
11}
12object Son {
13 def main(args: Array[String]): Unit = {
14 val s: Son = new Son("zhangsan", 30, "beijing")
15 s.printInfo()
16 }
17}
Scala类层级结构,
Scala里,每个类都继承自通用的名为Any的超类。因为所有的类都是Any的子类,所以定义在Any中的方法就是“共同的”方法:它们可以被任何对象调用。
因为每个类都继承自Any,所以Scala程序里的每个对象都能用==、!=或equals比较,用hashCode做散列,以及用toString转为字符串。Any类里的等号和不等号方法被声明为final,因此他们不能再子类里重写。实际上,==
总是与equals相同,!=
总是与equeal相反。因此,独立的类可以通过重写equals方法改变==
或!=
的意义。
Any有两个子类:AnyVal和AnyRef(相当于Java里的Object)。
AnyVal是Scala里每个内建值类的父类。有9个这样的值类:Byte、Short、Char、Int、Long、Float、Double、Boolean和Unit。其中的前8个都对应到Java的基本类型。这些值类都被定义为既是抽象的又是final的,不能使用new创造这些类的实例。Unit被用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()。
AnyRef类是Scala里所有引用类(reference class)的基类。它其实是Java平台上java.lang.Object类的别名。因此Java里写的类和Scala里写的都继承自AnyRef。
Scala类与Java类的不同在于它们还继承自一个名为ScalaObject的特别trait。是想要通过ScalaObject包含的Scala编译器定义和实现的方法让Scala程序的执行更高效。
scala.Null和scala.Nothing是用统一的方式处理Scala面向对象类型系统的某些“边界情况”的特殊类型。Null类是null引用对象的类型,它是每个引用类(继承自AnyRef的类)的子类。Null不兼容值类型。Nothing类型在Scala的类层级的最低端;它是任何其他类型的子类型。然而,根本没有这个类型的任何值。Nothing的一个用处是它标明了不正常的终止。
Trait特质
为什么不可以继承多个父类?原因是多个父类里有相同函数或属性时,无法控制用哪个。
Scala的Trait相当于Java里的Interface,但Trait不仅可以定义函数,还可以有函数体实现。实现关键词是extends,实现多个Trait用with。当extends的多个Trait里有相同函数时,子类必须重写该函数。
父trait里无函数体的函数,子类必须override
重写父类里有函数体的函数,必须有关键词override
trait里的变量,都是val类型
在trait里定义的的变量,必须是val类型,如果变量没初始化,子类必须override
案例1,
1trait TestTrait {
2 def fun()
3}
反编译后为
1public interface com.padluo.spark.scala.basic.TestTrait {
2 public abstract void fun();
3}
当def fun()改为def fun(){} 时,反编译结果如何?
1trait TestTrait {
2 def fun() {}
3}
反编译后为(有问题???)
1D:\Java\idea\IdeaProjects\spark-study\spark-core\target\classes\com\padluo\spark\scala\basic>javap TestTrait.class
2Compiled from "TestTrait.scala"
3public abstract class com.padluo.spark.scala.basic.TestTrait$class {
4 public static void fun(com.padluo.spark.scala.basic.TestTrait);
5 public static void $init$(com.padluo.spark.scala.basic.TestTrait);
6}
7D:\Java\idea\IdeaProjects\spark-study\spark-core\target\classes\com\padluo\spark\scala\basic>javap TestTrait$class.class
8Compiled from "TestTrait.scala"
9public abstract class com.padluo.spark.scala.basic.TestTrait$class {
10 public static void fun(com.padluo.spark.scala.basic.TestTrait);
11 public static void $init$(com.padluo.spark.scala.basic.TestTrait);
12}
案例2,
1trait TestTrait {
2 def fun() {
3 println("---")
4 }
5 def fun200()
6}
反编译后为(有问题)
1D:\Java\idea\IdeaProjects\spark-study\spark-core\target\classes\com\padluo\spark\scala\basic>javap TestTrait.class
2Compiled from "TestTrait.scala"
3public abstract class com.padluo.spark.scala.basic.TestTrait$class {
4 public static void fun(com.padluo.spark.scala.basic.TestTrait);
5 public static void $init$(com.padluo.spark.scala.basic.TestTrait);
6}
7D:\Java\idea\IdeaProjects\spark-study\spark-core\target\classes\com\padluo\spark\scala\basic>javap TestTrait$class.class
8Compiled from "TestTrait.scala"
9public abstract class com.padluo.spark.scala.basic.TestTrait$class {
10 public static void fun(com.padluo.spark.scala.basic.TestTrait);
11 public static void $init$(com.padluo.spark.scala.basic.TestTrait);
本文首发于steem,感谢阅读,转载请注明。
https://steemit.com/@padluo
读者交流电报群
https://t.me/sspadluo
知识星球交流群
以上是关于Scala的ClassObjectTrait的主要内容,如果未能解决你的问题,请参考以下文章