简体   繁体   中英

how to simulated multiple inheritance pattern in F#?

I have one class Service and One interface IService . I want to implement this two to ExampleService class.

I know C# and in C# we can do this using below code

class ExampleService : Service, IService
{
}

How can i do in F#.Thanks.

type ExampleService() =
    inherit Service()

    interface IService with
    // Below is interface implementation
        member x.ImplementedInterfaceMember() = 
            ...

First, lets take a look in the interface syntax in the F# wiki page here:

open System

type Person(name : string, age : int) = 
 member this.Name = name
 member this.Age = age

(* IComparable is used for ordering instances *)
 interface IComparable<Person> with
    member this.CompareTo(other) =
        (* sorts by name, then age *)
        match this.Name.CompareTo(other.Name) with
        | 0 -> this.Age.CompareTo(other.Age)
        | n -> n

(* Used for comparing this type against other types *)
 interface IEquatable<string> with
    member this.Equals(othername) = this.Name.Equals(othername)

As you can see, interfaces are included inside classes, and their functionality is described via the keyword with .

Now let's see the inheritence module as it's described in the official MSDN site:

type MyClassBase1() =
  let mutable z = 0
  abstract member function1 : int -> int
  default u.function1(a : int) = z <- z + a; z

type MyClassDerived1() =
  inherit MyClassBase1()
  override u.function1(a: int) = a + 1

Here, the other class is written outside, and the implementation/overrides come after the keyword inherits .

So, in your case:

type Service()=
 (* Service parent class details here *)

type ExampleService() = 
 inherit Service()
 (* More stuff about the parent class here, i.e overrides *)
 interface IService<ExampleClass> with
 (* Add here the interface details. *)

I know this is a bit tangential to the content of the original question, but the answers here don't address the more general title of the question which is currently pushing this to the top search result for "F# multiple inheritance".

It is possible to simulate multiple inheritance through serial inheritance:

type A() =
    member z.hello a = $"Hello %s{a}"

type B() =
    inherit A()
    member z.goodbye a = $"Goodbye %s{a}"

type C() =
    inherit B()
    member z.howAreYou n = $"%s{z.hello n}, how are you?"

let c = C()
c.howAreYou "world"

Every instance of C will have the members of A and B here.

Another alternative is composition instead of inheritance where the classes which implement the desired functionality are properties of the composing class:

type A() =
    member z.hello a = $"Hello %s{a}"

type B() =
    member z.goodbye a = $"Goodbye %s{a}"

type C(a: A, b: B) =
    member z.A = a
    member z.B = b
    member z.howAreYou n = $"%s{z.A.hello n}, how are you?"


let c = C(A(), B())
c.howAreYou "world"

As noted by Joel in the comments, the original post isn't actually describing multiple inheritance. But, in good faith, OP's query could be answered by inheriting from Service and implementing IService in ExampleService as A. Abramov explained. (Though, from a design perspective, I would expect Service to be implementing IService , but that wasn't the question.)

type IService =
    abstract member greet: string -> string

type Service() =
    member z.serve n = $"%s{n}, your dinner is served"

type ExampleService() =
    inherit Service()

    interface IService with
        member z.greet n = "Welcome to chez sharp, %s{n}"

let e = ExampleService()
(e :> IService).greet "world"

However, as noted in the MSDN docs on interfaces , one must call interface members explicitly through the use of the upcast operator. Depending on your use case, this extra step may make serial inheritance or composition a better solution with serial inheritance being the closest to multiple inheritance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM