Scala面向对象 包、类和对象、封装、继承和多态、抽象类、伴生对象、特质、类型检查、枚举和应用类、Type

这篇博客详细介绍了Scala编程中的包结构、类和对象的构造、继承机制、动态绑定、抽象类、单例对象、特质以及特征的叠加。通过实例展示了如何定义和使用这些概念,包括构造器参数、访问权限、包对象、匿名子类以及单例设计模式。此外,还探讨了特质的叠加和类型定义,展示了如何在Scala中实现类似Java的静态属性和方法以及依赖注入。
摘要由CSDN通过智能技术生成

目录

Scala包

类和对象 

构造器 

继承 

动态绑定

抽象类 

单例对象(伴生对象) 

特质 

特征的叠加 


 Scala包

//用嵌套风格定义包
package com{

  import com.bigdata.scala.Inner //局部导入 作用于当前范围

  //在外层包定义单例对象
  object Outer{
    var out:String="out"

    def main(args: Array[String]): Unit = {
      println(Inner.in)

    }

  }
  package bigdata{
    package scala{
      object Inner{
        val in:String="in"

        def main(args: Array[String]): Unit = {
          println(Outer.out)
          Outer.out="outer"
          println(Outer.out)

        }
      }
    }
  }
}

//在同一个文件中定义多个包
package aaa{
  package bbb{

    import com.bigdata.scala.Inner

    object Test01_Package{
      def main(args: Array[String]): Unit = {
        println(Inner.in)
      }
    }
  }
}

//包对象

package object chapter06 {
  //定义当前包共享的属性和方法
  val commonValue = "大数据"
  def commonMethod()={
    println(s"我们学习${commonValue}")

  }
}

//package chapter06
//
//object Test02_PackageObject {
//  def main(args: Array[String]): Unit = {
//    commonMethod
//    println(commonValue)
//  }
//}

package chapter06{
  object Test02_PackageObject {
    def main(args: Array[String]): Unit = {
      commonMethod
      println(commonValue)
    }
  }

}

package ccc {
  package ddd {
    object Test02_PackageObject {
      def main(args: Array[String]): Unit = {
        println(school)
      }
    }
  }
}

//定义一个包对象
package object ccc{
  val school:String="qinghua"
}

类和对象 

package chapter06

import scala.beans.BeanProperty
//类 对象
object Test03_Class {
  def main(args: Array[String]): Unit = {
    //创建一个对象
    val student=new Student()
//    student.name //error 不能访问private属性
    println(student.age) //默认初值为0
    println(student.sex) //默认初值为null
    student.sex="female"
    println(student.sex)



  }

}

//定义一个类
class Student{
  //定义属性
  private var name:String="alice"
  @BeanProperty  //显性的调用get set方法
  var age:Int=_
  var sex:String=_
}
package chapter06
//访问权限
object Test04_Access {
  def main(args: Array[String]): Unit = {
    //创建对象
    val person:Person=new Person
//    person.idCard  //error
//      person.name  //error

    println(person.age)  //包访问权限
    println(person.sex)
    person.printInfo()

    val worker:Worker=new Worker

//    worker=new Worker

    worker.printInfo()
  }

}


//定义一个子类
class Worker extends Person{
  override def printInfo(): Unit ={
    println("Worker:")
//    println(idCard) //error  私有的属性只能在自己的类以及伴生对象中 可以访问
    //子类是不能访问的
    name="bob"
    age=25
    sex="male"

    println(s"Worker:$name  $sex  $age")

  }
}
package chapter06
//有继承关系的类
object Test04_ClassForAccess {


}


//定义一个父类
class Person{
  private var idCard:String="3523566"  //私有的属性只能在自己的类以及伴生对象中 可以访问 子类是不能访问的
  protected var name:String="alice"  //受保护的对象只能在当前类和子类中 可以访问到
  var sex:String="female"
  private [chapter06] var age:Int=18 //包访问权限的属性

  def printInfo():Unit={
    println(s"Person:$idCard  $name $sex  $age")
  }




}

构造器 

package chapter06
//构造器
object Test05_Constructor {
  def main(args: Array[String]): Unit = {
    val student1=new Student1
    student1.Student1()
    val student2=new Student1("alice")
    val student3=new Student1("bob",22)


  }

}


//定义一个类
class Student1{  //主构造器没有参数 省略()
  //定义属性
  var name:String=_
  var age :Int=_

  println("1,主构造方法被调用")

  //声明辅助构造方法
  def this(name:String){
    this()  //   ( )直接调用主构造器
    println("2,辅助构造方法一被调用")
    this.name=name   //直接写name=name 优先使用当前的参数
    println(s"name:$name age:$age")

  }

  def this(name:String,age:Int){
    this(name)
    println("3,辅助构造方法二被调用")
    this.age=age   //直接写name=name 优先使用当前的参数
    println(s"name:$name age:$age")
  }

  def Student1():Unit={  //可以定义一个跟类名完全一样的方法 但根本不是构造方法 就是一个普通方法
    println("一般方法被调用")
  }






}

package chapter06
//构造器的参数用法
object Test06_ConstructorParams {
  def main(args: Array[String]): Unit = {
    val student2=new Student2
    student2.name="alice"
    student2.age=22
    println(s"stduent2:name=${student2.name},age=${student2.age}")


    val student3=new Student3("bob",18)
    println(s"stduent3:name=${student3.name},age=${student3.age}")

    val student4=new Student4("zhangsan",20)
    student4.printInfo()

    val student6=new Student6("lisi",24,"beijing")
    student6.printInfo()



  }

}

//定义类
//无参构造器
class Student2{
  //单独定义属性
  var name :String=_
  var age :Int=_
}

//上面定义等价于 Scala给主构造器传参  最为推荐的写法
class Student3(var name :String ,var age :Int)

//主构造器参数无修饰
class Student4( name :String , age :Int) {
  def printInfo() {
    println(s"stduent4:name=${name},age=${age}")

  }
}

//class Student5(val name:String,val age:Int)

class Student6(var name :String ,var age :Int) {
  var school: String = _

  def this(name: String, age: Int, school: String) {
    this(name, age)
    this.school = school
  }


  def printInfo() {
    println(s"stduent6:name=${name},age=${age},school=${school}")

  }
}

继承 

package chapter06
//继承
object Test07_Inherit {
  def main(args: Array[String]): Unit = {
    val student1:Student7=new Student7("alice",22)
    val student2=new Student7("bob",20,"20163402288")

    student1.printInfo()
    student2.printInfo()

    val teacher=new Teacher
    teacher.printInfo()

    def personInfo(person:Person7):Unit= {  //用父类的类型来进行参数的接收  若使用接口也可实现
      person.printInfo()
    }


      println("------------------------------------------")

      //多态 动态绑定方法 运行时才去确定
      //在定义多态时 指的是要把子类或者实现类的对象实例传给一个父类或者接口的一个引用
      //这样就可以实现同一接口 有多种不同的状态 不同的实现
      val person=new Person7()
      personInfo(student1)
      personInfo(teacher)
      personInfo(person)

    }

  }


//定义一个父类
class Person7(){
  var name:String=_
  var age:Int=_

  println("1,父类的主构造器的调用")

  def this(name:String,age:Int){
    this()  //具体实现 必须调用主构造器
    println("2,父类的辅助构造器的调用")
    this.name=name
    this.age=age
  }

  def printInfo():Unit={
    println(s"Person:$name $age")
  }

}

//定义子类
class Student7(name:String,age:Int) extends Person7(name,age){  //()  (name,age)
  var stdNo:String=_
  println("3,子类的主构造器的调用")

  def this(name:String,age:Int,stdNo:String){
    this(name,age)
    println("4,子类的辅助构造器的调用")
    this.stdNo=stdNo
  }

  override def printInfo(): Unit = { //这里想打印学生的信息 加上学号 所以重写父类的方法
    println(s"Student:$name $age $stdNo")


  }


}

class Teacher extends Person7 {
  override def printInfo(): Unit = {
    println(s"Teacher")

  }
}

动态绑定

package chapter06
//动态绑定
object Test08_DynamicBind {
  def main(args: Array[String]): Unit = {
    val student:Person8=new Student8
    println(student.name)
    student.hello()

  }

}

class Person8{
  val name:String="person"
  def hello():Unit={
    println("hello person")
  }

}


//在Java子类当中 对应的属性和方法一样 即方法重写 覆盖了父类的方法 Scala当中需要加上override
class Student8 extends Person8{
  override val name:String="student"
  override def hello():Unit={
    println("hello student")
  }

}

抽象类 

package chapter06
//抽象类
object Test09_AbstractClass {
  def main(args: Array[String]): Unit = {

    val student=new Student9
    student.eat()
    student.sleep()

  }

}

//定义抽象类
abstract class Person9{
  //非抽象属性
  val name:String="person"

  //抽象属性
  var age :Int

  //非抽象方法
  def eat():Unit={
    println("person eat")
  }

  //抽象方法
  def sleep():Unit
}

  //定义具体的实现子类
  class Student9 extends Person9{ //若Student9为普通类的话 里面的东西都需要是具体的
    //把所有的抽象属性和抽象方法都具体之后 才不会报错
    //或者加abstract

    var age:Int=18

     def sleep(): Unit = {
       println("student sleep")  //实现抽象属性和方法
     }

    //重写非抽象属性和方法 必须加override
    override val name:String="student"  //override不能定义一个可变的变量 var
//    name ="student" //var 直接改



    override def eat(): Unit = {
      super.eat() //调用父类的方法 加super
      println("student eat")
    }


  }




package chapter06
//匿名子类
object Test10_AnnoymousClass {
  def main(args: Array[String]): Unit = {
    val person:Person10=new Person10 {  //必须要把抽象属性和方法实现出来
      override var name: String = "alice"

      override def eat(): Unit = println("person eat")
    }
    println(person.name)
    person.eat() //此时得到的是具体的抽象对象

    //结果和实现了具体的子类 然后再去创建对应的实例 调用这个方法的结构是一样的

  }

}

//定义抽象类 匿名子类一般都是针对抽象类和接口来用的
abstract class Person10{
  var name:String
  def eat():Unit
}

单例对象(伴生对象) 

package chapter06
//伴生对象(单例对象)
object Test11_Object {
  def main(args: Array[String]): Unit = {
//    val student=new Student11("alice",22) //已经不能调用当前的构造器 去创建对象实例了
//    student.printInfo()

    val student1=Student11.newStudent("alice",22)
    student1.printInfo()
    val student2=Student11.apply("bob",20)
    student2.printInfo()
    val student3=Student11("zhangsan",24)
    student3.printInfo()

  }

}

//定义类
class Student11 private(val name:String,val age:Int) { //private主构造器私有化
  def printInfo() {
    println(s"stduent11:name=${name},age=${age},school=${Student11.school}")  //所有的属性和方法都是基于对象调用的
  }
}

//伴生对象 学生在同一个学校 静态的
//名字必须和上面的伴生类一样

object  Student11{
  val school:String="qinghua" //可以当做静态属性来看 Java里面的static

  //定义一个类的对象实例的创建方法  工厂方法
  def newStudent(name:String,age:Int):Student11=new Student11(name,age)
  //在当前伴生对象里面 可以调用伴生类的私有成员和方法

  //伴生对象里面一个普通的方法
  def apply(name:String,age:Int):Student11=new Student11(name,age)

  //在Scala底层对于 apply有个特殊的优惠政策 可以简洁 直接可以把apply省略

}


package chapter06
//1.单例设计模式 在伴生对象里面创建一个实例 全局只有一份
//2.作为属性放在这里 相当于Java里面的静态属性
//3.定义一个公有的方法 返回这唯一的一份对象实例就可以了
object Test12_Singleton {
  def main(args: Array[String]): Unit = {
    val student1=Student12.getInstance()
    student1.printInfo()

    val student2=Student12.getInstance()
    student2.printInfo()

    println(student1)
    println(student2) //得到的引用地址完全一样 全局就这么一份 单例设计模式


  }

}

//定义类
class Student12 private(val name:String,val age:Int) { //private主构造器私有化
  def printInfo() {
    println(s"stduent12:name=${name},age=${age},school=${Student11.school}")  //所有的属性和方法都是基于对象调用的
  }
}

//饿汉式
//object Student12{
//  private val student:Student12=new Student12("alice",18)
//  def getInstance():Student12=student
//
//}


//懒汉式 不要一上来就把对象创建出来
// 更搞笑的方法 先判断之前有没有 如果有就直接用 如果没有就再创建
object  Student12{
  private var  student:Student12=_  //给空值后面要更改 var
  def getInstance():Student12={
    if(student==null){
      //如果没有实例的话 就创建一个
      student=new Student12("alice",18)
    }
    student
  }
}







特质 

package chapter06
//特质
object Test13_Trait {
  def main(args: Array[String]): Unit = {
    val student:Student13=new Student13
    student.sayHello()
    student.study()
    student.dating()
    student.play()

  }

}

//定义一个父类
class Person13{
  val name:String="person"
  var age :Int=18
  def sayHello():Unit={
    println("hello from "+name)
  }

//  def increase():Unit={
//    println("person increased")
//  }

}

//定义一个特质
trait Young{
  //声明抽象和非抽象属性
  var age:Int
  val name:String="young"

  //声明抽象和非抽象的方法
  def play():Unit={
    println(s"young people ${name} is playing")
  }

  def dating():Unit
}
//单继承 多实现
class Student13 extends Person13 with Young{
  //name冲突 重写冲突的属性
  override val name: String = "student"


  //实现抽象方法
  override def dating(): Unit = println(s"student ${name} is dating")

  def study():Unit=println(s"student $name is studying")

  //重写父类方法
  override def sayHello(): Unit = {
    super.sayHello()
    println(s"hello from:student $name")
  }




}

package chapter06
//混入多个特质
object Test14_TraitMixin {
  def main(args: Array[String]): Unit = {
    val student=new Student14
    student.study()
    student.increase()

    student.play()
    student.increase()

    student.dating()
    student.increase()

    println("-------------------------------")

    //动态混入
    //当前定义的特征 不是在某一个类中直接混入进去 而是在使用中 再额外的添加某一特质

    val studentWithTalent=new Student14 with Talent {
      //创建对象实例的时候才去实现对应的特质里面的 定义和声明的抽象属性和抽象方法
      override def dancing(): Unit = println("student is good at dancing")

      override def singing(): Unit = println("student is good at singing")

    }

    studentWithTalent.sayHello()
    studentWithTalent.play()
    studentWithTalent.study()
    studentWithTalent.dating()
    studentWithTalent.increase()
    studentWithTalent.singing()
    studentWithTalent.dancing()



  }

}

//再定义一个特质
trait Konwledge{
  var amount:Int=0
  def increase():Unit
}

trait Talent{
  def singing():Unit
  def dancing():Unit

}


//单继承 多实现
class Student14 extends Person13 with Young with Konwledge {
  //name冲突 重写冲突的属性
  override val name: String = "student"


  //实现抽象方法
  override def dating(): Unit = println(s"student ${name} is dating")


  def study():Unit=println(s"student $name is studying")


  //重写父类方法
  override def sayHello(): Unit = {
    super.sayHello()
    println(s"hello from:student $name")
  }

  //实现特质中的抽象方法
  override def increase(): Unit = {
    amount +=1
    println(s"student $name konwledge increased: $amount")
  }




}


特征的叠加 

package chapter06
//特征的叠加
object Test15_TraitOverlying {
  def main(args: Array[String]): Unit = {
    val student=new Student15
    student.increase()


    //钻石问题特征叠加
    val myFootBall=new MyFootBall
    println(myFootBall.describe())

  }
}


//定义球类特征
trait Ball{
  def describe():String="ball"
}

//定义颜色特征
trait ColorBall extends Ball{
  var color:String="red"
  override def describe(): String = color + "-" + super.describe() //CategoryBall

}

//定义种类特征
trait CategoryBall extends Ball{
  var category:String="foot"
  override def describe(): String = category + "-" + super.describe()
}

//定义一个自定义球类
class MyFootBall extends CategoryBall with ColorBall{ //越本质的东西 放在越后面
  override def describe(): String = "my ball is a "  + super[CategoryBall].describe() //ColorBall往左
}






trait Konwledge15{
  var amount:Int=0
  def increase():Unit={
    println("knowledge increased")
  }
}

trait Talent15{
  def singing():Unit
  def dancing():Unit
  def increase():Unit={
    println("talent increased")
  }

}


class Student15 extends Person13 with Talent15 with Konwledge15{
  override def dancing(): Unit = println("dancing") //直接在类中重写冲突方法。

  override def singing(): Unit = println("singing")

  override def increase(): Unit = {
    super.increase() //拿特征的最后一个做调用 with Konwledge15 从右到左叠加
    //指定要调父类的方法
    //super[Person13].increase()


    //1.优先使用特质。一个类扩展多个特质是很方便的,但却只能扩展一个抽象类。

    //2.如果你需要构造函数参数,使用抽象类。因为抽象类可以定义带参数的构造函数,而特质不行(有无参构造)。

  }

}

Type定义新类型 

package chapter06



object Test16_TraitSelfType {
  def main(args: Array[String]): Unit = {
    val user =new RegisterUser("alice","12345")
    user.insert()

  }

}

//用户类
class User( val name:String,val password: String)

trait  UserDao{  //要想使用User的属性 不想让他们有继承的关系
  //指定一个自身类型 就拥有了一个User 外部直接插入了User对象一样
  //依赖注入的功能


  _: User=>  //定义自身类型
  //向数据库插入数据
  def insert ():Unit={
    println(s"insert into db:${this.name}")

  }
}

//定义注册用户类
class RegisterUser(name:String,password:String ) extends User(name,password) with UserDao
package chapter06



object Test16_TraitSelfType {
  def main(args: Array[String]): Unit = {
    val user =new RegisterUser("alice","12345")
    user.insert()

  }

}

//用户类
class User( val name:String,val password: String)

trait  UserDao{  //要想使用User的属性 不想让他们有继承的关系
  //指定一个自身类型 就拥有了一个User 外部直接插入了User对象一样
  //依赖注入的功能


  _: User=>  //定义自身类型
  //向数据库插入数据
  def insert ():Unit={
    println(s"insert into db:${this.name}")

  }
}

//定义注册用户类
class RegisterUser(name:String,password:String ) extends User(name,password) with UserDao

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值