$03[Scala(面向对象)]

第一章.面向对象

1.Scala包

package com.atguigu.chapter06

object $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 Person

  def 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.chapter06

object $02_ClassDefined {
  /**
   * java创建类:[访问修饰符] class 类名{....}
   * java创建对象: new 类名(....)
   *
   * scala创建类: class 类名{......}
   * scala创建对象: new 类名(.......)
   */
  class Person{}

  def main(args: Array[String]): Unit = {
    val person = new Person
    println(person)
  }

}

3.定义属性和方法

package com.atguigu.chapter06

object $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 + y
    private val address = "shenzhen"
    private def add(x:Int,y:Int) = x + y
  }

  def main(args: Array[String]): Unit = {
    val person = new Person
    println(person.name)
    println(person.age)
    println(person.func(10, 20))
    //println(person.address)
    //println(person.add(10, 20))
  }

}

4.构造器

package com.atguigu.chapter06

object $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.chapter06

import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.serializer.SerializeFilter


import scala.beans.BeanProperty

object $05_Private {

  class Person{
    @BeanProperty
    var name:String = _
    @BeanProperty
    var age:Int = _

    /*def setName(name:String) = this.name =name
    def setAge(age:Int) = this.age =age
    def getName()= this.name
    def 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=20
    println(person.name)*/
    person.setName("zhaoliu")
    person.setAge(18)
    println(person.getName())
    //对象转json
    val json = JSON.toJSONString(person, null.asInstanceOf[Array[SerializeFilter]])
    println(json)
  }

}

6.继承

package com.atguigu.chapter06

import scala.util.Random

object $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 =0
    override 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 Student
    println(student.age)
    println(student.address)
    println(student.add(10, 20))
    val person = getPerson()
    println(person.add(20, 10))
    val p:Person = new Student
    println(p.address)

  }
  def getPerson():Person={
    val index = Random.nextInt(10)
    if(index % 2 ==0) new Student
    else new Student2
  }
}

7.抽象类

package com.atguigu.chapter06

object $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 = 20
    override 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 Dog
    println(dog.age)
    println(dog.m1(10, 20))
    //匿名子类
    val animal = new Animal {
      override val age: Int = 100

      override def m1(x: Int, y: Int): Int = x+y
    }
    println(animal.age)
  }

}

8.单例对象(伴生对象)

Scala语言是完全面向对象的语言,所以并没有静态的操作(即在Scala中没有静态的概念)。但是为了能够和Java语言交互(因为Java中有静态概念),就产生了一种特殊的对象来模拟类对象,该对象为单例对象。若单例对象名与类名一致,则称该单例对象这个类的伴生对象,这个类的所有“静态”内容都可以放置在它的伴生对象中声明。

package com.atguigu.chapter06

object $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 =20
  def yy()=println("++++++++++++++++++")
  def getName()= Person.name

}
object Person{
  private val name ="lisi"
  def xx()= println(".............")
  def getAge()= new Person().age
  def apply(address:String):Person = new Person(address)
  def apply():Person = new Person()
}

9.特质

  1. Scala语言中,采用特质trait(特征)来代替接口的概念,也就是说,多个类具有相同的特征(特征)时,就可以将这个特质(特征)独立出来,采用关键字trait声明。
  2. Scala中的trait中即可以有抽象属性和方法,也可以有具体的属性和方法一个类可以混入(mixin)多个特质
  3. Scala引入trait特征,第一可以替代Java的接口,第二个也是对单继承机制的一种补充。
package com.atguigu.chapter06

object $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 Log2
  trait 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 Errorlog
    println(log.name)
    println(log.m1(10, 20))
  }

}

10.特质混入

package com.atguigu.chapter06
object $10_ObjectMix {
  /**
   * 对象混入:让某个对象拥有指定特质的属性和方法
   *    语法: new 类名(...) with 特质名
   */
    trait Log{
      val name = "lisi2"
    }
  class ErrorLog
  def main(args: Array[String]): Unit = {
    val log = new ErrorLog
    //println(log.name)
    val log2 = new ErrorLog with Log
    println(log2.name)
  }
}

11.特质的叠加

package com.atguigu.chapter06

object $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 ErrorLog
    obj.log("hello")
  }

}

12.特质自身类型

package com.atguigu.chapter06

import java.io.{FileInputStream, FileOutputStream, ObjectInputStream, ObjectOutputStream}
import scala.beans.BeanProperty

object $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 {
    @BeanProperty
    var name:String = _
    @BeanProperty
    var age:Int = _

  }

  def main(args: Array[String]): Unit = {
    val student = new Student
    student.setName("lisi")
    student.setAge(20)
    student.write()

    val s1 = new Student
    val ref = s1.read()
    val stu = ref.asInstanceOf[Student]
    println(stu.getAge)
    println(stu.getName)
  }

}

13.类型检查和判断

package com.atguigu.chapter06

import scala.util.Random

object $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 Animal
  class 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 = String
    val name = new MyString("hello")
    println(name)
  }
  def getAnimal()={
    val num = Random.nextInt(10)
    if(num%2==0) new Dog
    else new Pig
  }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值