Kind:
Class:相当于java中的class,但是没有static修饰,里面的属性方法不是静态的
Object:里面的属性和方法都是静态的,可以直接调用
Trait:特质,相当于java中的接口,App就是特质
val和var
val:修饰的变量不可变,有getter方法,没有setter方法
var:修饰的变量可变,有getter方法,也有setter方法
package study3
class Dog {
val id =10
//可以用下划线作为一个临时替代,但是使用下划线作为临时替代,必须指定数据类型
var name:String =_
private val hobby = "shopping"
def shout(contain:String):Unit={
println(contain)
}
}
class Cat{
}
class Animals{
}
object enter{
def main(args: Array[String]): Unit = {
val d =new Dog
//如果没有给赋值,打印输出为null
//println(d.name)
d.name="zhangsan"
println(d.name)
d.shout("nihao!!")
// . 可以省略
d shout("wo去")
println(d.id)
}
}
JavaBeans规范定义了Java的属性是像getXXX()和setXXX()的方法。
创建一个Bean,使用@BeanProperty注解标识某个属性变量
通过getName、setName访问属性
package study3
import scala.beans.BeanProperty
class Person {
@BeanProperty var num:Int=_
val id = 11
var name:String = _
//private修饰的方法,只能在伴生类和伴生对象中进行调用
private val hobby = "hobby"
//private[this] 修饰的属性和方法只能在本类中使用
private[this] val age =20
def sayHello(): Unit ={
println("Nice to meet you!")
}
}
object Enter1{
def main(args: Array[String]): Unit = {
val person = new Person
println(person.id)
//name_=:这是scala中的setter方法 (第一种方式)
//person.name_= ("wangwu")
//第二种方式
/*person.name="wangwu"
println(person.name)*/
person.setNum(111)
println(person.getNum)
}
}
主构造器和辅助构造器
- 直接定义在类中的事主构造器,辅助构造器可有有任意多个,但是辅助构造器,首行必须调用主构造器或者其他辅助构造器.
- Java中构造器赋值,是赋值在对象当中;scala中构造器赋值,是将所赋的值给到构造器去运行.
- 构造器当中如果没有固定值,必须给赋值,如果构造器当中有默认值,可以选择赋值,如果不赋值,就会采用默认值.如果赋值则使用新赋值.
- 构造器当中参数没有通过val或var修饰,相当于用private修饰.无法通过对象掉用属性,如果用val或var修饰,被修饰的参数提升为属性,通过对象就可以调用
package study3
//主构造器
class Student(var name:String,age:Int) {
println(name)
println(age)
var color = "color"
// println(color)
//辅助构造器
def this(name:String,age:Int,color:String){
this(name,age)
this.color = color
println(color)
}
}
运行
package study3
object Student_Enter {
def main(args: Array[String]): Unit = {
//调用了主构造器
// val stu = new Student("lihua",18)
//根据传参数的多少选择调用 主/辅助构造器
val 流川枫 = new Student("流川枫",17,"red")
}
}
伴生类和伴生对象
- 一个文件中
- class的名字和object的名字相同
这时,class就是object的伴生类,object就是class的伴生对象 - 伴生类和伴生对象之间的私有属性和方法可以相互调用
apply方法
伴生对象中使用,使用时,不用再创建对象
apply方法案例:
package study3
class Wolf(name:String,age:Int) {
var eat = "sheep"
def this(name:String,age:Int,eat:String){
this(name,age)
this.eat=eat
}
}
object Wolf{
def apply(name: String, age: Int): Wolf = {
println("调用了2个参数的主构造器")
new Wolf(name, age)
}
def apply(name: String, age: Int, eat: String): Wolf = {
println("调用了3各参数的辅助构造器")
new Wolf(name, age, eat)
}
def main(args: Array[String]): Unit = {
val wolf = Wolf("灰太狼",5,"喜羊羊")
}
}
App特质
object AppDemo extends App{
println("我是main方法")
}
继承
子类继承父类,子类拥有父类当中的属性和方法,子类也有属于自己的属性和方法.
override和super关键字
- 重写父类当中的非抽象的属性或者方法,要加override关键字,在复写抽象的属性和方法的时候,可选择添加或者不加.
- 子类调用父类当中的属性或者方法要加super关键字
超类构造器
子类的主构造器可以调用父类的构造器,但是子类当中的辅助构造器无法直接调用超类的主构造器
Trait
相当于java当中的接口,在java当中实现接口通过implements,而在scala当中,无论是继承类还是实现特质trait统一使用extends
with关键字
继承父类的或是实现特质trait 的时候用extends关键字.但是如果有多个Trait,只能用一次extends,其他连接使用with关键字
抽象类
抽象的属性或者抽象的方法必须存在于抽象类或特质中
一个类继承了抽象类,必须实现抽象类当中的属性和方法
实现抽象类当中属性和方法,可以选择添加override
什么时候用override
复写非抽象属性或方法,必须加override
实现抽象类当中的抽象属性或方法以及实现特质当中的抽象属性或者方法都是选择添加override关键字
样例类
通过case class或case object定义的就是样例类
case class:多例样例类
case object:单例样例类
偏函数
是一组没有match的case语句
目的:验证传入的参数是否正确
方法定义
def 方法名(参数名:参数类型, 参数名:参数类型):返回值类型={方法体}
def 方法名(参数名:参数类型, 参数名:参数类型)={方法体}
函数定义
val 函数名 = (参数名:参数类型,参数名:参数类型)=>函数体
val 函数名:(参数类型,参数类型)=>返回值类型={函数体}
方法和函数总结
1.方法和函数定义形式不同
2.方法就是函数,函数也是对象
3.函数可以作为参数传递到方法当中
递归函数
递归函数意味着函数可以调用它本身。
object Test {
def main(args: Array[String]) {
for (i <- 1 to 10)
println(i + " 的阶乘为: = " + factorial(i) )
}
def factorial(n: BigInt): BigInt = {
if (n <= 1)
1
else
n * factorial(n - 1)
}
}
高阶函数
高阶函数(Higher-Order Function)就是操作其他函数的函数。
Scala 中允许使用高阶函数, 高阶函数可以使用其他函数作为参数,或者使用函数作为输出结果。
object High_Function {
def main(args: Array[String]): Unit = {
val fun1=(x:Int)=>{
x+1
}
val fun2=(f1:Int=>Int)=>{
f1(1)+123
}
val fun3= (f5:Int=>Int,y:Int)=>{
f5(y)
}
println(fun1(1))
println(fun2(fun1))
println(fun3(fun1, 3))
}
}
scala函数嵌套
我们可以在 Scala 函数内定义函数,定义在函数内的函数称之为局部函数。
以下实例我们实现阶乘运算,并使用内嵌函数:
局部函数有作用域,作用的范围是定义局部函数开始到所在的代码块结束
object Test {
def main(args: Array[String]) {
println( factorial(0) )
println( factorial(1) )
println( factorial(2) )
println( factorial(3) )
}
def factorial(i: Int): Int = {
def fact(i: Int, accumulator: Int): Int = {
if (i <= 1)
accumulator
else
fact(i - 1, i * accumulator)
}
fact(i, 1)
}
}
柯里化和闭包
柯里化:一个必然产生的东西,将方法原来一次传入的参数编程多次传入
object CurryDemo {
def main(args: Array[String]): Unit = {
/*//原来的方法定义
def hello(a:Int,b:Int)={
a+b
}
println(hello(10,20))
//柯里化
def curry(x:Int)(y:Int)={
x+y
}
val res: Int = curry(15)(35)
println(res)*/
//柯里化的演变(柯里化是发展的一个必然产生的形式)
/*def hello2(x:Int)={
(y:Int)=>y
}*/
def hello2(x:Int)(y:Int)=y
println(hello2(100)(200))
}
}
闭包:方法体当中运算调用了方法的参数
def hello3(x:Int)={ (y:Int)=>y+x }