第一章.面向对象
1.Scala包
package com.atguigu.chapter06object $01_Package {/*** 包的好处:1.便于区分同名类 2.便于管理* java中对于包的用法:* 1.导包:导包的位置必须在package声明之后,类名之前* 2.导入包下某个类: import 包名.类名* 3.导入包下所有类: import 包名.** 4.声明包: 语法 package 包名 声明包必须在源文件第一行* scala中对于包的用法* 1.导包:scala可以在任意位置导入包* a.导入包下某个类: import 包名.类名* b.导入包下所有类: import 包名._* c.导入包下多个类: import 包名.{类名1,类名2,....}* d.导入包下某个类,并起别名: import 包名.{类名=>别名}* e.导入包下除开某个类的所有类: import 包名.{类名=>_ , _}* 2.声明包* a.语法: package 包名* b.声明包必须在源文件第一行* 3.创建包* a.语法: package 包名{....}* b.此种方式创建的包只能在classes目录才能看到* 4.包对象* a.语法: package object 包名{...}* b.包对象定义的非private的属性和方法可以在包中任何位置使用* 5.包与访问修饰符结合* a.语法: private[包名] val 属性名:类型 = 值* b.private[包名]修饰的成员只能在指定的包下使用,其他包不能使用*/private[chapter06] val sex = "man" //包与访问修饰符结合import java.util.{HashMap => JavaHashMap} //导入包下所有类class Persondef main(args: Array[String]): Unit = {val map = new JavaHashMap[String, Int]()val p = new xx.Person}}package xx{class Person}
2.定义Class
package com.atguigu.chapter06object $02_ClassDefined {/*** java创建类:[访问修饰符] class 类名{....}* java创建对象: new 类名(....)** scala创建类: class 类名{......}* scala创建对象: new 类名(.......)*/class Person{}def main(args: Array[String]): Unit = {val person = new Personprintln(person)}}
3.定义属性和方法
package com.atguigu.chapter06object $03_ClassFieldAndMethod {/*** java中class定义属性:[访问修饰符] 类型 属性名 = 值* java中class定义方法: [访问修饰符] 返回值类型 方法名(参数类型 参数名,...){...}* scala中class定义属性: [访问修饰符] val/var 属性名:类型 = 值* scala中默认是public效果* scala在class中定义属性的时候var修饰的属性可以通过_赋予初始值* scala中class定义方法: [访问修饰符] def 方法名(参数名:类型,...):返回值类型 = {....}**/class Person{//定义属性val name:String = "zhangsan"//scala在class中定义属性的时候var修饰的属性可以通过_赋予初始值var age:String = _val func = (x:Int,y:Int) => x + yprivate val address = "shenzhen"private def add(x:Int,y:Int) = x + y}def main(args: Array[String]): Unit = {val person = new Personprintln(person.name)println(person.age)println(person.func(10, 20))//println(person.address)//println(person.add(10, 20))}}
4.构造器
package com.atguigu.chapter06object $04_Contruct {/*** java中构造器的定义* 1.定义位置: 定义在类内部* 2.语法: 访问修饰符 类名(参数类型 参数名,...){...}** scala中构造器分为两种* a.主构造器* 1.定义位置: 定义在类名后面* 2.语法: class 类名([访问修饰符] [val/var] 属性名:类型 [=默认值],....)* 主构造器使用val/var修饰的属性与不使用val/var修饰的属性属性的区别* 使用val/var修饰的非private属性可以在class内部/外部都可以使用* 不使用val/var修饰的属性只能在class内部使用** b.辅助构造器* 1.定义位置: 定义在class内部* 2.语法: def this(参数名:类型){* //辅助构造器第一行必须调用其他的辅助构造器或者主构造器* this(...)* }*/class Person(private val name:String = "zhangsan",var age:Int = 20,address:String){var money:Double = _var flag:Boolean = _def this(flag:Boolean){this(address="beijing")this.flag = flag}def this(money:Double){this(true)this.money=money}}def main(args: Array[String]): Unit = {val person = new Person(address = "beijing")//println(person.name)println(person.age)//println(person.address)val person1 = new Person(10.0)println(person1.flag)println(person1.money)val person2 = new Person(false)println(person2.flag)}}
5.封装
package com.atguigu.chapter06import com.alibaba.fastjson.JSONimport com.alibaba.fastjson.serializer.SerializeFilterimport scala.beans.BeanPropertyobject $05_Private {class Person{@BeanPropertyvar name:String = _@BeanPropertyvar age:Int = _/*def setName(name:String) = this.name =namedef setAge(age:Int) = this.age =agedef getName()= this.namedef getAge()= this.age*//*** java很多Api底层都需要set/get方法,scala为了兼容java的Api,提供了一个注解@BeanProperty,该注解能够自动生成set/get方法* @BeanProperty注解不能用于private修饰的属性上**/}def main(args: Array[String]): Unit = {val person = new Person/*person.name="lisi"person.age=20println(person.name)*/person.setName("zhaoliu")person.setAge(18)println(person.getName())//对象转jsonval json = JSON.toJSONString(person, null.asInstanceOf[Array[SerializeFilter]])println(json)}}
6.继承
package com.atguigu.chapter06import scala.util.Randomobject $06_Extends {/*** java通过extends关键字实现继承* java通过@overwrite注解实现方法的重写** scala通过extends关键字实现继承* 哪些不能被继承* final修饰的class不能被继承* 父类中private修饰的成员不能被继承* scala子类可以通过override关键字实现方法实现方法与val属性的重写* var修饰的属性不能被重写* scala子类中可以通过super关键字调用父类的方法和属性* scala中的属性和方法都能做到多态,java只能方法多态*/class Person{private val name = "lisi"var age:Int = _val address:String = "shenzhen"def add(x:Int,y:Int) = x+y}class Student extends Person{//override var age:Int =0override val address:String="beijing"override def add(x:Int,y:Int):Int={x*y}}class Student2 extends Person{override val address:String="tianjin"override def add(x: Int, y: Int): Int = x-y}def main(args: Array[String]): Unit = {val student = new Studentprintln(student.age)println(student.address)println(student.add(10, 20))val person = getPerson()println(person.add(20, 10))val p:Person = new Studentprintln(p.address)}def getPerson():Person={val index = Random.nextInt(10)if(index % 2 ==0) new Studentelse new Student2}}
7.抽象类
package com.atguigu.chapter06object $07_Abstract {abstract class Animal{//具体属性val name:String ="lisi"//抽象属性val age:Int//具体方法def add(x:Int,y:Int):Int=x+y//抽象方法def m1(x:Int,y:Int):Int}class Dog extends Animal{override val age:Int = 20override def m1(x:Int,y:Int):Int = x-y}/*** java中抽象类的定义: abstract class 类名{...}** scala中抽象类的定义: abstract class 类名{....}* 抽象方法: 没有方法体的方法称之为抽象方法* 抽象属性: 没有初始化的属性称之为抽象属性** scala抽象类中既可以定义抽象属性也可以定义具体属性,既可以定义抽象方法也可以定义具体方法**/def main(args: Array[String]): Unit = {val dog = new Dogprintln(dog.age)println(dog.m1(10, 20))//匿名子类val animal = new Animal {override val age: Int = 100override def m1(x: Int, y: Int): Int = x+y}println(animal.age)}}
8.单例对象(伴生对象)
Scala语言是完全面向对象的语言,所以并没有静态的操作(即在Scala中没有静态的概念)。但是为了能够和Java语言交互(因为Java中有静态概念),就产生了一种特殊的对象来模拟类对象,该对象为单例对象。若单例对象名与类名一致,则称该单例对象这个类的伴生对象,这个类的所有“静态”内容都可以放置在它的伴生对象中声明。
package com.atguigu.chapter06object $08_Object {/*** 单例对象: object object名称{....}* object中定义的所有属性和方法都是类似java static修饰的,可以通过 object名称.属性名/方法名 调用* class中定义的所有属性和方法都是类似java 非static修饰的** 伴生类[class]和伴生对象[object]* 必须满足两个条件* a.class与object的名称必须一致* b.class与object必须在同一个.scala源文件中* 伴生类和伴生对象的特性:可以互相访问对方private修饰的成员* apply方法[主要是为了简化伴生类对象的创建]* 定义位置: 必须定义在伴生对象中* 定义apply方法之后,就可以通过 object名称.apply(...)/object名称(...) 获取伴生类的对象*/def main(args: Array[String]): Unit = {println($08_Object)Person.xx()new Person().yy()println(Person.getAge())val person = Person.apply("beijing")person.yy()val person2 = Person("tianjin")println(person2.getName())}}class Person(val address:String){def this(){this("")}private val age =20def yy()=println("++++++++++++++++++")def getName()= Person.name}object Person{private val name ="lisi"def xx()= println(".............")def getAge()= new Person().agedef apply(address:String):Person = new Person(address)def apply():Person = new Person()}
9.特质
- Scala语言中,采用特质trait(特征)来代替接口的概念,也就是说,多个类具有相同的特征(特征)时,就可以将这个特质(特征)独立出来,采用关键字trait声明。
- Scala中的trait中即可以有抽象属性和方法,也可以有具体的属性和方法,一个类可以混入(mixin)多个特质。
- Scala引入trait特征,第一可以替代Java的接口,第二个也是对单继承机制的一种补充。
package com.atguigu.chapter06object $09_TraitDefined {/*** scala是单继承多实现* 特质的语法:trait 特质名{....}* scala中子类实现特质:* 1.子类不需要继承父Class,此时子类实现第一个trait使用extends关键字,其他trait的实现使用with关键字* 2.子类需要继承父class,此时子类实现trait使用with关键字* 特质中既可以定义具体方法也可以定义抽象方法,既可以定义抽象属性也可以定义具体属性***/trait Log1{//抽象属性val name:String//具体属性val age = 20//抽象方法def m1(x:Int,y:Int):Int//具体方法def m2(x:Int) = x*x}trait Log2trait Log3//子类不需要继承父class,此时子类实现第一个trait使用extends关键字,其他trait的实现使用with关键字class Errorlog extends Log1 with Log2 with Log3{override val name:String ="lisi"override def m1(x: Int, y: Int): Int = x + y}class ParentLog//子类需要继承父class,此时子类实现trait使用with关键字class WarnLog extends ParentLog with Log1 with Log2 with Log3{override val name: String = "zhangsan"override def m1(x: Int, y: Int): Int = x - y}def main(args: Array[String]): Unit = {val log = new Errorlogprintln(log.name)println(log.m1(10, 20))}}
10.特质混入
package com.atguigu.chapter06object $10_ObjectMix {/*** 对象混入:让某个对象拥有指定特质的属性和方法* 语法: new 类名(...) with 特质名*/trait Log{val name = "lisi2"}class ErrorLogdef main(args: Array[String]): Unit = {val log = new ErrorLog//println(log.name)val log2 = new ErrorLog with Logprintln(log2.name)}}
11.特质的叠加
package com.atguigu.chapter06object $11_TriatAdd {/*** 子类可以实现多个父特质,如果这多个父特质都有一个同名方法并且参数列表也一样的时候,此时子类默认调用该同名方法会报错* 子类可以通过重写该同名方法来解决报错问题* 子类中如果想要调用父类的同名方法可以使用super.方法名的方式调用,此时默认情况下调用的是继承顺序最后一个特质的同名方法* 如果子类想要调用指定父特质的同名方法可以使用super[特质名].方法名的方式调用* 子类可以实现多个父特质,如果这多个父特质中都有一个同名方法并且参数列表也一样的时候,并且这多个特质都继承同一个父特质的时候,此时可以通过super调用* 同名方法的时候是按照继承顺序从右向左开始调用*/trait ParentLog{def log(msg:String)={println(s"ParentLog:${msg}")}}trait Log1 extends ParentLog{override def log(msg: String): Unit = {println(s"Log1:${msg}")super.log(msg)}}trait Log2 extends ParentLog{override def log(msg: String): Unit = {println(s"Log2:${msg}")super.log(msg)}}trait Log3 extends ParentLog{override def log(msg: String): Unit = {println(s"Log3:${msg}")super.log(msg)}}class ErrorLog extends Log1 with Log2 with Log3{override def log(msg: String): Unit = {println(s"ErrogLog:${msg}")super.log(msg)}}def main(args: Array[String]): Unit = {var obj = new ErrorLogobj.log("hello")}}
12.特质自身类型
package com.atguigu.chapter06import java.io.{FileInputStream, FileOutputStream, ObjectInputStream, ObjectOutputStream}import scala.beans.BeanPropertyobject $12_Self {/*** 特质自身类型:提醒子类实现该特质的时候必须提前实现/继承某个特质/class* 语法:this:类型=>*/trait ObjectReadAndWrite{//this:Serializable=>_:Serializable=>def read() ={val ois = new ObjectInputStream(new FileInputStream("d:/obj.txt"))val ref = ois.readObject()ois.close()ref}def write()={val oos = new ObjectOutputStream(new FileOutputStream("d:/obj.txt"))oos.writeObject(this)oos.flush()oos.close()}}class Student extends ObjectReadAndWrite with Serializable {@BeanPropertyvar name:String = _@BeanPropertyvar age:Int = _}def main(args: Array[String]): Unit = {val student = new Studentstudent.setName("lisi")student.setAge(20)student.write()val s1 = new Studentval ref = s1.read()val stu = ref.asInstanceOf[Student]println(stu.getAge)println(stu.getName)}}
13.类型检查和判断
package com.atguigu.chapter06import scala.util.Randomobject $13_TypeCheck {/*** java判断对象是否属于某个类型:对象 instanceof 类型* java中强转: (类型)对象* java中获取对象的class形式: 对象.getClass* java中获取类的class形式: 类名.class** scala中判断对象是否属于某个类型: 对象.isInstanceOf[类型]* scala中强转: 对象.asInstanceOf[类型]* scala中获取对象的class形式: 对象.getClass<常用>* scala中获取类的class形式:classOf[类名]<常用>** 新类型:给类起别名* 语法: type 别名 = 类名*/val RED = "red" //枚举class Animalclass Dog extends Animal{val name = "haha"}class Pig extends Animal{val age = 20}def main(args: Array[String]): Unit = {val animal = getAnimal()println(animal.getClass)if(animal.isInstanceOf[Pig]){val pig = animal.asInstanceOf[Pig]println(pig.age)}else{val dog = animal.asInstanceOf[Dog]println(dog.name)}type MyString = Stringval name = new MyString("hello")println(name)}def getAnimal()={val num = Random.nextInt(10)if(num%2==0) new Dogelse new Pig}}
