定义
定义类 class
package tcode.chapter06
object $01_ClassDefind {
class Person
/
java中创建类: [public] class 类名{..}
scala中没有public关键字,默认就是public效果的
scala中创建类: class 类名{..}
scala中创建类的对象: new 类名(..)
/
def main(args: Array[String]): Unit = {
val person = new Person<br /> println(person)<br /> }<br />}
定义方法和字段method、field
package tcode.chapter06
object $02_ClassMethodFields {
class Person{
//属性
//
val name:String = “zhangsan”
var age = 20<br /> //在class中var修饰的属性可以通过_赋予初始值,使用_赋予初始值的时候,属性的类型必须指定<br /> var sex:Boolean = _//val aa:String = _private val address = "beijing"//方法<br /> def add(x:Int,y:Int) = x+y<br /> }<br /> /<br /> java在class中定义属性: [修饰符] 类型 属性名 = 值;<br /> java在class中定义方法: 修饰符 返回值类型 方法名(类型 参数名,...){..}<br /> scala在class中定义属性: [修饰符] val/var 属性名:类型 = 值<br /> 在class中var修饰的属性可以通过_赋予初始值,使用_赋予初始值的时候,属性的类型必须指定<br /> scala在class中定义方法: [修饰符] def 方法名(参数名:类型,..):返回值类型 = {...}<br /> /<br /> def main(args: Array[String]): Unit = {<br /> val person = new Person<br /> println(person.name)<br /> //person.name = "lisi"<br /> println(person.age)<br /> person.age=100<br /> println(person.age)println(person.sex)println(person.add(10, 20))<br /> }<br />}
定义构造器constructer
package tcode.chapter06object $03_ClassContruct {/scala中构造器分为两种: 主构造器、辅助构造器主构造器定义位置: 定义在类名后面用()表示语法: class 类名([修饰符] [val/var] 属性名:类型=默认值,.... )使用val/var修饰的非private属性与不用val/var修饰的属性的区别:使用val/var修饰的非private属性既可以在class内部访问也可以在class外部访问不用val/var修饰的属性只能在class内部访问辅助构造器定义位置: 定义在class内部语法: def this(参数名:类型,...){辅助构造器第一行必须调用主构造器或者是其他的辅助构造器this(...)}/class Person(private val name:String ,var age:Int,address:String){// 主构造器def this(name:String){this(name,200,"")}def this(name:String,age:Int){this(name)}def getAddress() = this.address}def main(args: Array[String]): Unit = {val person = new Person("lisi",20,"shenzhne")println(person.age)println(person.getAddress())val person2 = new Person("wangwu")println(person2.age)}}
特性
封装性private
@BeanProperty
package tcode.chapter06import com.alibaba.fastjson.JSONimport com.alibaba.fastjson.serializer.SerializeFilterimport scala.beans.BeanPropertyobject $04_Private {class Person{@BeanProperty/ private /val name:String = "lisi"@BeanProperty/private /var age:Int = _/def getName() = this.namedef setAge(age:Int) = this.age=agedef getAge() = this.age/}/scala为了兼容java的api,提供了@BeanProperty,该注解能够自动生成属性的set/get方法@BeanProperty不能与private一起使用/def main(args: Array[String]): Unit = {val person = new Person/ println(person.getName())person.setAge(100)println(person.getAge())///json操作//对象转jsonval json = JSON.toJSONString(person, null.asInstanceOf[Array[SerializeFilter]])println(json)//json转对象val js = """{"name":"wangwu","age":200}"""val p = JSON.parseObject(js,classOf[Person])println(p.age)}}
继承性 extend
package tcode.chapter06object $05_Extends {class Person{private val name = "lsii"val sex = "man"var age = 20def add(x:Int,y:Int) = x+y}class Student extends Person{override val sex = "woman"//重写方法override def add(x:Int,y:Int) = {val k = xysuper.add(k,x)}}/java中通过extends关键字实现继承scala中通过extends关键字实现继承哪些不能被继承1、final修饰的class不能被继承2、父类private修饰的成员不能被继承如果父类定义的成员/方法不适用于子类,子类可以通过override关键字重写val修饰的属性/方法,为什么是val?因为可变的不需要重写,直接改即可子类中可以通过super关键字来调用父类的方法多态: 父类的引用子类的实例/def main(args: Array[String]): Unit = {val student = new Studentprintln(student.sex)println(student.age)//多态val p:Person = new Studentprintln(p.sex)println(p.age)}}
抽象性
😍抽象
package tcode.chapter06object $07_AbstractClass {abstract class Dog{//具体属性var age:Int =100var sex:Int//抽象属性val name:String//具体方法def sum(x:Int,y:Int) = x+y//抽象方法def add(x:Int,y:Int):Int}class Pig extends Dog{override var sex: Int = 100override val name: String = "lisi"//重写抽象方法override def add(x: Int, y: Int): Int = x-y}/java中创建抽象类: public abstract class 类名{..}java的抽象类中可以定义抽象方法scala抽象类的语法: abstract class 类名{..}scala抽象类中既可以定义抽象方法,也可以定义具体方法scala抽象类中既可以定义抽象属性也可以定义具体属性抽象方法: 没有方法体的方法称之为抽象方法,定义抽象方法的时候如果方法返回值类型没有定义默认是Unit抽象属性: 没有初始化的属性称之为抽象属性/def main(args: Array[String]): Unit = {val pig = new Pigprintln(pig.add(10,20))println(pig.name)println(pig.sum(20, 30))println(pig.age)println(pig.sex)//匿名子类val dog = new Dog {override var sex: Int = 20override val name: String = "zhangsan"override def add(x: Int, y: Int): Int = xy}println(dog.name)}}
🤩特质
特质实现extends .. with .. with..
package tcode.chapter06object $10_TratiDefined {trait Logger{//具体属性val name = "lisi"//抽象属性val age:Int//抽象方法def add(x:Int,y:Int):Int//具体方法def hello() = println("Hello..........")}trait Logger2trait Logger3class Aclass ErrorLogger extends A with Logger with Logger2 with Logger3 {override val age: Int = 100override def add(x: Int, y: Int): Int = x+y}/特质: 类似java的接口scala单继承多实现特质的语法: trait 特质名{...}, trait相当于interface特质中既可以定义抽象方法也可以定义具体方法特质中既可以定义抽象属性也可以定义具体属性特质的实现:1、子类不需要继承父类,只需要实现接口的时候,此时第一个接口的实现通过extends实现,其他接口通过with关键字实现2、子类需要继承父类, 此时通过extends关键字继承父类,特质的实现通过with关键字实现总结:必须写extends,父类相比接口优先/def main(args: Array[String]): Unit = {val logger = new ErrorLoggerprintln(logger.name)println(logger.age)}}
特质混入with
package tcode.chapter06
object $11_TraitObject {
trait Logger{
val name = “lisi”
val age = 20
def add(x:Int,y:Int) = x+y
}
class ErrorLogger
/
特质的混入: 让某个对象拥有指定trait的所有属性/方法
语法: new 类名(…) with 特质名
/
def main(args: Array[String]): Unit = {
val logger = new ErrorLogger with Logger //new 类名(…) with 特质名
println(logger.name)val logger2 = new ErrorLogger<br /> // println(logger2.name)<br /> }<br />}
特质叠加extends .. with .. with..
package tcode.chapter06
object $12_TraitAdd {
trait ParentLogger{
def add(x:Int,y:Int):Int = {
println(“ParentLogger: add”)
x/y
}
}
trait Logger1 extends ParentLogger{
override def add(x:Int,y:Int):Int = {<br /> println("Logger1: add")<br /> super.add(x+y,y)<br /> x<br /> }<br /> }
trait Logger2 extends ParentLogger{
override def add(x:Int,y:Int):Int = {
println(“Logger2: add”)
val k = x-y<br /> //super.add(k,x)<br /> k<br /> }<br /> }
trait Logger3 extends ParentLogger{
override def add(x:Int,y:Int):Int ={
println(“Logger3: add”)
val k = xy
super.add(x,y)
}
}
class ErrorLogger extends Logger1 with Logger2 with Logger3{
override def add(x: Int, y: Int): Int = {<br /> println("ErrorLogger: add")<br /> val k = x+y<br /> //super[Logger2].add(k,xx)<br /> super.add(k,xx)<br /> }<br /> }
/
scala中特质可以多实现,所以如果实现的多个特质中都有同名方法【参数列表也一样】,此时子类调用默认会报错
解决方案: 在子类中重写同名方法
子类通过super关键字调用父trait的同名方法的时候,默认是调用继承顺序最右边的trait的同名方法
子类如果想要调用指定父trait的方法可以通过 super[特质名].方法名 的方式调用
子类如果有继承多个父trait,这多个父triat有同一个父trait的时候,调用同名方法的时候是按照继承顺序从右向左调用
/
def main(args: Array[String]): Unit = {
val logger = new ErrorLogger<br /> println(logger.add(10, 20))<br /> }<br />}自身类型<br />package tcode.chapter06
import java.io.{FileInputStream, FileOutputStream, ObjectInputStream, ObjectOutputStream}
import scala.beans.BeanProperty
object $13_Self {
class Student
trait ObjectReadAndWrite {
_:Serializable => // 告知程序员需要实现这个特质
//从磁盘读取对象
def read() = {
val ois = new ObjectInputStream( new FileInputStream(“d:/obj.txt”) )
val obj = ois.readObject()ois.close()obj<br /> }<br /> //将对象写入磁盘<br /> def write() = {val oos = new ObjectOutputStream( new FileOutputStream("d:/obj.txt") )oos.writeObject(this)oos.flush()oos.close()<br /> }
}
/
自身类型: 告知子类在实现trait的时候必须实现/继承某个指定的类型,起提示作用
语法: this:指定类型 =>
/
class Person extends ObjectReadAndWrite with Serializable {// 需要被告知程序员才会用
@BeanProperty<br /> var name:String = _<br /> @BeanProperty<br /> var age:Int = _<br /> }
def main(args: Array[String]): Unit = {
val person = new Person<br /> person.setAge(100)<br /> person.setName("lisi")person.write()val p = new Person<br /> val obj = p.read()<br /> val p2 = obj.asInstanceOf[Person]<br /> println(p2.getName)<br /> }<br />}
创建对象
单例对象object
package tcode.chapter06
object $08_Object {
val name = “lsii”
/
单例对象: object object名
获取单例对象: oject名,意思是要使用这个对象,直接用名字.方法即可
scala object中所有的属性与方法都是类似java static修饰的,所以可以通过 object名称.属性/方法 形式调用
scala class中所有的属性与方法都是类似java 非static修饰的,所以必须通过 对象.属性/方法 形式调用
/
def main(args: Array[String]): Unit = {
println($08_Object)// 因为是对象名,所以打印的是地址<br /> println($08_Object)// 这里打印了多个对象,但是打印出来的地址都是相同的,说明自始至终都是一个对象,即“单例”<br /> println($08_Object)<br /> println($08_Object)<br /> println($08_Object)<br /> println($08_Object.name)<br /> }<br />}
半生类和半生对象ClassAndObject
通过伴生对象的apply方法,实现不使用new方法创建对象。
package tcode.chapter06object $09_ClassAndObject {/伴生类[class]和伴生对象[object]1、class与object的名称必须一样2、class与object必须在同一个源文件[.scala]中伴生类和伴生对象能够互相访问对方private修饰的成员apply方法: 是为了简化伴生类对象的创建apply方法必须定义在伴生对象中定义apply方法之后,后续可以通过 object名.apply()/object名("xx") 方式可以得到伴生类的对象/def main(args: Array[String]): Unit = {//println(Book.age)val book = new Book// 这里需要new对象,不方便println(book.getAge())println(Book.getName())// 这里直接调用方法,不需要再new了println(Book.apply().getAge()) Book.apply()等价于new Book //object名.apply()println(Book().getAge()) 记这条,这条是更简洁的写法,注意“()”不能省略,如果有参数也可以写参数 //object名()println(Book("shenzhen").address)Array("spark","scala")}}//如果想让构造器编程私有的:class Book private(val address:String)class Book(val address:String){def this() {this("xxx")}private val name = "zhangsan"def getAge() = Book.age}object Book{private val age = 100def getName() = {val book = new Bookbook.name}def apply(address:String): Book = new Book(address)def apply(): Book = new Book()}
包
//声明包
package tcode.chapter06
import java.util
object $06_Package {
/
包的作用:
1、控制作用域
2、便于管理
3、访问修饰符+包控制访问权限
java的包的用法:
1、导包: import 包名 【导包必须放在package声明之下,class声明之前】
1、导入包下所有类: import 包名.
2、导入包下某个类: import 包名.类
2、声明包: 在源文件第一行通过 package 包名
scala中包的用法:
1、声明包: 在源文件第一行通过 package 包名
2、创建包: 通过 package 包名{..} 创建包
3、导包:
scala可以在任何位置导入包
1、导入包下所有类: import 包名.
2、导入包下某个类: import 包名.类
3、导入包下多个指定类: import 包名.{类名1,类名2,..}
4、导入包下某个类并指定别名: import 包名.{类名=>别名}
5、导入包下除开某个类的所有类: import 包名.{类名=>, _}
4、包对象
语法: package object 包名{..}
作用: 包对象中定义的非private修饰的属性/方法在包中任何位置都可以使用
5、权限管控
语法:
1、修饰属性:private[包名] val/var 属性 = 值
2、修饰方法: private[包名] def 方法名(..):返回值类型 = {..}
private[包名]代表修饰的属性/方法只能在当前包下使用
/
def main(args: Array[String]): Unit = {
import java.util.{HashMap=>JavaHashMap,ArrayList,HashSet}<br /> //import java.util._<br /> val map = new JavaHashMap[String,String]()<br /> map.put("aa","bb")
}
}
//创建包
package xx{
class Student
object AA{
def main(args: Array[String]): Unit = {
println("---")<br /> println($03_ClassContruct.name)<br /> }<br /> }<br />}
5、权限管控
语法:
1、修饰属性:private[包名] val/var 属性 = 值
2、修饰方法: private[包名] def 方法名(..):返回值类型 = {..}
private[包名]代表修饰的属性/方法只能在当前包下调用,其他包不能使用
// 私有,但chapter06这个包可以调用此私有属性
object $03_ClassContruct {
private [chapter06] val name = “ldc”//声明包
package tcode.chapter06
import java.util
object $06_Package {
/
包的作用:
1、控制作用域
2、便于管理
3、访问修饰符+包控制访问权限
java的包的用法:
1、导包: import 包名 【导包必须放在package声明之下,class声明之前】
1、导入包下所有类: import 包名.
2、导入包下某个类: import 包名.类
2、声明包: 在源文件第一行通过 package 包名
scala中包的用法:
1、声明包: 在源文件第一行通过 package 包名
2、创建包: 通过 package 包名{..} 创建包
3、导包:
scala可以在任何位置导入包
1、导入包下所有类: import 包名.
2、导入包下某个类: import 包名.类
3、导入包下多个指定类: import 包名.{类名1,类名2,..}
4、导入包下某个类并指定别名: import 包名.{类名=>别名}
5、导入包下除开某个类的所有类: import 包名.{类名=>, _}
4、包对象
语法: package object 包名{..}
作用: 包对象中定义的非private修饰的属性/方法在包中任何位置都可以使用
5、权限管控
语法:
1、修饰属性:private[包名] val/var 属性 = 值
2、修饰方法: private[包名] def 方法名(..):返回值类型 = {..}
private[包名]代表修饰的属性/方法只能在当前包下使用
/
def main(args: Array[String]): Unit = {
import java.util.{HashMap=>JavaHashMap,ArrayList,HashSet}<br /> //import java.util._<br /> val map = new JavaHashMap[String,String]()<br /> map.put("aa","bb")
}
}
//创建包
package xx{
class Student
object AA{
def main(args: Array[String]): Unit = {
println("---")<br /> println($03_ClassContruct.name)<br /> }<br /> }<br />}
5、权限管控
语法:
1、修饰属性:private[包名] val/var 属性 = 值
2、修饰方法: private[包名] def 方法名(..):返回值类型 = {..}
private[包名]代表修饰的属性/方法只能在当前包下使用
// 私有,但chapter06这个包可以调用
object $03_ClassContruct {
private [chapter06] val name = “ldc”
扩展
类型检查和转换
java的类型检查和判断<br /> 1、判断对象是否属于某个类型: 对象 instanceof 类名<br /> 2、将对象强转为指定类型: (类型)对象<br /> java中class获取<br /> 1、获取对象的class形式: 对象.getClass<br /> 2、获取类的class形式: 类名.class<br /> <br /> scala中类型检查和判断<br /> 1、判断对象是否属于某个类型: 对象.isInstanceOf[类型]<br /> 2、将父类对象强转为指定类型: 对象.asInstanceOf[类型]<br /> scala中class获取<br /> 1、获取对象的class形式: 对象.getClass,通过父类.getclass来知道到底是哪个子类实现了多态<br /> 2、获取类的class形式: classOf[类名]
package tcode.chapter06import scala.util.Randomobject $14_TypeCheck {val RED = "red"def main(args: Array[String]): Unit = {val animal = getAnimalprintln(animal.getClass)if(animal.isInstanceOf[Pig]){println(animal.asInstanceOf[Pig].name)}else{println(animal.asInstanceOf[Dog].age)}}class Animalclass Pig extends Animal {val name = "lisi"}class Pig2 extends Pigclass Dog extends Animal {val age = 20}def getAnimal() = {val index = Random.nextInt(10)if(index%3==0){new Pig2}else if(index%5==0){new Dog}else{new Pig}}}
枚举类和应用类
1)说明
枚举类:需要继承Enumeration
应用类:需要继承App
2)案例实操
object Test {def main(args: Array[String]): Unit = {println(Color.RED)}}// 枚举类object Color extends Enumeration {val RED = Value(1, "red")val YELLOW = Value(2, "yellow")val BLUE = Value(3, "blue")}// 应用类object Test20 extends App {println("xxxxxxxxxxx");}
Type定义新类型
1)说明
使用type关键字可以定义新的数据数据类型名称,本质上就是类型的一个别名
type 别名 = 类型
2)案例实操
object Test {def main(args: Array[String]): Unit = {type S=Stringvar v:S="abc"def test():S="xyz"}}
