1、定义一个Student类:
package com.aura.scala.day03
/**
* 在scala的一个代码文件中,可以同时定义多个类
* 而且这多个类可以都是public的。那么其实如果没有使用任何的修饰,那么这个类其实就是pulbic的
* java定义的这个public的必须和代码文件的名称一样,
* 但是,scala中, scala的代码文件的名称可以不用和public的class的名称一致
*/
class Teacher{
}
// 伴生类
class Student {
println("huangbo love java ")
/**
* 1、 在scala定义中的属性,都需要进行初始化
* 2、 使用val修饰的属性,具备getter方法, 不具备setter方法
* 3、 使用var修饰的属性,具备getter方法, 具备setter方法
* 4、 private修饰的变量,表示私有。除了自己以外,其他的任何组件都不能访问
* 但是有一个例外:
* 和当前这个类同名的object组件(对应的伴生对象)中可以访问
* class Student 伴生类
* object Student 伴生对象
* private修饰的变量,除了自己和伴生对象之外, 其他的任何组件都不能访问
* 5、 private 自己 + 伴生对象
* private[this] 自己, 伴生对象都不能访问
* 6、补充:
* 一个类中,除了属性之外,也可以定义方法
* 那么方法的访问级别:private private[this] 的效果和修饰属性一模一样
* 如果在定义一个属性, 没有加任何其他修饰符的话,默认是public的
*
* 总结:
* var val 决定是否有setter功能
* private private[this] 决定是否可以伴生对象访问
*/
val id = 9527
var name = "唐伯虎"
private var age = 18
private[this] var salary = 400000
def sum(x:Int, y:Int) :Int = {
println("hello world")
println(x, y)
x + y
}
sum(2, 3)
println("huangbo love scala ")
}
/**
* 如果要执行某个代码测试,就需要编写一个main方法的obejct组件, 而且该main方法
* 必须放在object中, 不能放在class中
*/
// 伴生对象
object Student{
def main(args: Array[String]): Unit = {
// 使用val修饰的属性,具备getter方法, 不具备setter方法
// 如果你调用了new的方式去创建一个对象,那么这个类的定义中的{}中的所有能执行的代码都会执行
// SparkContext {}中的代码有2100行左右 new SparkContext
val student: Student = new Student()
//student.id = 6379 // ××× 不允许修改
println(student.id)
// 使用var修饰的属性,具备getter方法, 具备setter方法
println(student.name)
student.name = "祝枝山"
println(student.name)
// private修饰的变量,除了自己和伴生对象之外, 其他的任何组件都不能访问
println(student.age)
// 使用private[this]修饰的变量,除了自己能访问之外,链伴生对象都不能访问
// println(student.salary) // ××× 不允许修改
}
}
2、定义一个构造器:
package com.aura.scala.day03
/**
* 在定义一个scala的类的构成中,如果这个类的类名后面没有跟 ()
* 我们认为这个类:有一个主构造器 格式:类型()
* 但是() 也可以省略(在没有参数的时候)
*
* 主构造器:直接跟在类名的后面的()就是
*
* scala中的主构造器 ===(类似,核心地位) java中的无参构造器
*
* 如何定义无参构造:
* class Student11{}
* class Student11(){}
*
* 如何定义有参构造呢?
* class Student11(var id:Int, var name:String){}
*
* 1、如果在主构造器中,属性使用var或者val修饰时,默认是public的
* 就相当于定义了一个成员变量:
* public var id:Int = 9527
* public var name:String = "唐伯虎"
*
* 2、如果属性不使用var或者val修饰,就相当于是:
* private[this] val age = 18
*
* 3、val或者var修饰的主构造器的参数自动成为成员属性
* 不使用var、val修饰,就相当于: private[this] val 修饰
* 使用private 或者 private[this]
*
* 4、有些时候,我们在定义类的构造器的时候需要禁止主构造器的使用。
*/
/**
* 主构造器也可以被私有。可以被private 和 private[this] 修饰
* 如果一个类的主构造器被: private[this] 修饰了的话, 那么如何创建对象呢?
* 使用辅助构造器
*/
class Student11 private (var id:Int, val name:String, age:Int,
private var salary:Double, private[this] val xx:Int) {
// val id = 9527
// var name = "tbh"
println("hello scala")
/**
* 这句话代码的作用:
* 相当于把主构造器中的一个不带var或者val修饰的属性在方法中使用了。
* 如果没有使用一次的话, 那就相当于是普通的主构造器的参数
*/
def myprint = println(age)
// public Student11(){} 这是java的语法定义无参构造
}
object Student11{
def main(args: Array[String]): Unit = {
// 首先执行{}
val student11: Student11 = new Student11(9527, "唐伯虎", 18, 500000, 44)
println(student11.id)
println(student11.name)
// println(student11.age) //不允许访问,private[this]
println(student11.salary)
// 私有了主构造器之后。这句代码就不能正常执行了。
// val student22: Student22 = new Student22(9527, "唐伯虎")
// 所以只能调用辅助构造器了。
val student22: Student22 = new Student22(9527, "唐伯虎", 33)
}
}
class Student22 private[this] (var id:Int, val name:String){
/**
* 定义辅助构造器有以下几个要点:
* 1、使用def进行定义
* 2、方法的名称必须是this
* 3、辅助构造器中的参数列表一般来说,都要包括主构造器中的参数列表
* 4、辅助构造器{}中的第一句代码,都要以为其他的构造器(其他的辅助构造器或者主构造器)开头
*/
def this(id:Int, name:String, age: Int) = {
// 第一句代码调用了主构造器
this(id,name)
println("helloworld")
}
def this(id:Int, name:String, age: Int, xx:String) = {
// 第一句代码调用了辅助构造器
this(id,name, age)
}
}
/**
* 两个问题:
* 1、 主构造器 和 辅助构造器的区别?
* 2、 Scala定义构造器,或者调用构造器为什么使用this ? 好处是什么?
*/
3、定义一个单例对象:
/**
* 定义类的时候: 把半生类 和伴生对象 放在一个文件中
* 其他的如果只是在当前这个文件中使用一次的类,那么可以定义在这个文件中
* 如果被使用多次,最好定义到一个独立的scala文件中
*/
/**
* 如果属性和方法定义在object组件中,就可以直接使用类名类访问
* 其实这既是java中的static的语法
*/
object ObjectTest {
def main(args: Array[String]): Unit = {
// 实例对象
val ot22: ObjectTest22 = new ObjectTest22("a", "b")
println(ot22.id)
println(ot22.m1(4))
// 静态(属性和方法)
println(ObjectTest11.id1)
println(ObjectTest11.m11(4))
// object修饰的一个类,就是一个单例对象。
val ot11_1 = ObjectTest11
val ot11_2 = ObjectTest11
println(ot11_1 == ot11_2) // true
println(ot11_1 eq ot11_2) // true
println(ot11_1 ne ot11_2) // false
println(ot11_1.equals(ot11_2)) // true
println("-------------------------------")
// 为了测试: == eq ne equals
/**
* == 在scala中,默认就是按照内容进行比较。前提是实现equals, 就是按照equals方法比较, 但是在java中, 就是比较引用
* ne eq 在scala中就是比较引用
* equals 效果等同于java中的equals
*/
val aa = new ObjectTest22("a", "b")
val bb = new ObjectTest22("a", "b")
println(aa == bb) // true
println(aa eq bb) // false
println(aa ne bb) // true
println(aa.equals(bb)) // true
println(aa.toString.equals(bb.toString)) // true
/**
* java中的this
* public void setName(String name){
* this.name = name;
* }
*/
}
}
object ObjectTest11 {
val id1:Int = 11
def m11(x:Int) = x + 1
}
class ObjectTest22(var a:String, var b:String) {
val id:Int = 11
def m1(x:Int) = x + 1
override def toString: String = a + "-" + b
override def equals(obj: scala.Any): Boolean =
this.toString.equals(obj.toString)
}
4、定义一个伴生对象:
// 伴生对象
object ObjectTestPrivate {
private val name:String = "aa"
def main(args: Array[String]): Unit = {
val oo = new ObjectTestPrivate()
val oo2 = ObjectTestPrivate
// 伴生对象,能访问伴生类中的私有成员
oo.myprint
println(oo.id)
}
}
// 伴生类
class ObjectTestPrivate{
private val id:Int = 22
// 伴生类能访问伴生对象的私有属性
private def myprint{
println(ObjectTestPrivate.name)
}
def ab1 = println("a")
def abc():Unit = {println("hello worl"); id}
val aaa = id
}
总结:
伴生类 和 伴生对象 之间可以互相访问对方的私有属性
Scala中的main方法为什么要定义在object中?
Java中main方法的定义:主方法需要定义为static类型的;在Scala中,object里面的方法都是静态方法,故需要将主方法定义在Object中。