Scala 【 6 面向对象编程 】

2023-03-09 14:42:22 浏览数 (2)

scala - 面向对象编程

定义类来说不需要修饰,直接使用 class 创建即可。

代码语言:javascript复制
class HelloWorld{
	private var name = "Li"
	def sayHello(){
	print("Hello,"    " "   name)
	}
	// 不加括号的方法调用时也不能加
	def getName = name
}

// 创建对象
val helloWorld = new HelloWorld

helloWorld.getName
getter 与 setter

定义不带 private 的 var field,此时 scala 生成的面向 JVM 的类时,会定义为 private 的 name 字段,并提供 public 的 getter 和 setter 方法。

如果使用 private 修饰 field ,则生成的 getter 和 setter 也是 private 的。

如果定义 val field ,则只会生成 getter 方法。

如果不希望生成 setter 和 getter 方法, 则将 field 声明为 private[this] 。

调用 getter 和 setter 方法,分别叫做 name 和 name = 。

自己定义 getter 与 setter
代码语言:javascript复制
class Student{
	private var myName = "Li"
	def name = "your name is"   myName
	def name_=(newValue:String){
	println("you cannot edit your name!")
	}
}

如果不希望 field 有 setter 方法,则可以定义为 val ,但是此时就不能更改 field 的值了。

如果希望能够仅仅暴露出一个 getter 方法,并且还能通过某些方法更改 field 的值,那么需要综合使用 private 以及自定义 getter 方法。此时由于 field 是 private 的,所以 setter 和 getter 都是 private ,对外界没有暴露;自己可以实现修改 field 值的方法;自己可以覆盖 getter 方法。

代码语言:javascript复制
class Student {
	private var myAge = 0
	def age_=(newAge: Int){
		if(newAge > 0) myAge = newAge
		else println("illegal age!")
	}
	def age = myAge
	def older(s: Student) = {
		myAge > s.myAge
	}
}

对比:

代码语言:javascript复制
class Student{
    private[this] var myAge = 0
    def age_=(newAge:Int){
        if(newAge > 0 ) myAge = newAge
        else println("illegal age!")
    }
    def age = myAge
    def older(s:Student) = {
        myAge > s.myAge
    }
}
//在这里就不能正常定义,因为访问不到 older 方法中的 myAge 。

如果将 field 使用 private 来修饰,那么代表这个 field 是类私有的,在类的方法中,可以直接访问类的其他对象的 private field 。

如果不希望 field 被其他对象访问到,那么可以使用 private[ this ] ,意味着对象私有的 field ,只有本对象内才可以访问到。

Java 风格的 getter 和 setter 方法

Scala 的 getter 和 setter 方法的命名和 Java 是不同的,是 field 和 field_= 的方式。

如果要让 Scala 自动生成 Java 风格的 getter 和 setter 方法,在 field 添加 @BeanProperty 注解即可。

辅助 constructor

在 Scala 中,可以结合类定义多个辅助 constructor ,类似 Java 中的构造函数重载。

辅助 constructor 之间可以互相调用,而且必须第一行调用主 constructor 。

代码语言:javascript复制
class Student{
    private var name = ""
    private var age = 0
    def this(name:String){
        this()
        this.name = name
    }
    def this(name:String, age: Int){
        this(name)
        this.age = age
    }
}
主 constructor

在 Scala 中,主 constructor 是与类名放在一起的,与 Java 不同。

在类中,没有定义在任何方法或者是代码之中的代码,就是主 constructor 的代码。

代码语言:javascript复制
class Student(val name:String, val age:Int){
 println("your name is "   name   ", your age is "   age)
}

// 主 contructor 中还可以通过使用默认参数,来给参数默认的值。
class Student(val name:String = "Li", val age:Int = 30){
	println("your name is"   name   ", your age is "   age )
}

如果主 constructor 传入的参数什么修饰都没有,比如 name:String ,那么如果类内部的方法使用到了,则会声明为 private[this] name ;否则没有该 field, 就只能是被 constructor 代码使用而已,这是一种优化机制。

内部类

在 Scala 中,同样的可以在类中定义内部类,但是与 Java 不同的是,每个外部类的对象的内部类都是不同的类。

意思就是定义之后生成两个外部类,那么这两个外部类的内部类不是同一种。

0 人点赞