Scala之面向对象(2)

news2025/2/26 3:48:55

目录

单例对象(伴生对象):

创建对象常用的两种方法:

(1)使用构造器构造(new)

(2)使用静态方法

 伴生对象的定义:

apply方法:

apply方法的调用:

单例模式:

单例模式分为两种:

1.懒汉式

2.饿汉式:(推荐)

特质(Trait):

基本语法:

说明

特质叠加:

特质和抽象类的区别:

单例对象(伴生对象):

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

创建对象常用的两种方法:

(1)使用构造器构造(new)

    val person0 = new Person09()

(2)使用静态方法

(在Scala中没有静态方法与之等价的是object---伴生对象)

    val person01: Person09 = Person09.getPerson()

 伴生对象的定义:

object Person09{
  def getPerson():Person09=new Person09
}

          方法2主要是在将构造器私有化的时候是无法new的  这时就需要使用伴生对象构造           

class Person09 private{
  val name :String="张三"
}

apply方法:

在Scala中引入了一个apply()方法模板  来替代上述的伴生对象的构造方法   在伴生对象中创建了方法,直接在main方法中调用apply方法即可

apply()方法在Scala中是做出了改进 在函数进行调用的时候可以不写方法名,直接进行调用

apply方法的调用:

    val person0: Person09 = Person09()

apply方法也是可以进行任意自定义的  没必要一定跟模板一样创建一个对象

特点就是可以不写方法名

直接Person09() 就能调用apply方法

系统在集合当中使用非常广泛,调用对象的apply方法

下边集合 Array就是一个对象  使用.var 自动生成对象  其实是Array集合

    val ints: Array[Int] = Array(1, 2, 3, 4)  

单例模式:

单例模式是确保一个类只有一个实例,即不能随便被创建对象,所以构造方法要使用private进行私有化,不能被外界进行实例化,这个实例是当前类的类成员变量,即类静态成员变量,这个静态变量需要提供给外界,所以需要提供静态方法向外界提供当前实例

单例模式分为两种:

1.懒汉式

占用内存少(减少创建对象的数量),线程不安全(在某个时间段 都进入if判断,都为真,都会赋值产生变量   就会产生线程安全---只会出现在第一次初始化的时候)

  class Singleton09 private{
  }
  object Singleton09{        //相当于静态方法 在静态方法中创建对象 便于外边的访问
    //先声明属性     先声明为null  后边获取的时候再赋值
    private var singleton:Singleton09=null;
    def apply(): Singleton09 = {
              if (singleton==null)
                {
                  singleton = new Singleton09
                }
                  singleton
    }
  }

2.饿汉式:(推荐)

饿汉式没有线程安全问题,写起来简单,占用内存多(提前创建)   它是在伴生对象中先进行创建对象 在jvm中进行类加载,这样就避免了线程安全问题

object Singleton09 {
  private var singleton: Singleton09 = new Singleton09;
  def apply(): Singleton09 = singleton
}

判断单例模式:

  def main(args: Array[String]): Unit = {
    //判断单例模式是否正确
    val singleton:Singleton09=Singleton09();
    val singleton1:Singleton09=Singleton09();
    println(singleton)
    println(singleton1)
  }

 可以看到地址值相同

特质(Trait):

Scala 语言中,采用特质 trait (特征)来代替接口的概念 ,也就是说,多个类具有相同
的特质(特征)时,就可以将这个特质(特征)独立出来,采用关键字 trait 声明。
Scala 中的 trait 中即 可以有抽象属性和方法,也可以有具体的属性和方法 一个类可
以混入( mixin )多个特质 。这种感觉 类似于 Java 中的抽象类( 现在就是接口--->现在的接口是可以有具体的属性和方法 )。
一个类具有某种特质(特征),就意味着这个类满足了这个特质(特征)的所有要素,
所以在使用时,也采用了 extends 关键字 ,如果有多个特质或存在父类,那么需要采用 with
关键字 连接。

基本语法:

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

说明

1 )类和特质的关系:使用继承的关系。
2 )当一个类去继承特质时,第一个连接词是 extends ,后面是 with
3 )如果一个类在同时继承特质和父类时,应当把父类写在 extends
(4)一个类可以混入多个特质
(5)所有的Java接口都可以当作Scala的特质进行使用
  class Person11 extends Young11 with old11 with java.io.Serializable{}

(6)动态混入:可灵活的扩展类的功能

        (6.1)动态混入:创建对象时混入 trait,而无需使类混入该 trait
        (6.2)如果混入的 trait 中有未实现的方法,则需要实现
        (6.3)如果特质中有抽象的方法和属性也是需要重写的
(7)特质冲突:如果继承的父类和特质中有相同的名称的具体数据(非抽象属性--抽象的可                   以重写)会报错冲突
如果属性是val  是可以在类中创建一个新的对象进行赋值改变 
如果属性是var 是不可以的 报错误

特质叠加:

        
        由于一个类可以混入(mixin )多个 trait ,且 trait 中可以有具体的属性和方法,若混入
的特质中具有相同的方法(方法名,参数列表,返回值均相同),必然会出现继承冲突问题。
冲突分为以下两种:
(1)第一种,一个类( Sub )混入的两个 trait TraitA TraitB )中具有相同的具体方法,且
两个 trait 之间没有任何关系,解决这类冲突问题,直接在类( Sub )中重写冲突方法。
(2)第二种,一个类( Sub )混入的两个 trait TraitA TraitB )中具有相同的具体方法,且
两个 trait 继承自相同的 trait TraitC ),及所谓的“钻石问题”,解决这类冲突问题, Scala
采用了 特质叠加 的策略。
钻石问题测试:
package chapter04
object Test11_TraitMinxin2 {
  def main(args: Array[String]): Unit = {
    val person1 = new Person12
    println(person1.Info())
  }
}
trait Age12{
val age:Int
  def Info()="age "
}
//下边两个特质均继承自Age12
trait Young12 extends Age12{
  override val age: Int = 12
  override def Info(): String = super.Info()+"Young "
}
trait Old12 extends  Age12{
  override val age: Int = 13
  override def Info(): String = super.Info()+"Old12 "
}
//钻石效应
class Person12 extends Young12 with  Old12 {
  override def Info(): String = super.Info()+"Person12 "
}

测试结果:

 上述结果说明,在产生钻石问题的时候会按照继承关系进行一个排序来进行调用

当我们如果只想调用某一个类的时候方法的时候,可以对继承的类进行指定

对Person12类进行了修改:

class Person12 extends Young12 with  Old12 {
  override def Info(): String = super[Young12].Info()+"Person12 "
}

执行结果:

特质和抽象类的区别:

1. 优先使用特质。一个类扩展(继承)多个特质是很方便的,但却只能扩展一个抽象类。
2. 如果你需要构造函数参数,使用抽象类。因为抽象类可以定义 带参数 的构造函数,
   而特质不行(只有无参构造)。
面向对象的扩展:
(1)类型检查和转换
在使用多态的时候,无法调用子类独有的方法,所以需要进行强制类型转换(在Scala中是使用方法进行强制类型转换)
代码样例:
package chapter04
object Test_14_Rxtends {
  def main(args: Array[String]): Unit = {
//多态
    var son:father14 =new son14
    val son1: son14 = son.asInstanceOf[son14]
    son1.sayHi()
  }
}
class father14{
}
class son14 extends father14 {
def sayHi(): Unit ={
  println("hi son")
}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/427492.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图像分割技术及经典实例分割网络Mask R-CNN(含基于Keras Python源码定义)

图像分割技术及经典实例分割网络Mask R-CNN(含Python源码定义) 文章目录图像分割技术及经典实例分割网络Mask R-CNN(含Python源码定义)1. 图像分割技术概述2. FCN与语义分割2.1 FCN简介2.2 反卷积2.2 FCN与语义分割的关系3. Mask …

Midjourney以图生图的详细教程(含6种案例介绍)

🏆 文章目标:学习并介绍Midjourney以图生图的详细教程 🍀 Midjourney以图生图的详细教程 ✅ 创作者:熊猫Jay 🎉 个人主页:Jay的个人主页 🍁 展望:若本篇讲解内容帮助到您&#xff0c…

SQL Server 单表数据查询

提示: 本篇文章详细介绍怎样向SQLServer中导入表格数据,导入之后根据不同的查询条件完成查询任务. 文章目录前言一、向SQL Server中导入数据二、例题1.查询所有学生的全部信息2.查询学生的学号和姓名3.查询所有学生的姓名和出生年4. 查询所有学生的姓名和出生年&…

【关于Linux中----生产消费模型】

文章目录一、生产消费模型1.1概念的引入1.2 321原则二、条件变量2.1概念的引入2.2理解条件变量2.3条件变量的使用三、基于BlockingQueue的生产者消费者模型3.1BlockingQueue的介绍3.2C queue模拟阻塞队列的生产消费模型3.3对生产消费任务的模拟封装四、遗留问题一、生产消费模型…

基于YOLOv5的水下海洋目标检测

摘要:水下海洋目标检测技术具有广泛的应用前景,可以用于海洋环境监测、海洋资源开发、海洋生物学研究等领域。本文提出了一种基于 YOLOv5 的水下海洋目标检测方法,使用数据增强方法进行了大量实验,并与其他方法进行了对比&#xf…

(SQL学习随笔3)SQL语法——SELECT语句

导航基本认识FROM关键字LIMIT与OFFSETORDER BYWHERE条件查询单值比较多条件组合范围筛选空值匹配LIKE通配条件分组运算符和函数数据变换分组运算表连接内连接左(右)外连接全外连接外键约束窗口函数UNION:表上下拼接子查询条件判断PostgreSQLMySQL基本认识 SELECT t…

【论文阅读】BiSeNet V2用于实时语义分割的双边网络

前言BiSeNet V2延续了v1版本的双边结构,分别处理空间细节信息、高层语义信息。同时设计更简洁高效的结构,进行特征提取,实现高精度和高速度。在训练模型时,使用了增强训练策略 ,添加多个辅助训练分支来促进不同浅层网络…

Spring-aop面向切面

1、理解必要的专业术语 先看看上面图,这是我的个人理解。(画的丑,主打真实) 1)Advice,通知/增强:类方法中提出来的共性功能(大白话就是提出来的重复代码) 2)Pointcut,切入点/切点&#…

【微服务】微服务架构下你不得不知的3种部署策略

文章目录前言滚动部署蓝绿部署金丝雀部署总结前言 不知道大家有了解过你们公司的软件产品是如何部署的么?采用的什么部署策略?其实在软件开发生命周期中,部署是非常关键的一环,你需要考虑多方面的因素,如何保证你部署…

【推荐算法】CTR中embedding层的学习和训练

note 连续特征处理:facebook DLRM模型,对连续值的处理方式是把所有的连续值输入到一个神经网络,然后通过神经网络把它压缩到一个embedding维度大小的一个向量上,然后将Embedding和其他离散特征Embedding Concat起来,再…

springboot-分页功能

1.分页功能的作用 分页功能作为各类网站和系统不可或缺的部分(例如百度搜索结果的分页等) ,当一个页面数据量大的时候分页作用就体现出来的,其作用有以下5个。 (1)减少系统资源的消耗 (2&#…

redis设计与实现读书笔记

这里主要记录一下在阅读redis设计与实现中碰到的一些没有记录过的知识。 引用计数技术 Redis的对象系统实现了基于引用计数技术的内存回收机制,当程序不再使用某个对象的时候,这个对象所占用的内存就会被自动释放;另外,Redis还通过引用计数…

低调且强大--iVX低代码平台

iVX目录前言一、低代码那么多 为什么选择iVX?二、“拼”出来的低代码平台,真的好用吗?三、iVX与其他低代码有啥可比性?前言 首先我们应该明白自动编程突破可能是:领域内Mini LLM 现在的思路都是搞LLM,几乎像…

通俗举例讲解动态链接、静态链接

参考动态链接 - 知乎 加上我自己的理解,比较好懂,但可能在细节方面有偏差,但总体是一致的 静态链接的背景 静态链接使得不同的程序开发者和部门能够相对独立的开发和测试自己的程序模块,从某种意义上来讲大大促进了程序开发的效率&#xf…

NPC 也有了生命?当 ChatGPT 注入游戏你能想象吗

🍎道阻且长,行则将至。🍓 目录引言:西部世界元宇宙,还记得吗ChatGPT 的世界?下图就是一个 ChatGPT 小镇: 引言:西部世界 《西部世界》以一个虚构的游戏般的“西部世界”为背景&am…

springboot验证码生成及验证功能

1.easy-captcha工具包 生成验证码的方式有许多种,这里选择的是easy-captcha工具包。 github开原地址为:easy-captcha工具包 其支持Java图形验证码,支持gif、中文、算术等类型,可用于Java Web、JavaSE等项目。 2添加依赖 首先需…

SQL Server的死锁说明

死锁指南一、了解死锁二、检测并结束死锁2.1、可能死锁的资源三、处理死锁四、最大限度地减少死锁4.1、以相同的顺序访问对象4.2、避免事务中的用户交互4.3、保持交易简短且在一个批次中4.4、使用较低的隔离级别4.5、使用基于行版本控制的隔离级别4.6、使用绑定连接4.7、停止事…

【云原生|Docker】04-docker的资源限制

目录 前言 容器的生命周期 1. 容器的启动过程 2. 容器的生命周期 ​编辑 内存限制 1. 内存限制的相关参数 2. 内存限制方式 2.1 设置-m,--memory,不设置--memory-swap 2.2 设置-m,--memorya,--memory-swapb,且b >a 2.…

本地从0搭建Stable Diffusion WebUI及错误记录

从0开始搭建本地Stable Diffusion WebUI环境 一.环境配置 1.使用的电脑配置 系统Windows10处理器英特尔 i7内存24GB显卡NVIDIA GTX 1060(6GB) 2.镜像源 阿里云 清华大学 中国科技大学 3.电脑环境变量配置 我的电脑–属性–高级系统设置–系统属性(高级)–环境变量 新建…

spring框架注解

3.Spring有哪些常用注解呢? Spring常用注解 Web: Controller:组合注解(组合了Component注解),应用在MVC层(控制层)。 RestController:该注解为一个组合注解,相当于Con…