10类基础

本文最后更新于 2021-08-05 11:42:59

类基础

object ObjDemo1 {

  def main(args: Array[String]): Unit = {
    val user = new User
    println(user.age)
    println(user.name)
    user.age=21
    println(user.age)
    user.age_$eq(11)
    println(user.age)
    user.eat()

    println(user.getAge())

    //给类起别名
    type U = User
    val u = new U
    u.eat()
    //打印的名字还是 User
    println(u.getClass.getName())


  }
}

/**
  * 默认是public class
  * 在java中 如果是public class 类名必须与文件名相同
  *           内部类可以有private ,static
  **/
class User{
  //默认是私有的变量
  //并且默认提供了 getter setter 但是不满足标准的javaBean规范,可以加上@BeanPropertity生成规范的,原来的也不会去掉
  //比如 age -> age() ,age_$eq()
  //但是age()不能用,age_$eq(xxx)可以用
//  @beanGetter 只加get
//  @beanSetter 只加set
  @BeanProperty
  var age =20
  @BeanProperty
  var name = "king"
  //private final 且只有getter
  val contry="china"
  //private
  //但是getter和setter是私有的了
  private var sex = "man"

  def eat()={
    println(s"$name eat")
  }
}

class User1{

  //当属性为var时,可以使用 _ 占位不赋初值
  //必须要手动指定类型
  // 数字 默认0
  // boolean 默认false
  //引用类型 默认null
  var name:String = _
  var age:Int = _
}


class User3(var name:String,val age:Int,sex:String){
  def eat={
    println(sex)
  }
}
//使用 有参主构造器 定义对象
//定义的参数自动成为成员变量
//如果没有指定 val或var 例如 sex ,则为private final ,如果内部没有使用,则会优化去掉(直接没有该成员变量)


class User4(@BeanProperty var name:String,val age:Int,sex:String){
  //辅助构造器,相当于构造器重载
  //辅助构造的参数就不是成员变量
  def this(){
    //第一行必须调用构造器
    this("aaa",1,"")
  }

  def this(c:Int){
    //后面的构造器可以调用前面定义辅助构造器的
    //前面的构造器不能调用后面的辅助构造器
    //this()
    this("aa",c,"")
  }

  def eat={
    println(sex)
  }
}

导包

object ObjDemo2 {

  def main(args: Array[String]): Unit = {
    //在任何地方导入包
    //局部使用
    import java.util.HashMap
    val stringToString = new HashMap[String,String]()


    //使用包对象
    foo
  }
}


//在priv.king.obj 下有一个类A
class A
package aa{
  //在priv.king.obj.aa 下有一个类A
  class A
}


/*
scala也有包的概念,命名于使用规则于java一样
1.包的声明
package priv.king.obj
2.包语句
在scala中, .scala文件一般会有多个类,所有的类都默认在一个包中

3.包使用
在文件最顶层导入
import java.util.HashMap

在代码任何需要的地方导入
比如在方法内导入


通配符导入
//导入util下所有包
import java.util._
//导入多个
import java.util.{HashMap,TreeMap}
//除了HashMap其他都导入

//导包的时候起别名
import java.util.{HashMap=>HM}

//除了HashMap其他都导入
//先给HashMap起别名,在导入所有
import java.util.{HashMap=>_ ,_}

//默认导入
//java中java.long.*
//scala中
java.lang._
scala._
scala.Predef._   Predef下所有的方法


 */

包对象

package priv.king

/**
  *
  * @author king 
  *         TIME: 2020/11/8 - 18:54
  *
  **/

//创建包对象
//包内的所有方法和属性,在包内的对象可以直接使用
//一个包下只能由一个包对象
package object obj {

    def foo={
      println("foo.......")
    }
}

image-20201108190418105

权限修饰符

object ObjDemo3 {
  def main(args: Array[String]): Unit = {
   // val hello = new Hello()
    val hello2 = new Hello2(1)

  }
}


//对主构造器私有
class Hello private(var age:Int){
  //对成员变量私有
  private var a=10

}


//对主构造器私有
//但是对obj包下所有的类公开 []
//指定公开对成员变量也适用
class Hello2 private[obj](var age:Int){
  //对成员变量私有
  private[obj] var a=10


}
/*
权限修饰符
java中
public:所有地方
protected: 同包和子类
[default]: 同包
private: 本类


scala中
[default] 默认是public
protected 子类
private 只能在本类

权限修饰灵活性

 */

继承于多态

object ObjDemo4 {


  def main(args: Array[String]): Unit = {

  }
}



class QQQ(var arg:String){
  private var a=1
  protected var b=1

  val c=222

  def name()={
    println("1111")
  }

}

class WWW(var arg1:String) extends QQQ(arg1){
  def fun={
//    println(a)  error
    println(b)

  }

  //属性重写
  //加上override关键字
  override val c:Int=2


  //子类重写必须加上override关键字
  override def name(): Unit ={
    super.name()
    println("2222")
  }
}

/*
单继承
构造器
先执行父构造器再执行子构造器

方法的重写必须加上override关键字

新概念:属性的重写
属性重写 加上override关键字
val只能重写val和不带参数的def
var只能重写抽象var


多态
 java只有方法有多态,属性没有多态

 scala中方法和属性都有多态
 属性其实还是访问的是getter方法

  */

抽象类

object ObjDemo5 {
  def main(args: Array[String]): Unit = {

    //匿名内部类
    var aa = new ZZZ(10) {
      override var b: Int = 1

      override def foo(): Int = 1
    }

  }
}

abstract class ZZZ(var a:Int){
  //抽象字段,不初始化
  var b:Int

  //抽象方法
  //需要指定返回类型
  def foo():Int
}

class XXX extends ZZZ(1){
  override var b: Int = _

  // ??? 实际上是调用Predef中的函数
  //def ???:Nothing=throw new NotImplementedError
  override def foo(): Int = ???
}

/*
scala抽象类
1.普通类有的抽象类都有
2.抽象类可以有抽象方法
3.抽象类不可以创建对象
 */

object && 伴生类

object ObjDemo6 {
  def main(args: Array[String]): Unit = {
    CCC.fun
	
     //apply 方法可以实现不用new   例如List()
    //相当于调用CCC.apply()
    //对象和类都有这个特性
    println(CCC())
  }
}


//CCC 相当于就是单例
//可以直接调用里面的方法
object  CCC{
  def fun=println("111")

  //apply可以重载
  def apply(): Int =10

}

//在一个.scala中有同名的object和class ,则称他们为伴生对象,伴生类
//编译过后  object中的相当于静态方法,class中的相当于非静态方法
//用来做静态工厂很方便

class CCC{

}
object ObjDemo7 {

  def main(args: Array[String]): Unit = {
    println(Phone.getPhone("iphone"))
    println(Phone.getPhone("huawei"))
    println(Phone.getPhone("google"))
    println(Phone.getPhone("google"))

  }

}

object Phone{

  val map=mutable.Map[String,Phone](
    "iphone"->new Phone("iphone"),
    "huawei"->new Phone("huawei")
  )

  def getPhone(brand:String)=map.getOrElseUpdate(brand,new Phone(brand))

}

class Phone private (var brand:String){
  //相当于主构造器中的代码
  println(s"$brand .........")

  override def toString:String = s"品牌->$brand"

}
//iphone .........
//huawei .........
//品牌->iphone
//品牌->huawei
//google .........
//品牌->google
//品牌->google

Trait

object ObjDemo8 {

  def main(args: Array[String]): Unit = {
    val abc = new ABCtrait
    abc.eat() //eat c

    val dtrait = new Dtrait with Atrait

  }
}

trait Atrait {
  def eat(): Unit ={
    println("eat a")
  }
}

trait Btrait extends Atrait {
  override def eat()={
    super[Atrait].eat()
    println("eat b")
  }
}

trait Ctrait extends Atrait {
  override def eat()={
    super.eat()
    println("eat c")
  }
}

class Dtrait {
  def fff()={
    println("555555")
  }
}


trait Etrait{
  //自身类型
  //相当于继承Dtrait
  self:Dtrait=>
  def fun()={
    self.fff()
  }
}

class ABCtrait extends Atrait with Btrait with Ctrait {

}



/*
没有父类:class  类名 extends  特质1   with    特质2   with   特质3 …
有父类:class  类名  extends  父类   with  特质1   with   特质2  with 特质3…

scala没有提供接口,但是提供了trait 编译后也是接口
1.抽象类中有的东西,trait都可以有
2.trait可以多混入
3.先混入的先初始化
4.如果一个类混入特质中有相同的方法,则会产生成员冲突,可以使用菱形结构解决问题(同时继承一个父类,在父类中定义方法),或者时在子类直接重写该方法
5.在多混入的菱形结构中,super调用前一个混入的方法,或者时 super[xxx]指定调用谁的
6.动态混入,,new B with A
7.trait也可以继承类,但是注意scala最终还是要去单继承
8.自身类型 self:XXX=>    相当于继承,将某个类注入到self变量中
 */

类型转换

object ObjDemo9 {
  def main(args: Array[String]): Unit = {
      val kkk = new KKK

    //类型判断
    println(kkk.isInstanceOf[KKK])
    println(kkk.isInstanceOf[LLL])
    println(kkk.isInstanceOf[Object])

    //类型转换
    val lll = kkk.asInstanceOf[LLL]

  }
}

class LLL

class KKK extends LLL

枚举

object ObjDemo10 {
  def main(args: Array[String]): Unit = {
    var o = OOO1
    println(OOO1.isInstanceOf[PPP])


    println(Season.Spring)
    println(Season.judge(1))
  }
}

sealed abstract class PPP

object OOO1 extends PPP

object OOO2 extends PPP

object OOO3 extends PPP


object Season extends Enumeration{
  type Season =Value //为了将Enumration.Value的类型暴露出来给外界使用
  val Spring,Summer,Autumn,Winter =Value ///在这里定义具体的枚举实例

  def judge(month:Int)={
    if(month>=1 && month<=3) Spring
  }

}

/*
sealed 修饰的类叫密封类
修饰后子类只能出现在当前文件中
1.模拟枚举
sealed abstract class PPP
object OOO1 extends PPP
2.java中编写,scala调用
3.继承Enumeration


 */

10类基础
https://jiajun.xyz/2020/11/03/scala/10类基础/
作者
Lambda
发布于
2020年11月3日
更新于
2021年8月5日
许可协议