Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 混合和继承之间有什么区别?_Scala_Oop - Fatal编程技术网

Scala 混合和继承之间有什么区别?

Scala 混合和继承之间有什么区别?,scala,oop,Scala,Oop,我试图在scala的上下文中理解mixin。我特别想知道继承和混合概念之间的区别 Mixin的定义是: mixin类充当父类,包含所需的功能。然后,子类可以继承或简单地重用此功能,但不能作为专门化的手段。通常,mixin会将所需的功能导出到子类,而不会创建一个僵硬的、单一的“is-a”关系。这里是mixin和继承概念之间的重要区别,因为子类仍然可以继承父类的所有特性,但是,不必应用关于子类“是”父类的语义 在上述定义中,我无法理解用粗体标记的语句。这是什么意思 子类可以继承mixin中的功能,但

我试图在scala的上下文中理解mixin。我特别想知道继承和混合概念之间的区别

Mixin的定义是:

mixin类充当父类,包含所需的功能。然后,子类可以继承或简单地重用此功能,但不能作为专门化的手段。通常,mixin会将所需的功能导出到子类,而不会创建一个僵硬的、单一的“is-a”关系。这里是mixin和继承概念之间的重要区别,因为子类仍然可以继承父类的所有特性,但是,不必应用关于子类“是”父类的语义

在上述定义中,我无法理解用粗体标记的语句。这是什么意思

  • 子类可以继承mixin中的功能,但不能作为专门化的手段
  • 在mixin中,子类继承父类的所有特性,但不必应用关于子类“是一种”父类的语义。-孩子如何扩展父母而不一定是父母?有这样的例子吗

  • 我认为这是在讨论实际的类层次结构。例如,
    Dog
    Animal
    的一种类型,如果它是从类(继承)扩展而来的。它可以在
    动物
    参数适用的任何地方使用。

    我不确定我是否正确理解了你的问题,但如果我理解了,你是在问什么东西可以继承,而不是真正意义上的继承

    然而,mixin不是继承——它实际上更类似于动态地将一组方法添加到对象中。继承说“这个东西是另一种东西”,而mixin说,“这个对象有这个东西的一些特征。”你可以在用于声明mixin的关键字中看到这一点:
    trait

    要从Scala主页上公然窃取一个示例:

    abstract class Spacecraft {
      def engage(): Unit
    }
    trait CommandoBridge extends Spacecraft {
      def engage(): Unit = {
        for (_ <- 1 to 3)
          speedUp()
      }
      def speedUp(): Unit
    }
    trait PulseEngine extends Spacecraft {
      val maxPulse: Int
      var currentPulse: Int = 0
      def speedUp(): Unit = {
        if (currentPulse < maxPulse)
          currentPulse += 1
      }
    }
    class StarCruiser extends Spacecraft
                         with CommandoBridge
                         with PulseEngine {
      val maxPulse = 200
    }
    
    抽象类航天器{
    def接合():装置
    }
    特徵CommandoBridge扩展航天器{
    def接合():装置={
    例如(trait(与类混合时称为mixin)就像Java中的一个接口(尽管有很多),在这个接口中,您可以向类添加额外的特性,而不必具有“is A”关系。或者您可以说,通常trait将多个独立类可以使用的特性捆绑在一起

    给你一个Scala库的例子,是一个
    trait
    ,它提供了一些基本的比较操作(比如
    =
    )到类的实现,这些类可以具有自然排序的数据

    例如,假设您有自己的类
    Number
    和子类
    EvenNumber
    OddNumber
    ,如下所示

    class Number(val num : Int) extends Ordered[Number] {
      override def compare(that : Number) = this.num - that.num
    }
    
    trait Half extends Number {
      def half() = num / 2
    }
    
    trait Increment extends Number {
      def increment() = num + 1
    }
    
    class EvenNumber(val evenNum : Int) extends Number(evenNum) with Half
    
    class OddNumber(val oddNum : Int) extends Number(oddNum) with Increment
    
    在上面的例子中,类
    EvenNumber
    OddNumber
    share
    Number
    是一种关系,但是
    EvenNumber
    Half
    没有“是”关系,也不是
    OddNumber
    share”与
    Increment
    的关系


    另一个重要的观点是,尽管类
    Number
    使用
    扩展有序的
    语法,但这意味着
    Number
    有一个隐含的关系,即
    有序的超类,即
    任何

    ,我认为它非常依赖于用法。Scala是一种多范式语言,因此它是powerful以及有时有点混乱。 我认为如果使用正确的方法,mixin是非常强大的。 应使用混合剂来引入行为并减少bolierplate

    Scala中的一个特性可以有实现,并且很容易扩展和使用它们

    Traits可以用于继承。它也可以被称为mixin,但在我看来,这不是使用
    mixin
    行为的最佳方式。在这种情况下,您可以将Traits视为Java抽象类。在这种情况下,您可以得到超类(trait)的“类型”的子类

    但是,trait也可以用作
    适当的mixin
    。现在,将trait用作
    mixin
    取决于实现,即“如何将其混合”。这主要是一个简单的问题,你可以问自己“特质的子类是否真的是该特质的
    种类
    ,或者特质行为中的行为是否简化了样板”。 通常,最好通过将特征混合到对象中来实现,而不是扩展特征来创建新类

    例如,考虑下面的例子:

        //All future versions of DAO will extend this
    trait AbstractDAO{
      def getRecords:String
      def updateRecords(records:String):Unit
    }
    //One concrete version
    trait concreteDAO extends AbstractDAO{
      override def getRecords={"Here are records"}
      override def updateRecords(records:String){
        println("Updated "+records)
      }
    }
    //One concrete version
    trait concreteDAO1 extends AbstractDAO{
      override def getRecords={"Records returned from DAO2"}
      override def updateRecords(records:String){
        println("Updated via DAO2"+records)
      }
    }
    //This trait just defines dependencies (in this case an instance of AbstractDAO) and defines operations based over that
    trait service{
      this:AbstractDAO =>
    
      def updateRecordsViaDAO(record:String)={  
      updateRecords(record) 
      }
      def getRecordsViaDAO={
      getRecords
      }
    }
    
    
    object DI extends App{
      val wiredObject = new service with concreteDAO //injecting concrete DAO to the service and calling methods
      wiredObject.updateRecords("RECORD1")
      println(wiredObject.getRecords)
    
      val wiredObject1 = new service with concreteDAO1
      wiredObject1.updateRecords("RECORD2")
      println(wiredObject1.getRecords)
    
    }
    
    concreteDAO
    是一种扩展了
    AbstractDAO
    的特性,这就是继承

    val wiredObject=使用concreteDAO的新服务
    - 这是正确的混合行为 由于服务特性要求
    AbstractDAO
    mixin
    service
    扩展
    ConcreteDAO
    无论如何都是错误的,因为
    service
    required
    AbstractDAO
    不是
    AbstractDAO
    的一种类型。
    相反,您使用不同的mixin创建
    服务的实例。

    mixin和继承的区别在于语义级别。在语法级别,它们都是相同的

    为了混入一个特征,或者从一个特征继承,它们都使用相同语法的
    extends
    with

    在语义层面上,一个想要被混合的特征通常没有一个
    是一个与混合它的类的
    关系,它不同于一个想要被继承的特征


    对我来说,一个特征是mixin还是父特征是非常主观的,这通常是一个混乱的根源。

    在Scala中,将mixin看作是一个整洁的编译时转换,它将用额外的方法装饰某些类型。在本文中