Scala面向对象

定义类

//不用修饰符
class HelloWorld{
	//定义一个私有的field 
	private var name = "CZM"
	def fun(){
		//这是一个带参数的方法
	}

	def getName = name
	//定义一个不带参数的方法

创建对象

val helloWorld = new HelloWorld		//括号可有可无 

调用方法

//可以不写*()*
helloWorld.fun()

//不能写*()*
helloWorld.getName

getter和setter方法

  • 定义不带private的var field Scala生成面向JVM的类时,会定义成private的字段,并提供Public的getter和setter (也就是说,你在用对象调用这个值的时候,底层转换为使用pubic的getter/setter方法访问)
  • 定义带private的field,则生成的getter和setter方法也是private的,外部不能调用,只能通过暴露的方法得到
  • 定义成val field时,只会生成getter方法
  • 如果不希望生成getter和setter方法,则将field声明成privete[this]
//自动生成的getter和setter方法,通过 val var private private[this]
var name = "CZM"
/*自动生成如下代码
//getter
def name = name

//setter
def name_ = (new_name:String)
*/

//手动getter和setter
private var name= "CZM"
def name = "Your name is "+name		//错误,因为这样相当于两次定义了name

class HelloWorld {
  private var old_name= "CZM"
    def name = "Your name is "+old_name		//正确:old_name 作为类中的私有feild,仅仅提供私有的getter和setter方法,而name作为一个提供了public的getter和setter方法的feild ==> var name并重写了public的getter和setter
    def name_=(new_name: String) {		//需要注意的是这里的语法规则,**=号前后不允许有空格**
	old_name = new_name
    print("Your new name is " + old_name)
  }
}

//调用getter和setter
var helloWorld = new HelloWorld()
helloWorld.name //geter 
helloWorld.name_= "asd" //正儿八经setter
helloWorld.name = "asd"	//新型setter,将name作为返回,买一送一

privete[this]的使用

class Student{
	private var myAge = 0
	//private[this] var myAge = 0 //调用getter方法会报错,即使定义了getter和setter方法

	def age = myAge
	def age_=(newValue:Int){
		if (newValue<0){println("illegal gar!!")}
		else{myAge = newValue}
	}
	def older(s:Student){
		myAge > s.myAge 
	}
}

怀旧党专用,使用类JAVA的getter和setter方法

@BeanProperty var age = 0
@BeanProperty var age:Int = _	//使用占位符需要声明类型

//同时拥有两种调用方式
s1.getAge
s1.age

构造函数constructor

主constructor

  • 主构造函数就是与类名在一起的构造函数,关键问题是,当主构造函数定义了之后,就不能调用无参构造函数了,也就是说,主构造函数定义了最少参数的构造函数,以后就只有更多参数的了
  • 主constructor中定义的参数,如果被使用到,则会被声明成privat[this] var name
  • 如果类中没有使用到这个参数,则不会被声明,并不会有这个feild
//当然,可以设置默认参数 
class Student(name:String,age:Int){}

辅助constructor

class Student(){
	private var name = ""
	private var age = 0

	def this(name:String){
		this()		//如果不相互调用,必须调用**主构造函数**,且要在**首行 == JAVA**
		this.name = name
	}

	def this(name:String,age:Int){
		this(name)
		this.age = age
	}
}

内部类

与JAVA不同的是,Scala中的外部类的对象的内部类都是不同的类

import scala.collection.mutable.ArrayBuffer

class Class {

  class Student(name: String) {}

  val students = new ArrayBuffer[Student]()

  def getStudent(name: String) = {
    new Student(name)
  }
}

val c1 = new Class
val c2 = new Class

val s1 = c1.getStudent("CZM")		//s1: c1.Student = Class$Student@1d3f8af1
val s2 = c2.getStudent("czm")		//s2: c2.Student = Class$Student@73589106

c1.students += s1	//正确
c1.students += s2	//错误,每一个内部类都是属于对象的,而不是独立存在的

/*错误信息
Error:(21, 24) type mismatch;
found   : c2.Student
required: c1.Student
c1.students += s2
*/

object对象

由于类中定义的feild都是属于对象的,并没有属于类的字段,在JAVA中使用Static定义的字段作为所有对象共用的类的字段,在scala中提供了object来存放。

  • object 也有constructor(不属于方法的代码都是静态加载),只在第一次被调用时执行一次,不能定义带参数的constructor
  • object通常用作单例模式(只有自己一个对象),或者作为伴生对象存放静态成员,静态工具方法
  • 与class相比,object仅仅是不能定义带参数的constructor,其他都是一样的,能继承其他方法
//定义object对象
object Person {		//不能有括号,不能定义带参数的constructor
  private var name = ""
  println("This is constructor!")
  def getName = name
  println("This is constructor too!")
}
Person.getName

//让object继承抽象类
abstract class Hello {
  def syaHello(name: String): Unit
}

object HelloObject extends Hello {
  override def syaHello(name: String): Unit = {
    println("Implement from Hello, your name is " + name)
  }
}

HelloObject.syaHello("CZM")

伴生对象和伴生类

  • 在同一个.scala文件中。同名的class和object,称object为class的伴生对象,class称为object的伴生类
  • 伴生对象和伴生类之间可以相互访问private的feild
  • class中的一切属于对象
  • object中的一切属于类
class Person(name: String, age: Int) {
  def sayHello = {
    println("Hello " + name + " you are " + age + " years old, and you must have " + Person.legNum + "legs")	//需要加上Object名访问object对象变量(即使不是私有的)
  }
}

object Person {
  private var legNum = 2    def getLegNum = legNum }

val p1 = new Person("czm", 18)
p1.sayHello

Apply方法(允许重载?)

  • apply方法中一般做什么?创建一个对象,并返回对象
  • 为什么要Apply方法?让创建类对象来的更简单,直接使用 类名()即可
  • 为什么要在伴生对象中创建apply方法?因为这是一个工具方法,不应该属于对象,应该用类名调用
class Person(name: String)

object Person {
  def apply(name: String): Person = new Person(name)
}
Person("你好")

main方法

  • 为什么要main方法?作为函数的入口
  • 为什么要定义在object中?因为main是public static的,需要被JVM使用类名调用

方法1

//注意文件名与类名相同
object HelloWorld {
  def main(args: Array[String]) {
    if (args.length != 0) {
      println("Hello " + args(0))
    } else {
      println("Hello World!")
    }
  }
}

方法2:继承APP Trait

继承APP Trait,然后将需要在main中运行的代码,直接在constructor中编写。直接使用args接收传入的参数黑人问号脸??:这里的参数是来自父类APP Trait的父类DelayedInit Trait的Main方法中的args

  • 工作原理:APP Trait 继承自DelayedInit Trait 编译时会将object中的constructor中的代码放到DelayedInit Trait的delayedInit方法中执行。DelayedInit的main方法将会调用delayedInit方法(为了懒加载?)
object HelloWorld extends App{
	if (args.length != 0) {
      println("Hello " + args(0))
    } else {
      println("Hello World!")
    }
}

使用object实现枚举

  • 枚举是什么:枚举是一个特殊的类,就是固定的多个常量对象的集合
  • Scala没有提供类似JAVA中的Enum这样的枚举特性,可以使用object继承Enumeration类,并且调用Value方法来初始化枚举值
  • 调用时,直接使用Season(0),为什么,不会跟apply冲突吗?继承了Enumeration,Enumeration中的apply方法是final的,子类不允许再定义apply只能继承Enumeration的apply(详情亲看源码)

scala实现枚举

object Season extends Enumeration{
  val SPRING,SUMMER,AUTUMN,WINTER = Value	//Value方法继承于Enumeration
  //可以自定义Value的元素
  val SPRING = Value(0,"spring")
  ...
}

//调用
//Enumeration的apply方法返回一个Value对象                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
Season(0)
res0: Season.Value = SPRING

Season("spring")

java中的枚举

enum Weeday{
	SUNDAY,MONDAY.TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY;
}

//在底层
//创建了一个final的Weeday类继承Enum
//实例化各个字段为 public final static 的 Weekday 对象,存在数组$VALUES中
//定义了一个values方法,用于返回数组		//Weekday.values()
//定义了一个valueOf方法,用于返回			//Weekday.valueof("SUNDAY")
posted @ 2017-08-31 13:26  岑忠满  阅读(233)  评论(0编辑  收藏  举报