Non-interface methods in interface implementation - oop

I have an interface which defines a method. I have a struct which implements this interface. In it, I have implemented the methods from this interface and also have additional methods defined.
For example:
package main
import (
"fmt"
)
type Animal interface {
MakeNoise()
}
type Dog struct {
color string
}
/* Interface implementation */
func (d *Dog) MakeNoise() {
fmt.Println("Bark!")
}
/* End Interface implementation */
func (d *Dog) WagTail() {
fmt.Println(d.color + " dog: Wag wag")
}
func NewDog(color string) Animal {
return &Dog{color}
}
func main() {
dog := NewDog("Brown")
dog.MakeNoise()
dog.WagTail()
}
On Playground: https://play.golang.org/p/B1GgoNToNl_l
Here, WagTail() is not part of the Animal interface but belongs to the Dog struct. Running this code gives an error
dog.WagTail undefined (type Animal has no field or method WagTail).
Is there a way I could have a struct adhere to an interface and also define it's own methods?

This may help you.
d := dog.(*Dog)
d.WagTail()
On Playground: https://play.golang.org/p/KlNqpmvFTJi

The error described it all:
dog.WagTail undefined (type Animal has no field or method WagTail)
To implement an interface you should implement all methods defined inside it.
dog := NewDog("Brown")
dog.MakeNoise()
dog.WagTail()
Now NewDog returns Animal interface which contains MakeNoise method but not WagTail.
The only way to manage your requirement is either create a variable of struct type Dog and then you can call any method having Dog as receiver.
d := &Dog{"Brown"}
d.WagTail()
Or you can return the pointer to Dog struct from NewDog method just like you did in your code mentioned in the comment as:
func NewDog(color string) *Dog {
return &Dog{color}
}
But if the method is not defined in interface you cannot implement it using the struct as method receiver.
Golang provides a way in which:
You can ask the compiler to check that the type T implements the
interface I by attempting an assignment using the zero value for T or
pointer to T, as appropriate
type T struct{}
var _ I = T{} // Verify that T implements I.
var _ I = (*T)(nil) // Verify that *T implements I.
If T (or *T, accordingly) doesn't implement I, the mistake will be caught at compile time.
If you wish the users of an interface to explicitly declare that they
implement it, you can add a method with a descriptive name to the
interface's method set. For example:
type Fooer interface {
Foo()
ImplementsFooer()
}
A type must then implement the ImplementsFooer method to be a Fooer, clearly documenting the fact and announcing it in godoc's output.
type Bar struct{}
func (b Bar) ImplementsFooer() {}
func (b Bar) Foo() {}
Most code doesn't make use of such constraints, since they limit the
utility of the interface idea. Sometimes, though, they're necessary to
resolve ambiguities among similar interfaces.

You can definitely do it, one such method is using type assertion as shown in the other answer here. Otherwise the answer by #Himanshu here describes the situation very well.
I would like to add to the discussion to further describe how you
could have a struct adhere to an interface and also define it's own methods
The MakeDog method returns an Animal, and there are a number of reasons you may consider returning a Dog (or whichever concrete type) directly.
The reason I bring this up is because of something someone told me about creating methods when I first started programming in Go:
Accept an Interface and return a Concrete type (such as a Struct)
Interfaces can accept any concrete type. That's why they are used when you don't know the type of argument you are passing to the function.
I did a google search with the following terms and quite a few articles turned up
golang accept interface, return struct
For example: https://mycodesmells.com/post/accept-interfaces-return-struct-in-go and http://idiomaticgo.com/post/best-practice/accept-interfaces-return-structs/
I have put together a little bit of a demo extending on your concepts in your question to try and clearly describe interface methods as well as methods and attributes for specific types
Taken from this snippet on Playground
package main
import (
"fmt"
)
type Animal interface {
MakeNoise() string
}
// printNoise accepts any animal and prints it's noise
func printNoise(a Animal) {
fmt.Println(a.MakeNoise())
}
type pet struct {
nLegs int
color string
}
// describe is available to all types of Pet, but not for an animal
func (p pet) describe() string {
return fmt.Sprintf(`My colour is "%s", and I have "%d" legs`, p.color, p.nLegs)
}
type Dog struct {
pet
favouriteToy string
}
// MakeNoise implements the Animal interface for type Dog
func (Dog) MakeNoise() string {
return "Bark!"
}
// WagTail is something only a Dog can do
func (d Dog) WagTail() {
fmt.Println("I am a dog,", d.pet.describe(), ": Wags Tail")
}
type Cat struct {
pet
favouriteSleepingPlace string
}
// MakeNoise implements the Animal interface for type Cat
func (Cat) MakeNoise() string {
return "Meow!"
}
// ArchBack is something only a Cat can do
func (c Cat) ArchBack() {
fmt.Println("I am a cat,", c.pet.describe(), ": Arches Back")
}
type Bird struct {
pet
favoritePerch string
}
// MakeNoise implements the Animal interface for type Cat
func (Bird) MakeNoise() string {
return "Tweet!"
}
// Hop is something only a Bird can do
func (c Bird) Hop() {
fmt.Println("I am a bird,", c.pet.describe(), ": Hops to a different perch")
}
func main() {
dog := Dog{
pet: pet{nLegs: 4, color: "Brown"},
favouriteToy: "Ball",
}
printNoise(dog)
dog.WagTail()
cat := Cat{
pet: pet{nLegs: 4, color: "Tabby"},
favouriteSleepingPlace: "Sofa",
}
printNoise(cat)
cat.ArchBack()
bird := Bird{
pet: pet{nLegs: 2, color: "Rainbow"},
favoritePerch: "Back of Cage",
}
printNoise(bird)
bird.Hop()
}

Yes, you can run methods that are not part of the interface. There were two issues in the code preventing it from running properly.
The function NewDog returns the type Animal. The WagTale method is attached to Dog not Animal which gave an error. The return type has been changed to Dog.
Pointers are not needed in this code and have been removed.
After these adjustments, the code runs and properly and all methods execute as expected.
Link on Go playground: https://play.golang.org/p/LYZJiQND7WW
package main
import (
"fmt"
)
type Animal interface {
MakeNoise()
}
type Dog struct {
color string
}
/* Interface implementation */
func (d Dog) MakeNoise() {
fmt.Println("Bark!")
}
/* End Interface implementation */
func (d Dog) WagTail() {
fmt.Println(d.color + " dog: Wag wag")
}
func NewDog(color string) Dog {
return Dog{color}
}
func main() {
dog := NewDog("Brown")
dog.MakeNoise()
dog.WagTail()
}

Related

How to define external functions that return type unions in Kotlin/JS?

I'm writing external declarations for LeafletJS 1.8.0, a JavaScript library, using Kotlin 1.6.21.
The Polyline class has a function, getLatLngs() that can return any of these types:
Array<LatLng>
Array<Array<LatLng>>
Array<Array<Array<LatLng>>>
Of course the setter is easy to overload to handle a type-union
open external class Polyline {
open fun setLatLngs(latlngs: Array<LatLng>): Polyline<T>
open fun setLatLngs(latlngs: Array<Array<LatLng>>): Polyline<T>
open fun setLatLngs(latlngs: Array<Array<Array<LatLng>>>): Polyline<T>
}
However it's not possible to overload the getter
open external class Polyline {
// ERROR: Conflicting overloads
open fun getLatLngs(): Array<LatLng>
open fun getLatLngs(): Array<Array<LatLng>>
open fun getLatLngs(): Array<Array<Array<LatLng>>>
}
As a compromise I can set the return type to dynamic and add a comment so users can see the intention.
open external class Polyline {
open fun getLatLngs(): dynamic /* Array<LatLng> | Array<Array<LatLng>> | Array<Array<Array<LatLng>>> */
}
There's an open ticket KT-13108, and an update in November 2021 indicates direct Kotlin support for type unions won't be available until after Kotlin 1.7 is released.
Is there a better way of implementing the external function so the return type is type safe, or users can see the available types that might be returned, and handle each appropriately? What's the idiomatic practice?
Problem:
You are looking for an idiomatic way to describe union types for external declarations with:
Type safety (to ensure protect against runtime exceptions)
Output Type Annotations (for documentation purposes and also IDE code completion)
Control flow that handles each type in the union (so the union type can be used in Kotlin)
Long story short, for any general representation of a JS union-type in Kotlin, it's not possible to hit all three of these criteria without having more information about the instances of those types (due to type-erasure which I'll explain). But, In your case and the vast majority of cases, there is a nice trick to do this by using Kotlin's extension functions.
Solution:
There are two cases that I'll explain what to do to hit these criteria as best as possible:
Union of types that don't use generics (like Cat | Dog | string)
Union of types that do use generics (This is your case as Array<LatLng>, Array<Array<LatLng>>, and Array<Array<Array<LatLng>>> each use Generics for their types)
Union types that don't use Generics:
Say you had the Kotlin external declaration for AnimalOwner that is currently using dynamic as an output for its getPet method:
AnimalOwner.kt (draft)
/*
pretend right here that the package is declared
and file:JsModule decorators are present
*/
external class Cat
external class Dog
external class AnimalOwner {
fun setPet(pet: Cat) // sets the owner's pet to a Cat
fun setPet(pet: Dog) // sets the owner's pet to a Dog
fun setPet(pet: String) // sets the owner's pet to a String
fun getPet(): dynamic // Union of types (Cat, Dog, String)
}
One can specify an external interface to represent the output type. Then, using extension functions, one can define how to cast/morph each instance into each type (or return null if it can't):
Pet.kt
/*
pretend right here that the package is declared
However, JsModule decorators are NOT (and cannot be) present here
*/
// created an interface and gave it an arbitrary name that fits
// what the output to getPet would represent
sealed external interface Pet // we sealed Pet to disallow others from inheriting it
// Create extension functions with fitting names which cast/morph to each type
// (these are not defined externally, they are defined in Kotlin itself):
inline fun Pet.asCat(): Cat? = this as? Cat
inline fun Pet.asDog(): Dog? = this as? Dog
inline fun Pet.asString(): String? = this as? String
Now, we can replace the dynamic keyword in AnimalOwner with Pet (the interface just created):
AnimalOwner.kt (revised)
/*
pretend right here that the package is declared
and JsModule decorators are present
*/
external class Cat
external class Dog
external class AnimalOwner {
fun setPet(pet: Cat)
fun setPet(pet: Dog)
fun setPet(pet: String)
fun getPet(): Pet // <- changed from dynamic to Pet
}
We can now use AnimalOwner by calling each extension function and checking if it is null or not:
fun printPetOf(animalOwner: AnimalOwner) {
val pet = animalOwner.getPet()
pet.asCat()?.also { cat -> console.log("I have a Cat") }
pet.asDog()?.also { dog -> console.log("I have a Dog") }
pet.asString()?.also { animalStr -> console.log("I have a $animalStr") }
}
fun test() {
val johnSmith = AnimalOwner()
johnSmith.setPet(Cat()) // johnSmith has a cat
printPetOf(johnSmith) // console: "I have a Cat"
johnSmith.setPet(Dog()) // johnSmith now has a dog
printPetOf(johnSmith) // console: "I have a Dog"
johnSmith.setPet("Mouse") // johnSmith now has a Mouse
printPetOf(johnSmith) // console: "I have a Mouse"
}
Union types that do use Generics:
This case is a little more complicated due to type-erasure. Let's use a similar example to AnimalOwner where now the owner is specifying lists of Dogs, Cats, or a String of animals:
AnimalOwner.kt (draft)
/*
pretend right here that the package is declared
and JsModule decorators are present
*/
external class Cat
external class Dog
external class AnimalOwner {
fun setPets(pets: List<Cat>) // sets the owner's pets to be a list of Cats
fun setPets(pets: List<Dog>) // sets the owner's pets to be a list of Dogs
fun setPets(pets: String) // sets the owner's pets to a String
fun getPets(): dynamic // Union of types (List<Cat>, List<Dog>, String)
}
At this point, if we attempt to do the same procedure to create an output type as before, we run into a problem when creating casting/morphing functions:
Pets.kt (ERROR)
/*
pretend right here that the package is declared
However, JsModule decorators are NOT (and cannot be) present here
*/
sealed external interface Pets // we sealed Pets to disallow others from inheriting it
inline fun Pets.asCats(): List<Cat>? = this as? List<Cat> // Possible Bug
inline fun Pets.asDogs(): List<Dog>? = this as? List<Dog> // Possible Bug
inline fun Pets.asString(): String? = this as? String
Specifically, we must change the following code this as? List<Cat> and this as? List<Dog> because Generics Types like List<T> lose information on the generic parameter T at runtime. This loss of information is called type-erasure (for more information see here). We must replace this with this as? List<*> for both extension methods because we can't know generics at runtime. This now creates another problem, as of now we cannot delineate between a list of Dogs and a list of Cats. This is where we require some outside knowledge of instances of these lists and how JavaScript getPets() method treats them. This is project specific so for the sake of this example I am going to pretend I have done some research to determine this outside knowledge we speak of.
So let's say we found out that our corresponding JavaScript method for getPets() always represents the returning of an empty list as list of Cats.
Now we have enough information to correct our code to delineate List<Cats> and List<Dog> even though we only have access to List<*>:
Pets.kt (revised)
/*
pretend right here that the package is declared
However, JsModule decorators are NOT (and cannot be) present here
*/
sealed external interface Pets
inline fun Pets.asCats(): List<Cat>? {
val listOfSomething = this as? List<*>
return listOfSomething?.let {
if (it.isEmpty() || it[0] is Cat) {
#Suppress("UNCHECKED_CAST")
it as List<Cat>
} else {
null
}
}
}
inline fun Pets.asDogs(): List<Dog>? {
val listOfSomething = this as? List<*>
return listOfSomething?.let {
if (it.isNotEmpty() && it[0] is Dog) {
#Suppress("UNCHECKED_CAST")
it as List<Dog>
} else {
null
}
}
}
inline fun Pets.asString(): String? = this as? String
Now, in AnimalOwner, we can change the output type of getPets from dynamic to Pets:
AnimalOwner.kt (revised)
/*
pretend right here that the package is declared
and JsModule decorators are present
*/
external class Cat
external class Dog
external class AnimalOwner {
fun setPets(pets: List<Cat>)
fun setPets(pets: List<Dog>)
fun setPets(pets: String)
fun getPets(): Pets // <- changed from dynamic to Pets
}
We can then use AnimalOwner the same way as the non-Generic case:
fun printPetOf(animalOwner: AnimalOwner) {
val pets = animalOwner.getPets()
pets.asCats()?.also { cats -> console.log("I have Cats") }
pets.asDogs()?.also { dogs -> console.log("I have Dogs") }
pets.asString()?.also { animalsStr -> console.log("I have $animalsStr") }
}
fun test() {
val johnSmith = AnimalOwner()
johnSmith.setPets(listOf(Cat(), Cat())) // johnSmith has two cats
printPetOf(johnSmith) // console: "I have Cats"
johnSmith.setPets(listOf<Cat>()) // johnSmith has an empty room of cats (I wonder where they went)
printPetOf(johnSmith) // console: "I have Cats"
johnSmith.setPets(listOf<Dog>()) // johnSmith STILL has 0 cats (Schrodinger's cats?)
printPetOf(johnSmith) // console: "I have Cats"
johnSmith.setPets(listOf(Dog(), Dog(), Dog())) // johnSmith has 3 dogs
printPetOf(johnSmith) // console: "I have Dogs"
johnSmith.setPets("a Mouse, a Horse, and a Sheep") // johnSmith now has "a Mouse, a Horse, and a Sheep"
printPetOf(johnSmith) // console: "I have a Mouse, a Horse, and a Sheep"
}
I would approach this problem like this.
Step 1: Create an abstract external return type say LatLngResult
external interface LatLngResult
Step 2: Set this return type as the return type to your methods returning unions
open external class Polyline {
open fun getLatLngs(): LatLngResult
}
Step 3: Add extension functions to cast your return type as desired
inline fun LatLngResult.asArray1() = asDynamic<Array<LatLng>>()
inline fun LatLngResult.asArray2() = asDynamic<Array<Array<LatLng>>>()
inline fun LatLngResult.asArray3() = asDynamic<Array<Array<Array<LatLng>>>>()
Step 4: Use the function
val res: LatLngResult = polyline.getLatLngs()
// case 1
val array1 : Array<LatLng> = res.asArray1()
// case 2
val array2 : Array<Array<LatLng>> = res.asArray2()
// case 3
val array3 : Array<Array<Array<LatLng>>> = res.asArray3()
Note 1: Just like you would approache it in typescript, you still need to know when is it convinient to use array1, array2, array3
Note 2: Specifying types is still optional in kotlin, I just added them here to make this answer easily digestable

Extend calculator with complex and rational module(using dynamic binding)

I already made calculator that can compute with integers and real numbers(i made it with go).
Then I want to make it possible to calculate complex and rational numbers by adding those modules.
(it can also calculate when types are mixed)
It can be easy if I check types of operands every time(runtime) and take care of each case, but I want to solve it with dynamic binding. Guys can you tell me the idea of how to solve this problem
I think by dynamic typing, you're probably referring to how in eg C++ and Java, dynamic binding is essentially having reference to a base class that can point to a derived class (because the derived class "is a" base class).
One might say that the base class defines the interface behind which derived classes morph. If the derived classes replace methods of the base class, a reference to the base class can still access those methods in the derived class.
Base class can define some methods to provide some "base" functionality to its derived classes. If those classes don't redefine the method, the base class's method can be called.
In go, both these concepts exist, but they're quite different.
Go has an explicit interface keyword that defines method signatures but no methods. Any value implicitly satisfies that interface if it has methods of the same name with the same signature.
type LivingBeing interface {
TakeInEnergy()
ExpelWaste()
}
The interface type becomes a valid type in the code. We can pass an interface to a function, and without knowing the type satisfying that interface, can call its methods:
func DoLife(being LivingBeing) {
being.TakeInEnergy()
being.ExpelWaste()
}
This is valid code, but not complete code. Unlike with base classes in other languages, interfaces cannot define functions, only their signatures. It is purely and only an interface definition. We have to define the types that satisfy the interface separately from the interface itself.
type Organism struct{}
func (o *Organism) TakeInEnergy() {}
func (o *Organism) ExpelWaste() {}
We now have a type organism that satisfies LivingBeing. It is something like a base class, but if we wanted to build on it, we can't use subclassing because Go doesn't implement it. But Go does provide something similar called embedding types.
In this example I'll define a new organism, Animal, that draws ExpelWaste() from LivingBeing, but defines its own TakeInEnergy():
type Animal struct {
Organism // the syntax for an embedded type: type but no field name
}
func (a *Animal) TakeInEnergy() {
fmt.Printf("I am an animal")
}
What isn't obvious from that code is that because Animal's Organism is not a named field, its fields and methods are accessible directly from Animal. It's almost as if Animal "is an" organism.
However it is *not * an organism. It is a different type, and it would be more accurate to think of object embedding as syntactic sugar to automatically promote Organism's fields and methods to Animal.
Since go is statically and explicitly typed, DoLife cannot take an Organism and then be passed an Animal: it doesn't have the same type:
/* This does not work. Animal embeds organism, but *is not* an organism */
func DoLife(being *Organism) {
being.TakeInEnergy()
being.ExpelWaste()
}
func main() {
var a = &Animal{Organism{}}
DoLife(&Animal{})
}
cannot use &Animal{} (type *Animal) as type *Organism in argument to DoLife
That's why interface exists - so that both Organism and Animal (and indeed, even Plant or ChemotrophBacteria) can be passed as a LivingBeing.
Putting it all together, here's the code I've been working from:
package main
import "fmt"
type LivingBeing interface {
TakeInEnergy()
ExpelWaste()
}
type Organism struct{}
func (o *Organism) TakeInEnergy() {
}
func (o *Organism) ExpelWaste() {}
type Animal struct {
Organism
}
func DoLife(being LivingBeing) {
being.TakeInEnergy()
being.ExpelWaste()
}
func (a *Animal) TakeInEnergy() {
fmt.Printf("I am an animal")
}
func main() {
var a = &Animal{Organism{}}
DoLife(a)
}
There are a few caveats:
Syntactically, If you want to declare an embedded literal you must explicitly provide its type. In my example Organism has no fields so there's nothing to declare, but I still left the explicit type in there to point you in the right direction.
DoLife can call the right TakeInEnergy on a LivingBeing, but Organism's methods cannot. They see only the embedded Organism.
func (o *Organism) ExpelWaste() {
o.getWaste() //this will always be Organism's getWaste, never Animal's
}
func (o *Organism)getWaste() {}
func (a *Animal)getWaste() {
fmt.Println("Animal waste")
}
Simlarly if you pass only the embedded part, then it's going to call its own TakeInEnergy(), not that of Animal; there's no Animal left!
func main() {
var a = &Animal{Organism{}}
DoLife(&a.Organism)
}
In summary,
Define explict interface and use that type wherever you want "polymorphic" behavior
Define base types and embed them in other types to share base functionality.
Don't expect the "base" type to ever "bind" to functions from the "derived" type.

Go "polymorphism"

People are saying, Go is not an OO (Object Oriented) language; don't use OO terms on Go. OK, let me describe what I am able to do with OO --
With an OO language, I can make different animals say different things based on their classes:
cat.Say() // miao
sheep.Say() // bahh
cow.Say() // moo
The same is getting the Area() from Shapes.
However, this go demo code made me believe that it is impossible. Included below as Exhibit#1.
Then today, I found this go demo code, which makes it entirely possible. Included below as Exhibit#2.
So my question is, what's fundamentally different between the two, that makes the first one wrong and second one correct?
How to make the first one "works"?
Exhibit#1:
// Credits: hutch
// https://groups.google.com/d/msg/golang-nuts/N4MBApd09M8/0ij9yGHK_8EJ
////////////////////////////////////////////////////////////////////////////
/*
https://groups.google.com/d/msg/golang-nuts/N4MBApd09M8/tOO5ZXtwbhYJ
LRN:
Subtype polymorphism: Not applicable (Go doesn't have subtyping).
Although if you embed a struct A implementing interface X into a struct B,
struct B will implement interface X, and can be used instead of struct A in
places where struct A is expected. So, kind of yes.
Robert Johnstone:
interfaces behave similarly to virtual functions, but they are not identical. See the (following) example program by hutch.
*/
package main
import "fmt"
type A struct {
astring string
}
type B struct {
A
bstring string
}
type Funny interface {
strange()
str() string
}
func (this *A) strange() {
fmt.Printf("my string is %q\n", this.str())
}
func (this *A) str() string {
return this.astring
}
func (this *B) str() string {
return this.bstring
}
func main() {
b := new(B)
b.A.astring = "this is an A string"
b.bstring = "this is a B string"
b.strange()
// Output: my string is "this is an A string"
// Many people familiar with OO (and unfamiliar with Go) will be quite
// surprised at the output of that program.
}
Exhibit#2:
// Credits: https://play.golang.org/p/Zn7TjiFQik
////////////////////////////////////////////////////////////////////////////
/*
Problem (From Polymorphism-Subtype.go):
https://groups.google.com/d/msg/golang-nuts/N4MBApd09M8/tOO5ZXtwbhYJ
LRN: Subtype polymorphism: Not applicable (Go doesn't have subtyping).
Goal:
This is to demo that "polymorphism" is still doable in Go.
*/
package main
import (
"fmt"
)
type Shape interface {
Area() float32
}
type Point struct {
x float32
y float32
}
// Make sure the structs are different sizes so we're sure it'll work with
// all sorts of types
type Circle struct {
center Point
radius float32
}
func (c Circle) Area() float32 {
return 3.1415 * c.radius * c.radius
}
type Rectangle struct {
ul Point
lr Point
}
func (r Rectangle) Area() float32 {
xDiff := r.lr.x - r.ul.x
yDiff := r.ul.y - r.lr.y
return xDiff * yDiff
}
func main() {
mtDict := make(map[string]Shape)
// No problem storing different custom types in the multitype dict
mtDict["circ"] = Circle{Point{3.0, 3.0}, 2.0}
mtDict["rect"] = Rectangle{Point{2.0, 4.0}, Point{4.0, 2.0}}
for k, v := range mtDict {
fmt.Printf("[%v] [%0.2f]\n", k, v.Area())
}
}
/*
$ go run Polymorphism-Shape.go
[circ] [12.57]
[rect] [4.00]
*/
Your two exhibits are doing different things.
In the first one, B has A embedded in it, and B doesn't implement the strange() method itself, so when you call b.strange(), you get the implementation of strange() defined for A. The receiver (this) of the strange method is b.A, not b, so the value b.A.astring is printed. If you wanted strange to print bstring, you would have to define strange for B.
This points out one of the differences between Go and other OO languages: embedding A within B does not mean that B is a "subclass" of A, so an object of type B cannot be used where an object of type A is expected. However, since B inherits the fields and methods of A, any interface that's implemented by A is also implemented by B, and, unless those methods are defined specifically for B, they operate on the A within B, not B itself.
In the second exhibit, you have the Shape interface which is implemented by the types Circle and Rectangle. The element type of your map is Shape, so any type that implements that interface can be an element in the map. When working with a value of an interface type as you are doing in the loop, you can call any method defined in the interface on the value, and the definition corresponding to the actual type of the value will be called.
First of all I would like to discuss the "impossible" part.
import "fmt"
type Animal interface {
Say() string
}
type Cat struct {}
func (cat Cat) Say() string {
return "miao"
}
type Sheep struct {}
func (sheep Sheep) Say() string {
return "bahh"
}
type Cow struct {}
func (cow Cow) Say() string {
return "moo"
}
func main() {
cat := Cat{}
sheep := Sheep{}
cow := Cow{}
fmt.Println(cat.Say())
fmt.Println(sheep.Say())
fmt.Println(cow.Say())
}
This will work exactly as you would expect. So there is a polymorphism in terms of "different structs responding differently to same method".
The intention of Exhibit#1 demonstrates that what Go does is actually similar to Java castings before #Overrides.
Just add the following method to the first example and see how that will work:
func (this B) strange() {
fmt.Printf("my string is %q\n", this.str())
}

Ensuring embedded structs implement interface without introducing ambiguity

I'm trying to clean up my code base by doing a better job defining interfaces and using embedded structs to reuse functionality. In my case I have many entity types that can be linked to various objects. I want to define interfaces that capture the requirements and structs that implement the interfaces which can then be embedded into the entities.
// All entities implement this interface
type Entity interface {
Identifier()
Type()
}
// Interface for entities that can link Foos
type FooLinker interface {
LinkFoo()
}
type FooLinkerEntity struct {
Foo []*Foo
}
func (f *FooLinkerEntity) LinkFoo() {
// Issue: Need to access Identifier() and Type() here
// but FooLinkerEntity doesn't implement Entity
}
// Interface for entities that can link Bars
type BarLinker interface {
LinkBar()
}
type BarLinkerEntity struct {
Bar []*Bar
}
func (b *BarLinkerEntity) LinkBar() {
// Issues: Need to access Identifier() and Type() here
// but BarLinkerEntity doesn't implement Entity
}
So my first thought was to have FooLinkerEntity and BarLinkerEntity just implement the Entity interface.
// Implementation of Entity interface
type EntityModel struct {
Id string
Object string
}
func (e *EntityModel) Identifier() { return e.Id }
func (e *EntityModel) Type() { return e.Type }
type FooLinkerEntity struct {
EntityModel
Foo []*Foo
}
type BarLinkerEntity struct {
EntityModel
Bar []*Bar
}
However, this ends up with an ambiguity error for any types that can link both Foos and Bars.
// Baz.Identifier() is ambiguous between EntityModel, FooLinkerEntity,
// and BarLinkerEntity.
type Baz struct {
EntityModel
FooLinkerEntity
BarLinkerEntity
}
What's the correct Go way to structure this type of code? Do I just do a type assertion in LinkFoo() and LinkBar() to get to Identifier() and Type()? Is there any way to get this check at compile time instead of runtime?
Go is not (quite) an object oriented language: it does not have classes and it does not have type inheritance; but it supports a similar construct called embedding both on struct level and on interface level, and it does have methods.
So you should stop thinking in OOP and start thinking in composition. Since you said in your comments that FooLinkerEntity will never be used on its own, that helps us achieve what you want in a clean way.
I will use new names and less functionality to concentrate on the problem and solution, which results in shorter code and which is also easier to understand.
The full code can be viewed and tested on the Go Playground.
Entity
The simple Entity and its implementation will look like this:
type Entity interface {
Id() int
}
type EntityImpl struct{ id int }
func (e *EntityImpl) Id() int { return e.id }
Foo and Bar
In your example FooLinkerEntity and BarLinkerEntity are just decorators, so they don't need to embed (extend in OOP) Entity, and their implementations don't need to embed EntityImpl. However, since we want to use the Entity.Id() method, we need an Entity value, which may or may not be EntityImpl, but let's not restrict their implementation. Also we may choose to embed it or make it a "regular" struct field, it doesn't matter (both works):
type Foo interface {
SayFoo()
}
type FooImpl struct {
Entity
}
func (f *FooImpl) SayFoo() { fmt.Println("Foo", f.Id()) }
type Bar interface {
SayBar()
}
type BarImpl struct {
Entity
}
func (b *BarImpl) SayBar() { fmt.Println("Bar", b.Id()) }
Using Foo and Bar:
f := FooImpl{&EntityImpl{1}}
f.SayFoo()
b := BarImpl{&EntityImpl{2}}
b.SayBar()
Output:
Foo 1
Bar 2
FooBarEntity
Now let's see a "real" entity which is an Entity (implements Entity) and has both the features provided by Foo and Bar:
type FooBarEntity interface {
Entity
Foo
Bar
SayFooBar()
}
type FooBarEntityImpl struct {
*EntityImpl
FooImpl
BarImpl
}
func (x *FooBarEntityImpl) SayFooBar() {
fmt.Println("FooBar", x.Id(), x.FooImpl.Id(), x.BarImpl.Id())
}
Using FooBarEntity:
e := &EntityImpl{3}
x := FooBarEntityImpl{e, FooImpl{e}, BarImpl{e}}
x.SayFoo()
x.SayBar()
x.SayFooBar()
Output:
Foo 3
Bar 3
FooBar 3 3 3
FooBarEntity round #2
If the FooBarEntityImpl does not need to know (does not use) the internals of the Entity, Foo and Bar implementations (EntityImpl, FooImpl and BarImpl in our cases), we may choose to embed only the interfaces and not the implementations (but in this case we can't call x.FooImpl.Id() because Foo does not implement Entity - that is an implementation detail which was our initial statement that we don't need / use it):
type FooBarEntityImpl struct {
Entity
Foo
Bar
}
func (x *FooBarEntityImpl) SayFooBar() { fmt.Println("FooBar", x.Id()) }
Its usage is the same:
e := &EntityImpl{3}
x := FooBarEntityImpl{e, &FooImpl{e}, &BarImpl{e}}
x.SayFoo()
x.SayBar()
x.SayFooBar()
Its output:
Foo 3
Bar 3
FooBar 3
Try this variant on the Go Playground.
FooBarEntity creation
Note that when creating FooBarEntityImpl, a value of Entity is to be used in multiple composite literals. Since we created only one Entity (EntityImpl) and we used this in all places, there is only one id used in different implementation classes, only a "reference" is passed to each structs, not a duplicate / copy. This is also the intended / required usage.
Since FooBarEntityImpl creation is non-trivial and error-prone, it is recommended to create a constructor-like function:
func NewFooBarEntity(id int) FooBarEntity {
e := &EntityImpl{id}
return &FooBarEntityImpl{e, &FooImpl{e}, &BarImpl{e}}
}
Note that the factory function NewFooBarEntity() returns a value of interface type and not the implementation type (good practice to be followed).
It is also a good practice to make the implementation types un-exported, and only export the interfaces, so implementation names would be entityImpl, fooImpl, barImpl, fooBarEntityImpl.
Some related questions worth checking out
What is the idiomatic way in Go to create a complex hierarchy of structs?
is it possible to call overridden method from parent struct in golang?
Can embedded struct method have knowledge of parent/child?
Go embedded struct call child method instead parent method
Seems to me having three ID in one structure with methods relying on them is even semantically incorrect. To not be ambiguous you should write some more code to my mind. For example something like this
type Baz struct {
EntityModel
Foo []*Foo
Bar []*Bar
}
func (b Baz) LinkFoo() {
(&FooLinkerEntity{b.EntityModel, b.Foo}).LinkFoo()
}
func (b Baz) LinkBar() {
(&BarLinkerEntity{b.EntityModel, b.Bar}).LinkBar()
}

How can I mock multiple types when the signature of a concrete method refers to another concrete type, not its interface?

I'm making use of a third party library that doesn't have any interfaces for its classes. I can use them in my structs no problem, but they have side effects that I want to avoid when unit testing.
// Somewhere there are a couple structs, with no interfaces. I don't own the code.
// Each has only one method.
type ThirdPartyEntry struct {}
func (e ThirdPartyEntry) Resolve() string {
// Do some complex stuff with side effects
return "I'm me!"
}
// This struct returns an instance of the other one.
type ThirdPartyFetcher struct {}
func (f ThirdPartyFetcher) FetchEntry() ThirdPartyEntry {
// Do some complex stuff with side effects and return an entry
return ThirdPartyEntry{}
}
// Now my code.
type AwesomeThing interface {
BeAwesome() string
}
// I have a class that makes use of the third party.
type Awesome struct {
F ThirdPartyFetcher
}
func (a Awesome) BeAwesome() string {
return strings.Repeat(a.F.FetchEntry().Resolve(), 3)
}
func NewAwesome(fetcher ThirdPartyFetcher) Awesome {
return Awesome{
F: fetcher,
}
}
func main() {
myAwesome := NewAwesome(ThirdPartyFetcher{})
log.Println(myAwesome.BeAwesome())
}
This works! But I want to write some unit tests, and so I'd like to Mock both the third party structs. To do so I believe I need interfaces for them, but since ThirdPartyFetcher returns ThirdPartyEntrys, I cannot figure out how.
I created a pair of interfaces which match up with the two third party classes. I'd like to then rewrite the Awesome struct and method to use the generic Fetcher interface. In my test, I would call NewAwesome() passing in a testFetcher, a struct which also implements the interface.
type Awesome struct {
F Fetcher
}
func NewAwesome(fetcher Fetcher) Awesome {
return Awesome{
Fetcher: fetcher,
}
}
type Entry interface {
Resolve() string
}
// Double check ThirdPartyEntry implements Entry
var _ Entry = (*ThirdPartyEntry)(nil)
type Fetcher interface {
FetchEntry() Entry
}
// Double check ThirdPartyFetcher implements Fetcher
var _ Fetcher = (*ThirdPartyFetcher)(nil)
I omit the test code because it's not relevant. This fails on the last line shown.
./main.go:49: cannot use (*ThirdPartyFetcher)(nil) (type *ThirdPartyFetcher) as type Fetcher in assignment:
*ThirdPartyFetcher does not implement Fetcher (wrong type for FetchEntry method)
have FetchEntry() ThirdPartyEntry
want FetchEntry() Entry
The signatures are different, even though I already showed that ThirdPartyEntry implements Entry. I believe this is disallowed because to would lead to something like slicing (in the polymorphic sense, not the golang sense). Is there any way for me to write a pair of interfaces? It should be the case that the Awesome class doesn't even know ThirdParty exists - it's abstracted behind the interface and injected when main calls NewAwesome.
It's not very pretty, but one way would be to:
type fetcherWrapper struct {
ThirdPartyFetcher
}
func (fw fetcherWrapper) FetchEntry() Entry {
return fw.ThirdPartyFetcher.FetchEntry()
}
I'd say mocking things that return structs vs interfaces is a relatively common problem without any great solutions apart from a lot of intermediate wrapping.