1. 类的基本操作

1.1. 类的定义

object _01ClassOps {def main(args: Array[String]): Unit = {/*scala中类对应对象的构建,和java一模一样 使用关键字new,以及构造函数来完成实例的创建scala可以使用默认的无参构造器完成实例创建,同时一类如果有无参构造器,在创建对象的时候,可以省略掉()*/val p = new Person()
//      val p1 = new Person//      p.name =p.setName("刘嘉豪")p.setAge(169)p.show()}
}class Person {/*_的作用就相当于java中private String name代表默认值;如果要使用_,前面的成员变量就应该指定数据类型*/private var name:String = _private var age = 13def show(): Unit = {println(s"name=${name}\tage=${age}")}def setName(name:String):Unit = {//成员变量和局部变量命名冲突之后使用this关键字来进行区分this.name = name}def getName() = this.name//单行函数
//  def setAge(age:Int) = this.age = agedef setAge(age:Int): Unit = {if(age < 0 || age > 150) {throw new RuntimeException("地球不欢迎你~")}this.age = age}def getAge = this.age
}

1.2. 类的构造

​ scala中有两类构造器——主构造器和辅助构造器。

object _02ConstructorOps {def main(args: Array[String]): Unit = {val p = new Person("华勇", 23)p.show()}
}class Person() {private var name:String = _private var age:Int = _def Person(): Unit = {println("--Person()--是默认的构造器吗?")}//自定义构造器 自定义构造器的第一句话必须要调用其它构造器def this(name:String, age:Int) {this()this.name = namethis.age = ageprintln("---------this(name:String, age:Int)---------")}println("-------------构造器~----------------")def show(): Unit = {println(s"name=${name}\tage=${age}")}
}

本例中的这个和类的定义交织在一起的默认的构造器,是scala类中最重要的一个构造器——主构造器(默认的构造器是无参主构造器,定义在类名和类的{之间,省略了())。

其余的自定义构造器,也就是在类中通过def this(xxx)定义的构造器称之为辅助构造器,同时辅助构造器的第一句话,必须要通过this来调用本类主构造器或者其它辅助构造器

object _02ConstructorOps {def main(args: Array[String]): Unit = {val _3p = new Person(77)_3p.show()}
}class Person(var name:String, var age:Int) {def Person(): Unit = {println("--Person()--是默认的构造器吗?")}def this() {this("嘿嘿", 33)println("---this() ---")}def this(name:String) {this()this.name = nameprintln("---this(name:String) ---")}def this(age:Int) {this("龚天明")this.age = ageprintln("---this(age:Int) ---")}println("-------------构造器~----------------")def show(): Unit = {println(s"name=${name}\tage=${age}")}
}

-------------构造器~----------------
—this() —
—this(name:String) —
—this(age:Int) —
name=龚天明 age=77

1.3. 内部类

object _03InnerClassOps {def main(args: Array[String]): Unit = {val outer = new Outerval inner = new outer.Inner()inner.show()}
}class Outer { ooo =>val x = 5class Inner { iii =>val x = 6def show(): Unit = {val x = 7System.out.println("x = " + x)System.out.println("inner class x = " + iii.x)System.out.println("Outer class x = " + ooo.x)}}
}

总结:scala的内部类和java的内部类的主要区别就在内部类对象的创建方式不一样。其次scala为了灵活的在内部类的局部访问内部类成员或者外部类的成员,可以给内部类和外部类的引用提供一个别名,方便操作。
也就是说,上例中这iii.x <=> this.x, ooo.x <=> Outer.this.x
内部类使用蛮多的一个地方:就是匿名内部类。

1.4. object对象

1.给scala类提供程序运行的入口,静态的main函数

2.给scala类也来提供静态成员——scala类的伴生对象来实现。
object中的所有的成员都是static静态

1.4. 单例

object _05ObjectOps {def main(args: Array[String]): Unit = {val s1 = Singleton.getInstance()val s2 = Singleton.getInstance()println(s1 == s2)}
}//单例
class Singleton private () {var x = 5
}
/* 饿汉式
object Singleton {private val instance = new Singletondef getInstance(): Singleton = {instance}
}*/
//懒汉式
object Singleton {private var instance:Singleton = _def getInstance(): Singleton = {if(instance == null) {Singleton.synchronized {if(instance == null) {instance = new Singleton}}}instance}
}

1.5. 伴生对象

scala伴生对象的作用
1、给伴生类提供了类似于java中的静态成员
2、可以给scala的class提供一种新的对象构造方式
3、 在伴生对象中创建一个名为apply的方法,该apply方法的参数列表为class的构造函数的参数列表,二者保持对应
4、 返回值为本类,通过该apply方法来完成对象的构造
5、伴生对象,不仅可以访问对应伴生类的非私有成员,同时还可以访问对应伴生类的私有成员

object _06ObjectOps {def main(args: Array[String]): Unit = {val worker = Worker()worker.show()println("--------------")val w1 = Worker("柳泽宁", 15)w1.show()}
}
class Worker(name: String, age: Int) {def this() {this("old李", 35)}def this(name: String) {this()}def show(): Unit = {println(s"name: ${name}, age: ${age}")}
}
object Worker {//伴生对象def apply(): Worker = {new Worker()}def apply(name: String, age: Int): Worker = {new Worker(name, age)}
}

2. 类的继承体系

类与类之间的一个很重要关系——继承/扩展(extends)。

2.1. 类的扩展

继承的特点:

  1. 子类可以继承父类的所有非私有(private),非静态的成员(变量和成员方法)。
  2. 可以对父类的相关方法进行覆盖/重写
  3. 也可以添加自己独有的成员
  4. 被final修饰的父类成员,子类不可以继承
  5. 被protected修饰的父类成员,子类可以继承
  6. 子类覆盖父类的方法的异常,必须要大于等于父类的异常
  7. 子类的访问权限必须要大于等于父类
class Person {private var name:String = _protected var age:Int = 0def this(name:String, age:Int) {this()this.name = namethis.age = age}def show(): Unit = {println(s"person's name is $name")}
}class Student extends Person {age = 15def this(age:Int) {this()this.age  = age}override def show(): Unit = {super.show()//子类调用父类的成员通过super关键字println(s"Student's age is $age")}
}

person’s name is null
Student’s age is 18

override在java中是一个注解,用来表示该方法是继承的,scala中是一个关键字,必须要添加在重写的方法前面,除非该方法是抽象的。

2.2. 类型检查和转换

使用isInstanceOf来进行类型判断,asInstanceOf进行类型转换。需要注意的是这两个操作都是对象的方法。

object _02EqualsOps {def main(args: Array[String]): Unit = {val w1 = new Worker("雷德言", 33)val w2 = new Worker("雷德言", 33)println(w1.equals(w2))}
}class Worker {private var name:String = _private var age:Int = _def this(name:String, age:Int) {this()this.age = agethis.name = name}override def equals(obj: Any): Boolean = {if(!obj.isInstanceOf[Worker]) //类型检查falseelse {//类型转换val that = obj.asInstanceOf[Worker]this.name.eq(that.name) && this.age == that.age}}
}

同时scala提供另一种更加简洁的写法,来处理这些类型检查和类型转换——模式匹配

override def equals(obj: Any): Boolean = {obj match {//模式匹配case that:Worker => {this.name.eq(that.name) && this.age == that.age}case _ => false}
}

2.3. 受保护字段和方法

被修饰为protected的age字段,不能在子类中被访问,但是通过scala的特定访问权限修饰设置,

  • 在访问修饰符后面使用[]指定要访问的package,比如protected[extendz]——代表了该字段只能在extendz包及其子包下面被访问。
  • 这实际上是更加精准的访问权限控制。
  • private后面也可以加[extendz],和上面类似
object _01ProtectedOps {def main(args: Array[String]): Unit = {val stu = new Studentval person = new Person()person.name = "清华学姐"person.age = 23stu.makeFriends(person)}
}
class Person {var name: String = "刘照路"protected[extendz] var age: Int = 18
//    protected[this] var age: Int = 18private[extendz] var gender = "guy"def show(): Unit = {println(s"${name}, age: ${age}, gender: ${gender}")}
}class Student extends Person {name = "刘照路2"age = 19def makeFriends(person: Person): Unit = {println(s"姓名为:${this.name}, 年龄为${this.age}的小哥哥和${person.name}, 年龄为:${person.age}的小姐姐成为了红颜知己~")}
}

被protected[this]所修饰的变量,只能在本类,及其子类中被调用,但不可以被子类对象调用。

2.4 访问权限修饰符

scala中的访问权限修饰符就只有这么两个:private、protected,缺省相当于public

2.5 子类调用父类构造

super.show()调用父类的方法
子类只能通过主构造器来调用父类的构造器。

object _01ExtendsOps {def main(args: Array[String]): Unit = {val stu = new Student("李烨培")stu.show()}
}class Person {private var name:String = _protected var age:Int = 0println("父类Person的主构造器-------")def this(name:String, age:Int) {this()this.name = namethis.age = ageprintln("----父类Person的辅助构造器this(name:String, age:Int)------")}def this(name:String) {this(name, 0)this.name = namethis.age = ageprintln("----父类Person的辅助构造器this(name:String)------")}def show(): Unit = {println(s"person's name is $name")}
}class Student(name:String) extends Person(name) {println("子类Student的主构造器")age = 15def this(age:Int) {this("zhangsan")this.age  = ageprintln("----子类Student的辅助构造器------")}override def show(): Unit = {super.show()println(s"Student's age is $age")}
}

父类Person的主构造器-------
----父类Person的辅助构造器this(name:String, age:Int)------
----父类Person的辅助构造器this(name:String)------
子类Student的主构造器
person’s name is 李烨培
Student’s age is 15

2.5. 重写字段和方法

​ 说白了就是在字段前面加上一个override关键字即可。最主要的作用就是父类中定义的非私有非protected的字段,子类如果想要定义个同名的字段,此时就需要使用override关键字完成覆盖,如果不用报错。

​ 被覆盖的字段只能被val修饰。

​ 方法的覆盖和java的覆盖是一样的。

2.6 匿名子类

匿名子类,其实说白了就是没有名字的类,通常匿名的类就是只调用一次的,没有必要进行定义,在运行时完成创建即可。

object _03AnonymousSubClassOps {def main(args: Array[String]): Unit = {fire(new Manager("黄世仁"))println("---------------------------------------")val m = new Manager("黄世仁"){override def manage(): Unit = {super.manage()println("还有升级版:克扣工资")}def haha(): Unit = {println("哈哈哈")}}m.haha()fire(m)}def fire(manage: Manager): Unit = {manage.manage()println("所以要炒了经理的鱿鱼~")}
}
class Manager(name: String) {def manage(): Unit = {println(s"行为为${name}的经理正在对员工吆五喝六~")}
}

2.7抽象类和抽象方法、字段

  • scala中的抽象类 抽象方法 抽象字段(这在java中不存在)
  • 一个类中的方法或者字段只有定义,没有实现,那么吧这些方法或者字段称之为抽象的方法和字段,
  • 而又抽象方法或者字段的类,我们称之为抽象类,用abstract关键字来进行修饰
  • 同样,抽象方法和字段的abstract关键字可以省略,而类上面abstract可不能省略。
  • 子类如果复写了父类的抽象的成员,是可以省略掉override关键字的,但是复写非抽象成员该关键字必须要加。
object _04AbstractOps {def main(args: Array[String]): Unit = {val cat = new Cat()cat.sleep()println("------------------------------")val fish = new Fish()fish.sleep()}
}/*** 定义一个抽象类*/
abstract class Animal {val leg: Intdef sleep():Unitdef dead(): Unit = {println("动物固有一死,或清蒸,或红烧,或爆炒,这真的是太难了~")}
}
class Cat extends Animal {val leg: Int = 4def sleep(): Unit = {println("喵星人,蜷缩成一团睡觉~")}
}
class Horse extends Animal {override val leg: Int = 4override def sleep(): Unit = {println("站着睡觉的还有谁!")}
}
class Fish extends Animal {override val leg: Int = 0override def sleep(): Unit = {println("睁着眼睛睡觉,太难了我~")}
}

2.8 trait特质

  • trait特质:
  • 不管是java还是scala的继承,有一个特点:只能单继承,不能多继承,在java中来弥补这个缺陷怎么解决:
  • 1、可以多层继承
  • 2、进行多实现(implements interface)
  • 在多实现这个接口的时候,比较痛苦,如果接口方法比较少还好,但是如果方法很多,实现起来非常的麻烦
  • 所以scala有了trait这样一个概念来弥补java中的interface只能由抽象方法的缺陷
  • 所以scala中的trait比java中的接口interface内容更加的丰富,既可以拥有抽象,也可以有拥有非抽象,当trait特质中的所有
  • 方法都抽象的时候,我们就可以理解其为java中的接口。
  • trait在进行调用的时候和scala的类的调用一样,都要使用关键字extends,而java的接口实现用implements
  • java的实现多接口的时候通过多个,来进行分割。很遗憾scala扩展多个trait的时候使用关键字with来进行分割。
  • 比java中的接口还牛的一点是,可以做到动态的运行时的扩展特质————特质的混入
  • 如果scala的一个类,既要扩展一个类,又要扩展特质,那么先写类,其次用with连接trait特质
object _05TraitOps {def main(args: Array[String]): Unit = {val logger = new ConsoleLoggerlogger.log("roma was not built in one day~")println("--------------------------")val fileName = "E:/data/out/scala/fileLogger.txt"val fLoger = new FileLogger(fileName) with MySerializablefLoger.log("god help those who help themselves.")fLoger.log("love is blind.")fLoger.close()fLoger.serialize("书到用时方恨少,绝知此事要躬行。")}
}trait Logger {def log(msg: String): Unitdef show(): Unit = {println("show~")}
}trait MySerializable {//完成了序列化def serialize(msg: String): Unit = {println("serilaize: " + msg)}
}class ConsoleLogger extends Logger {override def log(msg: String): Unit = {println("consoleLogger: " + msg)}
}class FileLogger(fileName: String) extends Logger /*with MySerializable */{private val bw = new FileWriter(fileName, true)override def log(msg: String): Unit = {bw.write(msg)bw.write("\r\n")bw.flush()}def close(): Unit = {if(bw != null) {bw.close()}}
}

scala类的介绍与操作02相关推荐

  1. scala类的序列化_Scala序列理解,通用类和内部类示例

    scala类的序列化 A sequence comprehension statement consists of a generator part which generates a list of ...

  2. 利用OpenCV的VideoCapture类实现视频读操作

    图像处理开发需求.图像处理接私活挣零花钱,请加微信/QQ 2487872782 图像处理开发资料.图像处理技术交流请加QQ群,群号 271891601 博主注:后来,博主又写了一篇更为详细介绍Vide ...

  3. Scala入门到精通——第十节 Scala类层次结构、Traits初步

    本节主要内容 Scala类层次结构总览 Scala中原生类型的实现方式解析 Nothing.Null类型解析 Traits简介 Traits几种不同使用方式 1 Scala类层次结构 Scala中的类 ...

  4. java基础-BigDecimal类常用方法介绍

    java基础-BigDecimal类常用方法介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.BigDecimal类概述 我们知道浮点数的计算结果是未知的.原因是计算机二进制 ...

  5. (转)基于MVC4+EasyUI的Web开发框架形成之旅--基类控制器CRUD的操作

    http://www.cnblogs.com/wuhuacong/p/3352016.html 在上一篇随笔中,我对Web开发框架的总体界面进行了介绍,其中并提到了我的<Web开发框架>的 ...

  6. scala 类中的对象是类_Scala类和对象– Singleton对象,伴侣类

    scala 类中的对象是类 Earlier we learned about Scala Programming Language and it's installation on Windows a ...

  7. Scala编程——下界介绍与实例分析

    最近又在重温Scala编程.上bilibili网站看了韩顺平老师在尚硅谷的Scala编程语言的教学视频.发现韩老师有关Scala下界的介绍与示例说明,讲解的不是很清晰.并认为可能会给一些学习Scala ...

  8. Scala——(常用类型与字面量,Scala类层次结构,值与变量自动类型推断,操作符,块表达式和赋值语句,输出和输出,字符串插值器,对象相等性)

    文章目录 常用类型与字面量 Scala类层次结构 值与变量&自动类型推断 操作符 块表达式和赋值语句 输出和输出 字符串插值器 对象相等性 常用类型与字面量 Scala和Java一样,有8种数 ...

  9. CImage类的介绍与使用

    CImage类的介绍与使用 程序代码下载处:http://download.csdn.net/source/2098910 下载处:http://hi.baidu.com/wangleitongxin ...

最新文章

  1. 看了蚂蚁金服的布局,你或能明白马云为何一定要将支付宝独立了!
  2. 【Python基础】python使用openpyxl操作excel
  3. Linux中shell变量作用域笔记
  4. 干掉勒索病毒的22岁程序员自曝黑历史:中学是电脑白痴
  5. Java只用一个循环语句输出九九乘法表
  6. 相机标定(二)—— 投影变换相关基础概述
  7. MyBatis开发经验总结
  8. 复旦大学计算机学院邱锡鹏,复旦大学邱锡鹏教授为我院师生做学术报告
  9. VHDL实现矩阵键盘
  10. 课题申报书范文_课题申请书范例
  11. 桌面版docker安装搭建
  12. 发送短信(SMS)承载方式有哪些?
  13. [信号基础] 信号频率,采样率,采样点(快拍数)等
  14. 【影像组学】理论学习——特征类型
  15. 认认真真推荐 10 个优质自学平台
  16. Read Committed
  17. 15年上半年系统集成项目管理工程师案例分析真题及答案
  18. C++ Reference: Standard C++ Library reference: C Library: cmath: erfc
  19. C语言结构体-火车票查询程序
  20. 2021年域名投资低迷,如何看待10年后的域名及域名前景?

热门文章

  1. STM32笔记 (十三)定时器输入捕获(利用定时器捕获高电平时间)
  2. 蚂蚁通讯框架SOFABolt之私有通讯协议设计
  3. 中秋放假最新提醒,这些地方恢复跨省旅游,你选好去哪儿旅游了吗?
  4. Unity 3D中的射线与碰撞检测
  5. 360无线网卡linux驱动下载,如何在Linux下写无线网卡的驱动
  6. Flutter实践之高仿有妖气漫画,移动客户端开发工程师专业
  7. mac版python3.7安装教程_M是什么意思_M的翻译_音标_读音_用法_例句_爱词霸在线词典...
  8. linux 下 批量添加后缀名,Linux 下批量修改后缀名
  9. 想在互联网上年入百万,必须具备这两种能力!
  10. linux 查看目录挂载,linux查看磁盘挂载的三种方法