把数据及对数据的操作方法放在一起,作为一个相互依存的整体——对象,面向
对象的三大特征:
封装
继承
多态
2、类的定义
简单类和无参方法
- class Counter{
-
- private var value =0;
-
- def increment() { value+=1};
-
- def current() =value;
-
- }
//注意:class 前面没有public 关键字修饰
如果要开发main方法,需要将main方法定义在该类的伴生对象中,即:object对
象中,(后续做详细的讨论):
在idea中创建以下文件:

- class Counter {
- private var value = 0;
-
- def increment() {
- value += 1
- };
-
- def current() = value;
-
- }
- class Student1 {
- //定义属性
- private var stuName:String = "Tom"
- private var stuAge:Int =20
-
- //成员方法
- def getStuName():String = stuName
- def setStuName(newName:String) =this.stuName=newName
-
- def getStuAge():Int = stuAge
- def setStuAge(newAge:Int) = this.stuAge=newAge
- }
- object student {
-
- def main(args: Array[String]): Unit = {
- //测试student1
- var s1 = new Student1
-
- //第一次输出
- println(s1.getStuName() + "\t" + s1.getStuAge())
-
- //调用set方法
- s1.setStuName("Mary")
- s1.setStuAge(25)
-
- //第二次输出
- println(s1.getStuName() + "\t" + s1.getStuAge())
-
- //第三次输出
- // println(s1.stuName + "\t" + s1.stuAge)
-
- }
-
- }
运行结果:
3、属性的getter和setter方法
当定义属性是private时候,scala会自动为其生成对应的get和set方法,如下所
示:
private var stuName:String = "Tom"
get方法: stuName ----> s2.stuName() 由于stuName是方法的名字,所
以可以加上一个括号
set方法: stuName_= ----> stuName_= 是方法的名字
定义属性:private var money:Int = 1000 希望money只有get方法,没有
set方法??
办法:将其定义为常量private val money:Int = 1000
private[this]的用法:该属性只属于该对象私有,就不会生成对应的set和
get方法。如果这样,就不能直接调用,例如:s1.stuName ---> 错误
//属性的get 和 set 方法
/*
1.当定义属性是private 时候,scala会自动为其生成对应的get 和set方法
private var stuName:String = "Tom"
(1) get 方法:stuName ----> s2.stuName()
(2) set 方法:stuName_=
2.定义属性:private var money:Int = 1000 希望money只有get方法,没有set方法?
方法:将其定义为常量private val money:Int = 1000
3.private[this]
3.private[this]的方法:该属性只属于该对象私有,就不会生成对应的set和get方法
*/
- class Student2 {
-
- //定义属性
-
- private var stuName:String = "Tom"
-
- //private [this] var stuAge:Int =20
-
- private var stuAge:Int = 20
-
- private val money:Int = 1000
-
-
-
- }
//测试
- object Student2 {
-
-
-
- def main(args: Array[String]): Unit = {
-
- var s2 = new Student2
-
- println(s2.stuName + "\t" + s2.stuAge)
-
- println(s2.stuName + "\t" +s2.stuAge + "\t" + s2.money)
-
-
-
- //修改money的值 --》 error
-
- //s2.money = 2000
-
-
-
- }
-
- }
4、内部类(嵌套类)
我们可以在一个类的内部在定义一个类,如下:我们在Student类中,再定义了
一个Course类用于保存学生选修的课程:
- import scala.collection.mutable.ArrayBuffer
-
-
-
- //嵌套类:内部类
-
- class Student3 {
-
- //定义一个内部类:记录学生选修的课程信息
-
- class Course(val courseName:String,val credit:Int){
-
- //定义其他方法
-
- }
-
- private var stuName:String = "Tom"
-
- private var stuAge:Int = 20
-
- //定义一个ArrayBuffer记录学生选修的所有课程
-
- private var courseList = new ArrayBuffer[Course]()
-
- //定义方法往学生信息中添加新的课程
-
- def addNameCourse(cname:String,credit:Int): Unit ={
-
- //创建新的课程
-
- var c = new Course(cname,credit)
-
- //将课程加入list
-
- courseList += c
-
- }
-
- }
//测试
- object Student3 {
-
- def main(args: Array[String]): Unit = {
-
- //创建学生对象
-
- var s3 = new Student3
-
- //给该学生添加新的课程
-
- s3.addNameCourse("Chinese",2)
-
- s3.addNameCourse("English",3)
-
- s3.addNameCourse("Math",4)
-
- //输出
-
- println(s3.stuName + "\t" + s3.stuAge)
-
- println("*********选修课程***********")
-
- for (s <-s3.courseList) println(s.courseName + "\t" + s.credit)
-
- }
-
-
-
- }
5、类的构造器
类的构造器分为:主构造器、辅助构造器
主构造器:和类的声明结合在一起,只能有一个主构造器
Student4(val stuName:String,val stuAge:Int)
(1) 定义类的主构造器:两个参数
(2) 声明了两个属性:stuName和stuAge 和对应的get和set方法
辅助构造器:可以有多个辅助构造器,通过关键字this来实现
/*
类的构造器
1.主构造器:和类的声明结合在一起;只能有一个主构造器
Student4(val stuName:String,var stuAge:Int)
(1)定义类的主构造器:两个参数
(2)声明了两个属性:stuName和stuAge 和 对应的get 和 set 方法
2.辅助构造器:可以有多个辅助构造器
通过关键字this 来实现
*/
- class Student4 (val stuName:String,val stuAge:Int) {
-
- //定义辅助构造器
-
- def this(age:Int){
-
- //调用主构造器
-
- this("no name",age)
-
- }
-
- }
- object Student4 {
-
- def main(args: Array[String]): Unit = {
-
- //创建Student4的一个对象
-
- var s4 = new Student4("Tom",20)
-
- println(s4.stuName + "\t" +s4.stuAge)
-
-
-
- //创建一个新的Student4 的对象
-
- var s42 = new Student4(25)
-
- println(s42.stuName + "\t" + s42.stuAge)
-
- }
-
-
-
- }
6、Scala中的Object对象
Scala没有静态的修饰符,但Object对象下的成员都是静态的 ,若有同名的
class,这其作为它的伴生类。在Object中一般可以为伴生类做一些初始化等操
作。下面是Java中的静态块的例子。在这个例子中,我们对JDBC进行了初始化:

而Scala中的Object就相当于Java中静态块。
在 Scala 中,是没有 static 这个东西的,但是它也为我们提供了单例模式的
实现方法,那就是使用关键字 object。
Scala 中使用单例模式时,除了定义的类之外,还要定义一个同名的 object 对
象,它和类的区别是,object对象不能带参数。
当单例对象与某个类共享同一个名称时,他被称作是这个类的伴生对象:
companion object。你必须在同一个源文件里定义类和它的伴生对象。类被称为
是这个单例对象的伴生类:companion class。类和它的伴生对象可以互相访问
其私有成员。
Object对象的应用
单例对象
//利用object 对象实现单例模式
- object CreditCard {
-
- //变量保存信用卡号,这里比较好的做法,是定义成private[this],即:该属性只属于该对象,这个方法由于定义在object中,所以是静态的,即:单例的
-
-
-
- private[this] var creditCardNumber:Long = 0
-
-
-
- //产生新的卡号
-
- def generateNewCCNumber():Long = {
-
- creditCardNumber += 1
-
- creditCardNumber
-
- }
//测试程序
- def main(args: Array[String]): Unit = {
-
- //产生新的卡号
-
- println(CreditCard.generateNewCCNumber())
-
- println(CreditCard.generateNewCCNumber())
-
- println(CreditCard.generateNewCCNumber())
-
- println(CreditCard.generateNewCCNumber())
-
- }
-
- }
使用应用程序对象:可以省略main方法;需要从父类App继承。
//使用应用程序对象,可以省略main方法
- object HelloWorld extends App{
-
-
-
- /*
- def main(args: Array[String]): Unit = {
- //这里的main就可以不写。相当于下面的代码是在main方法中执行的。
- }
- */
-
- println("Hello World")
-
- ///如何取得命令行的参数
-
- if(args.length > 0) {
-
- println(args(0))
-
- }else{
-
- println("no arguents")
-
- }
-
- }
7、Scala中的apply方法()
遇到如下形式的表达式时,apply方法就会被调用:
Object(参数1,参数2,......,参数N)
通常,这样一个apply方法返回的是伴生类的对象;其作用是为了省略new关键字

Object的apply方法举例:
- //object的apply方法
-
- class Student5(val stuName:String) {
-
- }
- object Student5 {
-
- //定义自己的apply方法
-
- def apply(stuName: String) = {
-
- println("*********Apply in Object **********")
-
- new Student5(stuName)
-
- }
-
- //如果没有这个apply方法,下面创建Mary的时候就会报错
-
-
-
- def main(args: Array[String]): Unit = {
-
- var s51 = new Student5("Tom")
-
- println(s51.stuName)
-
-
-
- var s52 = new Student5("Mary")
-
- //由于省略了new关键字,创建这个对象的时候,就会在Object找对应的apply方法
-
- println(s52.stuName)
-
- }
-
- }
8、Scala中的继承
Scala和Java一样,使用extends关键字扩展类。
案例一:Employee类继承Person类
//演示Scala的维承父类
- class Person(val name:String,val age:Int) {
-
- //定义结果
-
- def sayHello():String = "Hello" + name + " and the age is " + age
-
- }
//子类
- class Employee (override val name:String,override val age:Int,val salary:Int) extends Person(name,age){
-
- //重新父类的sayHello方法
-
- //注意override 是关键字
-
- override def sayHello(): String = "子类中的sayHello方法"
-
- }
- object Demo {
-
- //测试程序
-
- def main(args: Array[String]): Unit = {
-
- //创建一个Employee的对象
-
- var p2:Person = new Employee("Mike",25,1000)
-
- println(p2.sayHello())
-
-
-
-
-
- //使用匿名子类来创建Person对象
-
- //这里我们创建了Person的一个匿名子类,并且在该子类中重写了sayHello方法。
-
- var p3:Person = new Person("Jerry",26) {
-
- override def sayHello(): String = "匿名子类中的sayHello方法"
-
- }
-
- println(p3.sayHello())
-
- }
-
- }
案例二:在子类中重写父类的方法
//子类
- class Employee (override val name:String,override val age:Int,val salary:Int) extends Person(name,age){
-
- //重新父类的sayHello方法
-
- override def sayHello(): String = "子类中的sayHello方法"
-
- }
案例三:使用匿名子类
//使用匿名子类来创建Person对象
//这里我们创建了Person的一个匿名子类,并且在该子类中重写了sayHello方法。
- var p3:Person = new Person("Jerry",26) {
-
- override def sayHello(): String = "匿名子类中的sayHello方法"
-
- }
-
- println(p3.sayHello())
案例四:使用抽象类。抽象类中包含抽象方法,抽象类只能用来继承。
//Scala中的抽象类
//父类:抽象类
- abstract class Vehicle{
-
- //定义抽象方法
-
- def checkType():String
- }
//子类
- class Car extends Vehicle {
-
- //实现checkType 方法
-
- override def checkType(): String = {"I am a Car"}
-
-
-
- }
- class Bycical extends Vehicle {
-
- //实现checkType方法
-
- override def checkType(): String = {"I am a bike"}
-
- }
- object Demo2 {
-
- //定义两个交通工具
-
- def main(args: Array[String]): Unit = {
-
- var v1:Vehicle = new Car
-
- println(v1.checkType())
-
-
-
- var v2:Vehicle = new Bycical
-
- println(v2.checkType())
-
- }
-
-
-
- }
案例五:使用抽象字段。抽象字段就是一个没有初始值的字段
- package class4
-
- //Scala中的抽象字段:就是没有初始值的字段
-
- //抽象的父类
-
- abstract class Person{
-
- //第一个抽象字段,并且只有get方法
-
- val id:Int
-
- //另一个抽象字段,并且有get和set方法
-
- var name:String
-
- }
-
- //子类:应该提供抽象字段的初始值,否则该子类也,应该是抽象的
-
- abstract class Employee1 extends Person {
-
- //val id:Int = 1
-
- var name:String = "No Name"
-
- }
-
- class Employee2(val id:Int) extends Person {
-
- var name:String = "No Name"
-
- }
-
- object Demo3 {
-
- def main(args: Array[String]): Unit = {
-
- var a:Person = new Employee2(1)
-
- println(a.id,a.name)
-
- }
-
- }
9、Scala中的trait(特质)
trait就是抽象类。trait跟Java抽象类最大的区别:trait支持多重继承
- package class4
-
-
-
- /*
- * Scala中的trait
- * 1.trait 就是抽象类
- * 2.区别:trait 支持多重继承
- */
-
-
-
- //第一个trait
-
- trait Human {
-
- val id:Int
-
- val name:String
-
-
-
- //方法
-
- def sayHello():String = "Hello" + name
-
- }
-
-
-
- //第二个trait
-
- trait Actions {
-
- //抽象方法
-
- def getActionNames():String
- }
- //子类
- class Student(val id:Int,val name:String) extends Human with Actions {
-
- override def getActionNames(): String = "Action is running"
-
- }
-
- object Demo4 {
-
- def main(args: Array[String]): Unit = {
-
- //创建一个student的对象
-
- var s1 = new Student(1,"Tom")
-
- println(s1.sayHello())
-
- println(s1.getActionNames())
-
- }
-
- }
10、包的使用
Scala的包和Java中的包或者C++中的命名空间的目的是相同的:管理大型程序中的名称。
Scala中包的定义和使用:
包的定义
包的引入:Scala中依然使用import作为引用包的关键字,例如
而且Scala中的import可以写在任意地方
11、包对象
包可以包含类、对象和特质,但不能包含函数或者变量的定义。很不幸,这是
Java虚拟机的局限。把工具函数或者常量添加到包而不是某个Utils对象,这是
更加合理的做法。Scala中,包对象的出现正是为了解决这个局限。Scala中的包
对象:常量,变量,方法,类,对象,trait(特质)
package class4
//Scala中的包对象:常量,变量,方法,类,对象,trait(特质)
//定义一个包对象
- package object MyPackageObject {
-
- //常量
-
- val x:Int = 0
-
- //变量
-
- var y:String = "Hello World "
-
- //方法
-
- def sayHelloWorld():String = "Hello World"
//类
- class MyTestClass {
-
- }
-
- //对象object
-
- object MyTestObject {
-
- }
-
- //特质 trait
-
- trait MyTestTrait {
-
- }
-
- }
- class Demo3 {
-
- //测试
-
- def method1 = {
-
- //导入需要的包对象
-
- import class4.MyPackageObject._
-
- //定义MyTestClass的一个对象
-
- var a= new MyTestClass
-
- }
-
- }
12、Scala中的文件访问
读取行
val source = scala.io.Source.fromFile("d:\\temp\\a.txt")
println(source.mkString)
val lines = source.getLines()
for(l<-lines) println(l.toString)
读取字符
val source = scala.io.Source.fromFile("d:\\temp\\a.txt")
for(c <-source) println(c)
其实这里的source就指向了这个文件中的每个字符。