|NO.Z.00032|——————————|BigDataEnd|——|Hadoop&Scala.V05|——|Scala.v05|类与对象|对象|

一、单例对象
### --- 单例对象

~~~     Scala并没有提供Java那样的静态方法或静态字段;
~~~     可以采用object关键字实现单例对象,具备和Java静态方法同样的功能;
~~~     使用object语法结构【object是Scala中的一个关键字】达到静态方法和静态字段的目的;
~~~     对象本质上可以拥有类的所有特性,除了不能提供构造器参数;
### --- 对于任何在Java中用单例对象的地方,在Scala中都可以用object实现:

~~~     作为存放工具函数或常量的地方
~~~     高效地共享单个不可变实例
### --- 代码示例

class Session {
    def hello(first: Int): Int = {
        println(first)
        first
    }
}
object SessionFactory {
    val session = new Session
    def getSession(): Session = {
        session
    }
    def main(args: Array[String]): Unit = {
        for (x <- 1 to 10) {
            //通过直接调用,产生的对象都是单例的
            val session = SessionFactory.getSession()
            println(session)
        }
    }
}
### --- Scala中的单例对象具有如下特点:

~~~     创建单例对象不需要使用new关键字
~~~     object中只有无参构造器
~~~     主构造代码块只能执行一次,因为它是单例的
object ObjectDemo {
    println("这是单例对象的代码!")
    def main(args: Array[String]): Unit = {
        val object1=ObjectDemo
        val object2=ObjectDemo
    }
}
二、编程代码实现
### --- 编程代码

package yanqi.cn.part04

object Object {
  println("这是单例对象的代码!")

  def printInfo: Unit = {
    println("Hello Scala Object!")
  }
}

object ObjectDemo {
  def main(args: Array[String]): Unit = {
//    val object1=Object
//    val object2=Object

    Object.printInfo
    Object.printInfo
  }
}
### --- 编译打印

D:\JAVA\jdk1.8.0_231\bin\java.exe "-javaagent:D:\IntelliJIDEA\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=55788:D:\IntelliJIDEA\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath D:\JAVA\jdk1.8.0_231\jre\lib\charsets.jar;D:\JAVA\jdk1.8.0_231\jre\lib\deploy.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\access-bridge-64.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\cldrdata.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\dnsns.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\jaccess.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\jfxrt.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\localedata.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\nashorn.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunec.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunjce_provider.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunmscapi.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunpkcs11.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\zipfs.jar;D:\JAVA\jdk1.8.0_231\jre\lib\javaws.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jce.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jfr.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jfxswt.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jsse.jar;D:\JAVA\jdk1.8.0_231\jre\lib\management-agent.jar;D:\JAVA\jdk1.8.0_231\jre\lib\plugin.jar;D:\JAVA\jdk1.8.0_231\jre\lib\resources.jar;D:\JAVA\jdk1.8.0_231\jre\lib\rt.jar;E:\NO.Z.10000——javaproject\NO.Z.00002.Hadoop\ScalaPro\out\production\ScalaPro;D:\JAVA\scala-2.12.2\lib\scala-library.jar;D:\JAVA\scala-2.12.2\lib\scala-reflect.jar yanqi.cn.part04.ObjectDemo
这是单例对象的代码!
Hello Scala Object!
Hello Scala Object!

Process finished with exit code 0

三、伴生类与伴生对象
### --- 伴生类与伴生对象

~~~     当单例对象与某个类具有相同的名称时,它被称为这个类的“伴生对象”;
~~~     类和它的伴生对象必须存在于同一个文件中,而且可以相互访问私有成员(字段和方法);
### --- 编程代码示例

class ClassObject {
    val id = 1
private var name = "yanqi"
def printName(): Unit ={
    //在ClassObject类中可以访问伴生对象ClassObject的私有字段
    println(ClassObject.CONSTANT + name )
}
}

object ClassObject{
    //伴生对象中的私有字段
    private val CONSTANT = "汪汪汪"
    def main(args: Array[String]) {
        val p = new ClassObject
        //访问伴生类的私有字段name
        p.name = "123"
        p.printName()
    }
}
四、编程实现
### --- 编程代码

package yanqi.cn.part04

//伴生类和伴生对象,它们的名字是一样的,并且必须存在于同一文件中
class ClassObject {
  private var name = "yanqi"

  def printInfo: Unit = {
    //在伴生类中可以访问伴生对象的私有成员
    println(ClassObject.num)
    println("Hello Object!")
  }
}

object ClassObject {
  private val num = 10

  def main(args: Array[String]): Unit = {
    val classObject = new ClassObject
    //在伴生对象中可以访问伴生类的私有成员
    println(classObject.name)
    classObject.printInfo
  }
}
### --- 编译打印

D:\JAVA\jdk1.8.0_231\bin\java.exe "-javaagent:D:\IntelliJIDEA\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=55965:D:\IntelliJIDEA\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath D:\JAVA\jdk1.8.0_231\jre\lib\charsets.jar;D:\JAVA\jdk1.8.0_231\jre\lib\deploy.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\access-bridge-64.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\cldrdata.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\dnsns.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\jaccess.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\jfxrt.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\localedata.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\nashorn.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunec.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunjce_provider.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunmscapi.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunpkcs11.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\zipfs.jar;D:\JAVA\jdk1.8.0_231\jre\lib\javaws.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jce.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jfr.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jfxswt.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jsse.jar;D:\JAVA\jdk1.8.0_231\jre\lib\management-agent.jar;D:\JAVA\jdk1.8.0_231\jre\lib\plugin.jar;D:\JAVA\jdk1.8.0_231\jre\lib\resources.jar;D:\JAVA\jdk1.8.0_231\jre\lib\rt.jar;E:\NO.Z.10000——javaproject\NO.Z.00002.Hadoop\ScalaPro\out\production\ScalaPro;D:\JAVA\scala-2.12.2\lib\scala-library.jar;D:\JAVA\scala-2.12.2\lib\scala-reflect.jar yanqi.cn.part04.ClassObject
yanqi
10
Hello Object!

Process finished with exit code 0

五、应用程序对象
### --- 应用程序对象

~~~     每个Scala应用程序都必须从一个对象的main方法开始,
~~~     这个方法的类型为 Array[String] => Unit;
~~~     备注:main方法写在class中是没有意义的,
~~~     在IDEA中这样的 class 连run的图标都不能显示
~~~     除了main方法以外,也可以扩展App特质(trait)
### --- 编程示例

object Hello extends App {
    if (args.length > 0)
        println(s"Hello World; args.length = ${args.length}")
    else
        println("Hello World")
}
六、编程实现
### --- 编程代码

package yanqi.cn.part04

object AppDemo extends App {
  println("Hello Spark!")
}
### --- 编译打印

D:\JAVA\jdk1.8.0_231\bin\java.exe "-javaagent:D:\IntelliJIDEA\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=55989:D:\IntelliJIDEA\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath D:\JAVA\jdk1.8.0_231\jre\lib\charsets.jar;D:\JAVA\jdk1.8.0_231\jre\lib\deploy.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\access-bridge-64.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\cldrdata.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\dnsns.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\jaccess.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\jfxrt.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\localedata.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\nashorn.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunec.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunjce_provider.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunmscapi.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunpkcs11.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\zipfs.jar;D:\JAVA\jdk1.8.0_231\jre\lib\javaws.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jce.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jfr.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jfxswt.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jsse.jar;D:\JAVA\jdk1.8.0_231\jre\lib\management-agent.jar;D:\JAVA\jdk1.8.0_231\jre\lib\plugin.jar;D:\JAVA\jdk1.8.0_231\jre\lib\resources.jar;D:\JAVA\jdk1.8.0_231\jre\lib\rt.jar;E:\NO.Z.10000——javaproject\NO.Z.00002.Hadoop\ScalaPro\out\production\ScalaPro;D:\JAVA\scala-2.12.2\lib\scala-library.jar;D:\JAVA\scala-2.12.2\lib\scala-reflect.jar yanqi.cn.part04.AppDemo
Hello Spark!

Process finished with exit code 0

七、apply方法
### --- apply方法:

~~~     object 中有一个非常重要的特殊方法 -- apply方法;
~~~     apply方法通常定义在伴生对象中,
~~~     目的是通过伴生类的构造函数功能,来实现伴生对象的构造函数功能;
~~~     通常我们会在类的伴生对象中定义apply方法,当遇到类名(参数1,...参数n)时apply方法会被调用;
~~~     在创建伴生对象或伴生类的对象时,通常不会使用new class/class() 的方式,
~~~     而是直接使用class()隐式的调用伴生对象的 apply 方法,这样会让对象创建的更加简洁;
### --- 编程示例

//class Student为伴生类
class Student(name: String, age: Int) {
    private var gender: String = _
    def sayHi(): Unit ={
        println(s"大家好,我是$name,$gender 生")
    }
    }
    
    //object Student是class class的伴生对象
    object Student {
        
        //apply方法定义在伴生对象中
        def apply(name: String, age: Int): Student = new Student(name, age)
        def main(args: Array[String]): Unit = {
            
            //直接利用类名进行对象的创建,这种方式实际上是调用伴生对象的apply方法实现的
            val student=Student("jacky",30)
            student.gender="男"
        student.sayHi()
    }
}
### --- 问题:在Scala中实现工厂方法,让子类声明哪种对象应该被创建,保持对象创建在同一位置。

~~~     例如,假设要创建Animal工厂,让其返回Cat和Dog类的实例,基于这个需求,
~~~     通过实现Animal伴生对象的apply方法,工厂的使用者可以像这样创建新的Cat和Dog实例。
 
abstract class Animal {
    def speak
}
class Dog extends Animal {
    override def speak: Unit = {
        println("woof")
    }
    }

class Cat extends Animal {
    override def speak: Unit = {
        println("meow")
    }
    }
object Animal {
    def apply(str: String): Animal = {
        if (str == "dog")
        new Dog
        else
        new Cat
    }
    def main(args: Array[String]): Unit = {
        val cat = Animal("cat")
        cat.speak
    val dog = Animal("dog")
    dog.speak
}
}
八、编程实现
### --- 编程代码

package yanqi.cn.part04

class Student(name: String, age: Int) {
  private var gender: String = _

  def sayHi(): Unit = {
    println(s"大家好,我是$name,$gender 生")
  }
}

object Student {
  //apply方法需要定义在伴生对象中
  def apply(name: String, age: Int): Student = new Student(name, age)

  def main(args: Array[String]): Unit = {
    //直接使用class(参数...)这种方式隐式调用伴生对象中的apply方法来创建class Student对象
    val student = Student("jacky", 30)
    //伴生类与伴生对象可以相互访问私有成员
    student.gender = "男"

    student.sayHi()
  }
}
### --- 编译打印

D:\JAVA\jdk1.8.0_231\bin\java.exe "-javaagent:D:\IntelliJIDEA\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=56017:D:\IntelliJIDEA\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath D:\JAVA\jdk1.8.0_231\jre\lib\charsets.jar;D:\JAVA\jdk1.8.0_231\jre\lib\deploy.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\access-bridge-64.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\cldrdata.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\dnsns.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\jaccess.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\jfxrt.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\localedata.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\nashorn.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunec.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunjce_provider.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunmscapi.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\sunpkcs11.jar;D:\JAVA\jdk1.8.0_231\jre\lib\ext\zipfs.jar;D:\JAVA\jdk1.8.0_231\jre\lib\javaws.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jce.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jfr.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jfxswt.jar;D:\JAVA\jdk1.8.0_231\jre\lib\jsse.jar;D:\JAVA\jdk1.8.0_231\jre\lib\management-agent.jar;D:\JAVA\jdk1.8.0_231\jre\lib\plugin.jar;D:\JAVA\jdk1.8.0_231\jre\lib\resources.jar;D:\JAVA\jdk1.8.0_231\jre\lib\rt.jar;E:\NO.Z.10000——javaproject\NO.Z.00002.Hadoop\ScalaPro\out\production\ScalaPro;D:\JAVA\scala-2.12.2\lib\scala-library.jar;D:\JAVA\scala-2.12.2\lib\scala-reflect.jar yanqi.cn.part04.Student
大家好,我是jacky,男 生

Process finished with exit code 0

 
 
 
 
 
 
 
 
 

Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
                                                                                                                                                   ——W.S.Landor

 

 

posted on   yanqi_vip  阅读(16)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示