1. 面向对象的基本概念
把数据及对数据的操作方法放在一起,作为一个相互依存的整体——对象
面向对象的三大特征:
封装
继承
多态
2. 类的定义
简单类和无参方法:
class Counter {
private var value = 0
def increment(){value += 1}
def current() = value
}
注意没有class前面没有public关键字修饰。
/**
* 代表学生信息
*/
class Student1 {
//定义学生属性
private var stuId : Int = 0
private var stuName : String = "Tom"
private var age : Int = 20
//定义方法(函数) get set
def getStuName() : String = stuName
def setStuName(newName : String) = {
this.stuName = newName
}
}
注意:如果要开发main方法,需要将main方法定义在该类的伴生对象中,即:object对象中
/**
* 测试student1类,创建main函数,写到object里面
*
* 注意object和class的名字 可以不一样
* 如果一样的话,这个object就叫做class的伴生对象
*/
object Student1{
def main(args: Array[String]): Unit = {
// 创建一个学生对象
var s1 = new Student1
//访问属性并输出
println(s1.getStuName())
//访问set方法
s1.setStuName("Andy")
println(s1.getStuName())
println("-----访问私有属性--------")
println(s1.stuId + "\t" + s1.stuName + "\t" + s1.age)
}
}
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方法。如果这样,就不能直接调用。
1. 内部类(嵌套类)
我们可以在一个类的内部在定义一个类,如下:我们在Student类中,再定义了一个Course类用于保存学生选修的课程。
import scala.collection.mutable.ArrayBuffer
/**
* 内部类
*
* 需求:定义一个学生类,同时要保存学生的成绩信息
*/
class Student2 {
//定义学生属性
private var stuName:String = "Tom"
private var stuAge:Int = 20
//定义一个数组保存学生的课程成绩
private var courseList = new ArrayBuffer[Course]()
//定义一个函数,用于添加学生的课程成绩
def addNewCourse(cname:String,grade:Int): Unit ={
//创建课程的成绩信息
var c = new Course(cname,grade)
//添加到学生对象中 courseList中
courseList += c
}
//定义课程类:主构造器,即把属性写在类名后面
class Course (var courseName:String,var grade:Int) {
}
}
object Student2 {
def main(args: Array[String]): Unit = {
//测试程序 创建学生对象
var s = new Student2
//给学生添加课程信息
s.addNewCourse("Chinese",80)
s.addNewCourse("Math",70)
s.addNewCourse("English",50)
println(s.stuName + "\t" + s.stuAge)
println("-------课程信息----------")
for (c <- s.courseList) println(c.courseName + "\t" + c.grade)
}
}
4. 类的构造器
类的构造器分为:主构造器、辅助构造器
主构造器:和类的声明结合在一起,只能有一个主构造器
辅助构造器:可以有多个辅助构造器,通过关键字this来实现
(1) 定义类的主构造器:两个参数
(2) 声明了两个属性:stuName和stuAge 和对应的get和set方法
/**
* 类的主构造器和辅助构造器
*/
class Student3(var stuName:String,var age:Int) {
//属性
private var gender : Int = 1
/**
* 定义辅助构造器,辅助构造器可以有多个
* 辅助构造器就是一个函数,只不过这个函数的名字叫 this
*/
def this(age:Int){
this("Mike",age) // 相当于 new student3("Mike",age)
println("这是辅助构造器 this(age:Int)")
}
def this(){
this(10) // 相当于 new student3("Mike",10)
println("这是辅助构造器 this()")
}
}
object Student3 {
def main(args: Array[String]): Unit = {
println("----使用主构造器--------")
//使用主构造器创建学生对象
var s1 = new Student3("Tom",20)
println(s1.stuName + "\t" + s1.age)
println("----使用辅助构造器--------")
//使用辅助构造器创建学生对象
var s2 = new Student3(20)
s2.gender = 0
s2.stuName = "Lily"
println(s2.stuName + "\t" + s2.age + "\t" + s2.gender)
}
}
5. Scala中的Object对象
Scala没有静态的修饰符,但Object对象下的成员都是静态的 ,若有同名的class,这其作为它的伴生
类。在Object中一般可以为伴生类做一些初始化等操作。
/**
* 实现单例模式
*/
object CreditCard {
//定义一个变量保存信用卡的卡号 private [this] 代表不会自动生成set get 方法
private [this] var creditCardNumber : Long = 0
//定义函数来产生卡号
def generateCCNumber() : Long = {
creditCardNumber += 1
creditCardNumber
}
//测试程序
def main(args: Array[String]): Unit = {
println(CreditCard.generateCCNumber())
println(CreditCard.generateCCNumber())
println(CreditCard.generateCCNumber())
println(CreditCard.generateCCNumber())
println(CreditCard.generateCCNumber())
println(CreditCard.generateCCNumber())
}
}
使用APP对象:应用程序对象
好处:可以省略main方法。
/**
* APP对象
*/
object HelloWorld extends App{
println("Hello world")
if (args.length > 0) {
println("有参数")
} else {
println("没有参数")
}
}
6. Scala中的apply方法
遇到如下形式的表达式时,apply方法就会被调用:
Object(参数1,参数2,......,参数N)
通常,这样一个apply方法返回的是伴生类的对象;其作用是为了省略new关键字
class Student4(var stuName:String)
/**
* 定义Student4的apply方法
*/
object Student4 {
def apply(name:String) = {
println("调用了apply方法")
new Student4(name)
}
def main(args: Array[String]): Unit = {
//使用主构造器创建学生对象
var s1 = new Student4("Tom")
println(s1.stuName)
//通过apply方法创建学生对象
var s2 = Student4("Mary")
println(s2.stuName)
}
}
7. Scala中的继承
Scala和Java一样,使用extends关键字扩展类。
/**
* 继承
* 父类 Person 人
* 子类 Emplyee 员工
*/
//定义父类
class Person(val name:String,val age:Int){
//定义函数
def sayHello() : String = "Hello " + name + " and the age is " + age
}
//定义子类
/**
* 使用 override 关键字,把子类的属性,覆盖父类的属性
*/
class Emplyee(override val name:String,override val age:Int,val salary:Int)
extends Person(name,age){
override def sayHello(): String = "子类中的sayHello"
}
object Demo1 {
def main(args: Array[String]): Unit = {
//创建Person对象
var p1 = new Person("Tom",20)
println(p1.name + "\t" + p1.age)
println(p1.sayHello())
//创建子类对象
var p2 : Person = new Emplyee("Mike",20,1000)
println(p2.sayHello())
//通过匿名子类来实现继承:没有名字的子类
var p3 : Person = new Person("Mary",20){
override def sayHello(): String = "匿名子类中的sayHello"
}
println(p3.sayHello())
}
}
/**
* 抽象类
*/
//父类:抽象类 ----交通工具类
abstract class Vehicle{
// 定义抽象方法 但不需要实现
def checkType() : String
}
//子类:自行车、汽车 从父类继承
class Car extends Vehicle{
override def checkType(): String = "I am a Car"
}
class Bike extends Vehicle{
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 Bike
println(v2.checkType())
}
}
9.Scala中的trait(特质)
trait就是抽象类。trait跟抽象类最大的区别:trait支持多重继承
/**
* trait
*
* 定义两个父类,定义两个trait
* 人 动作
* 子类:
* 学生
*/
trait Human{
//抽象字段
val id : Int
val name : String
}
trait Action{
//定义一个抽象函数
def getActionName() : String
}
//定义子类
class Student(val id:Int,val name:String) extends Human with Action{
//需要实现getActionName方法
override def getActionName(): String = "Action is running"
//extends Human with Action , Action2 就是多重继承
}
object Demo1 {
def main(args: Array[String]): Unit = {
//创建学生对象
var s1 = new Student(1,"Tom")
println(s1.id + "\t" + s1.name)
println(s1.getActionName())
}
}
10.包的使用
Scala的包和Java中的包或者是c++中的命名空间的目的是相同的,管理大型程序中的名称。
包的定义:package
包的引入:Scala中依然使用import作为引用包的关键字
Scala中的import可以写在任意地方
11.包对象
包可以包含类、对象和特质,但不能包含函数或者变量的定义。很不幸,这是Java虚拟机的局限。
把工具函数或者常量添加到包而不是某个Utils对象,这是更加合理的做法。Scala中,包对象的出现正
是为了解决这个局限。
Scala中的包对象:常量,变量,方法,类,对象,trait(特质)
package object test {
//常量
val x:Int = 0
//变量
var y:String = "HelloWorld"
//方法
def helloWorld():String= "helloworld"
//类
class MyTestClass{
}
//object
object MyTestObject{
}
//特质
trait MyTrait{
}
}
object Test{
def main(args: Array[String]): Unit = {
print(test.x)
}
}