scala基础之对象

对象一词在Java中代表着类的实例,在scala中有着双重含义,即表示类的实例又是一个关键词object

一 将对象视为类的实例

1.1对象的强制转换

可以使用asInstanceOf,这种情况一般适用于动态类型的强制转换

# 检测某个变量是否属于某一类型

变量.isInstanceOf[类型]

# 类型转换:变量.asInstanceOf[类型]

# 检测某一个变量的class是否属于某一个某一个类

变量.getClass ==classOf[类型]

classAnimal(var name:String,var age:Int) {
    def this(name:String){
        this(name,0)
    }

    def desc(): Unit ={
        print(s"My name is$name, and my age is$age ")
    }
}

class Lion(name:String, age:Int, var kind:String) extends Animal(name,age){
    override def desc(): Unit = {
        super.desc();
        println("我是"+kind+"动物")
    }
}

class Wolf(name:String, age:Int, var kind:String) extends Animal(name,age){
    override def desc(): Unit = {
        super.desc();
        println("我是"+kind+"动物")
    }
}
object ClassClient {
    def main (args: Array[String]): Unit = {
        val a:Animal = new Animal("小黄",12)
        val lion:Animal = new Lion("马沙",5,"猫科")
        val wolf:Wolf = new Wolf("西北",2,"犬科")

        println(a.isInstanceOf[Animal])
        println(lion.isInstanceOf[Animal])
        println(wolf.isInstanceOf[Wolf])

        if (lion.isInstanceOf[Animal]) {
            val l = lion.asInstanceOf[Lion]
            print(l.desc())
        }
        print(lion.getClass,classOf[Animal])
        if (lion.getClass == classOf[Animal]){
            println("true")
        }
    }
}

 

1.2Java.Class的Scala等价类

当API要求传入一个类,在Java中需要传入Java的.Class,但是在scala中不是这样做的。是通过传入classOf[类型]

valinfo = new DataLine.Info(classOf[Target
DataLine])

 

1.3 确定对象所属的类

变量.getClass

二 将对象视为object关键词(伴生对象)

2.1 用object启动一个应用

用main方法启动一个应用或者为脚本提供一个入口

我们可以用2种方式来解决这个问题:

第一种办法:定义object去继承App

object BasisObject extends App {
    val numList = List(11,22,33,44,55)
    numList.map((x:Int) => x - 1).foreach(e => print(e+" "))
}

 

第二种办法:定义一个object,手动实现一个main方法,类似于java

object BasisObject {
    def main(args: Array[String]) {
        val numList = List(11,22,33,44,55)
        numList.map((x:Int) => x - 1).foreach(e => print(e+" "))
    }
}

 

2.2 用object创建单例

创建一个单例对象,以保证只有一个类的实例存在

object CashRegister {
    def open {println("opened")}
    def closed {println("closed")}
}

 

然后CashRegister被定义为一个对象,他只能有一个实例,而且他的调用方式和java静态类有点类似

CashRegister.open 
CashRegister.closed

这种模式在创建工具方法时

2.3 用伴生类创建静态成员

创建包含实例方法和静态方法的类,和java不一样scala没有静态关键字

在类中定义费静态成员,然后在伴生对象(和类名同名的object)中创建静态成员对象

class Pizza(var crustType:String) {
    var price:Float = 0.0f;
    def func(): Unit ={
        println("披萨价格是=> "+price)
    }
}

object Pizza{
    val CRUST_TYPE_THIN = "thin";
    val CRUST_TYPE_THICK = "thick"
    defgetFoo = "Foo"
}
object BasisObject {
    def main(args: Array[String]) {
        /*我们空间又直接访问Pizza的静态成员*/
        println(Pizza.CRUST_TYPE_THIN,Pizza.getFoo)
        /*我们也可以创建对象*/
        val p = new Pizza(Pizza.CRUST_TYPE_THICK)
        p.price = 28.95f;
        p.func()
    }
}

 

访问私有成员变量:

知道类和其伴生类能互相访问私有成员很重要,

class Foo {
    private val secret = 2;
}

object Foo{
    def double(foo:Foo) = foo.secret * 2
}
 
object BasisObject {
    def main(args: Array[String]) {
        val foo = new Foo
        print(Foo.double(foo))
    }
}

 

class Foo {
    private val secret = 2;
    def printObj:Unit= {
        println(s"I can see ${Foo.obj}")
    }
}

object Foo{
    private val obj = "Foo's Object"
    def double(foo:Foo) = foo.secret * 2
}

 

object BasisObject {
    def main(args: Array[String]) {
        val foo = new Foo
        foo.printObj
    }
}

 

2.4 将通用代码放入包对象

在不引入类或者对象的前提下,让函数、字段或者其他代码在包级别可用

解决办法:

将要在所有类中共享的代码放在一个包中的对象中

大概就是:将很多类需要用到的代码,字段或者函数放入包中某一个object,然后包下的其他类或者object来调用这个object就不需要import

比如现在有一个包com.scala.objects.Tools包,这个包下面专门放一些工具方法

然后现在定一个包级别的(com.scala.objects.Tools)也就是跟包平级的一个object,名字必须与包名相同,所以这个object名字也叫Tools,然后这个object和com.scala.objects.Tools属于同一层级。

语法:package object 包名

package com.scala.objects

package object Tools {
    //公用字段
    val MAGIN_NUM = 42

    //公用方法
    def echo(a:Any){println(a.toString)}

    //枚举
    object Margin extends Enumeration{
        type Margin = Value
        val TOP,BOTTOM,LEFT,RIGHT = Value
    }

    //type
    type MutableMap[K,V] = scala.collection.mutable.Map[K,V]
    val MutableMap = scala.collection.mutable.Map
}
 
package com.scala.objects.Tools

object MainDriver extends App {
    echo("Hello World")
    echo(MAGIN_NUM)
    echo(Margin.LEFT)

    val mm = MutableMap("name"->"nicky")
    mm += ("age"->"20")
    for((k,v) <- mm) {
        printf("key: %s, value: %s\n",k,v)
    }
}

 

 

2.5 不使用new关键字创建对象实例

两种办法:

第一种:定义case class 类名,它在内部会自己创建apply方法,我们就可以不用new

case class People(name:String, var age:Int) {
    def func(): Unit ={
        println(name,age)
    }
}

 

第二种:为类创建伴生对象,然后在伴生对象,我们自己提供apply方法

class Pizza(var crustType:String) {
    var price:Float = 0.0f;
    def func(): Unit ={
        println("披萨价格是=> "+price)
    }
}

object Pizza{
    val CRUST_TYPE_THIN = "thin";
    val CRUST_TYPE_THICK = "thick"
    def getFoo = "Foo"

    def apply(crustType:String):Pizza = {
        val p = new Pizza(crustType)
        p
    }
}

 

其实内部也还是使用new去创建

2.6 在scala中用apply方法实现工厂方法

在scala中实现工厂方法,让子类声明哪一种对象应该被创建

我们可以利用半生对象的apply方法,与其为了工厂创建get方法,不如将工厂的决策算法放在apply方法内

 

需求:创建Animal 工厂,返回Cat和Dog的实例

abstract class Pet(name:String, age:Int) {
    /*定义抽象属性,子类来实现*/
    val greeting:String
    var color:String
    def sayHello{println(greeting)}
    /*定义抽象方法,子类来实现*/
    def action
    override def toString:String = s"I say: $greeting, and I'm $age, my color is $color"
}

object Pet {
    def apply(kind:String):Pet = {
        if ("cat".equals(kind)) {
            new Cat("小花", 2)
        } else {
            new Dog("小白", 3)
        }
    }
}

 

class Dog(name:String,age:Int) extends Pet(name,age){
    val greeting = "汪汪"
    var color = "白色"

    override def action: Unit = {
        print("我正在啃骨头")
    }
}

class Cat(name:String, age:Int) extends Pet(name,age){
    val greeting = "喵喵"
    var color = "黑色"

    override def action: Unit = {
        print("我正在卖萌")
    }
}

 

object ClassClient {
    def main(args: Array[String]) {
        val dog = Pet("dog")
        val cat = Pet("cat")
        println(dog.sayHello)
        println(cat.sayHello)
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫言静好、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值