An object is polymorphic when its specific type may vary.
The types a specific value may take, is called class.

It is trivial to copy an object if its type is known:

int x;
int y = x;
Here x is not polymorphic, so y is declared of same type (int) as x.
But if the specific type of x were unknown, then y could not be declared of any specific type.

The task: let a polymorphic object contain an instance of some specific type S derived from a type T.
The type T is known.
The type S is possibly unknown until run time.
The objective is to create an exact copy of such polymorphic object (not to create a reference, nor a pointer to).
Let further the type T have a method overridden by S.
This method is to be called on the copy to demonstrate that the specific type of the copy is indeed S.

package main
 
import (
    "fmt"
    "reflect"
)
 
// interface types provide polymorphism, but not inheritance.
type i interface {
    identify() string
}
 
// "base" type
type t float64
 
// "derived" type.  in Go terminology, it is simply a struct with an
// anonymous field.  fields and methods of anonymous fields however,
// can be accessed without additional qualification and so are
// "inherited" in a sense.
type s struct {
    t
    kōan string
}
 
// another type with an "embedded" t field.  (t is the *type*, this field
// has no *name*.)
type r struct {
    t
    ch chan int
}
 
// a method on t.  this method makes t satisfy interface i.
// since a t is embedded in types s and r, they automatically "inherit"
// the method.
func (x t) identify() string {
    return "I'm a t!"
}
 
// the same method on s.  although s already satisfied i, calls to identify
// will now find this method rather than the one defined on t.  
// in a sense it "overrides" the method of the "base class."
func (x s) identify() string {
    return "I'm an s!"
}
 
func main() {
    // three variables with different types, initialized from literals.
    var t1 t = 5
    var s1 s = s{6, "one"}
    var r1 r = r{t: 7}
 
    // variables declared with the same type.  initial value is nil.
    var i1, i2, i3 i
    fmt.Println("Initial (zero) values of interface variables:")
    fmt.Println("i1:", i1)
    fmt.Println("i2:", i2)
    fmt.Println("i3:", i3)
 
    // in the terminology of the Go language reference, i1, i2, and i3
    // still have static type i, but now have different dynamic types.
    i1, i2, i3 = t1, s1, r1
    fmt.Println("\nPolymorphic:")
    fmt.Println("i1:", i1, "/", i1.identify(), "/", reflect.TypeOf(i1))
    fmt.Println("i2:", i2, "/", i2.identify(), "/", reflect.TypeOf(i2))
    fmt.Println("i3:", i3, "/", i3.identify(), "/", reflect.TypeOf(i3))
 
    // copy: declare and assign in one step using "short declaration."
    i1c, i2c, i3c := i1, i2, i3
 
    // modify first set of polymorphic variables.
    i1, i2, i3 = s{3, "dog"}, r{t: 1}, t(2)
 
    // demonstrate that copies are distinct from first set
    // and that types are preserved.
    fmt.Println("\nFirst set now modified:")
    fmt.Println("i1:", i1, "/", i1.identify(), "/", reflect.TypeOf(i1))
    fmt.Println("i2:", i2, "/", i2.identify(), "/", reflect.TypeOf(i2))
    fmt.Println("i3:", i3, "/", i3.identify(), "/", reflect.TypeOf(i3))
 
    fmt.Println("\nCopies made before modifications:")
    fmt.Println("i1c:", i1c, "/", i1c.identify(), "/", reflect.TypeOf(i1c))
    fmt.Println("i2c:", i2c, "/", i2c.identify(), "/", reflect.TypeOf(i2c))
    fmt.Println("i3c:", i3c, "/", i3c.identify(), "/", reflect.TypeOf(i3c))
}