From the example below, is there anyway that Child object can call Parent's method? For instance, I want Child (boy1 and girl1) to call parent's "Remember" method; so parents can remember what Child want them to remember.
Thank you so much
package main
import "fmt"
type child struct {
Name string
}
func (p *child) Yell() {
fmt.Println("Child's yelling")
}
type parent struct {
Name string
Children []child
Memory []string
}
func (p *parent) Yell() {
fmt.Println("Parent's yelling")
}
func (p *parent) Remember(line string) {
p.Memory = append(p.Memory, line)
}
func main() {
p := parent{}
p.Name = "Jon"
boy1 := child{}
boy1.Name = "Jon's boy"
girl1 := child{}
girl1.Name = "Jon's girl"
p.Children = append(p.Children, boy1)
p.Children = append(p.Children, girl1)
fmt.Println(p)
p.Yell()
for i:=0;i<len(p.Children);i++ {
p.Children[i].Yell()
}
}
Thanks to #Jim, here's the solution. The pointer is always confusing.
package main
import "fmt"
type child struct {
Name string
prnt *parent
}
func (p *child) Yell() {
fmt.Println("Child's yelling")
}
type parent struct {
Name string
Children []child
Memory []string
}
func (p *parent) Yell() {
fmt.Println("Parent's yelling")
}
func (p *parent) Remember(line string) {
p.Memory = append(p.Memory, line)
}
func main() {
p := parent{}
p.Name = "Jon"
boy1 := child{}
boy1.Name = "Jon's boy"
boy1.prnt = &p
girl1 := child{}
girl1.Name = "Jon's girl"
girl1.prnt = &p
p.Children = append(p.Children, boy1)
p.Children = append(p.Children, girl1)
fmt.Println(p)
p.Yell()
for i := 0; i < len(p.Children); i++ {
p.Children[i].Yell()
p.Children[i].prnt.Remember("test:" + p.Children[i].Name)
}
fmt.Println(p.Memory)
}
You can add a pointer to the parent in the child struct
type child struct {
Name string
parent *parent
}
func (p *child) Yell() {
fmt.Println("Child's yelling")
p.parent.Remember(p.Name + " called")
p.parent.Yell()
}
I am just a starter of Golang.
Seems Golang convention is CamelCase for class name, and when inherit a base class ("Parent") shouldn't assign a variable name. p.Parent will automatically work, i.e. as follows:
type Child struct {
*Parent // put at top
Name string
}
func (p *Child) Yell() {
fmt.Println("Child's yelling")
p.Parent.Remember(p.Name + " called")
p.Parent.Yell()
}
Reference:
http://arch-stable.blogspot.hk/2012/05/golang-call-inherited-constructor.html
https://medium.com/#simplyianm/why-gos-structs-are-superior-to-class-based-inheritance-b661ba897c67
Some other example inherit with non-pointer Parent like:
type Child struct {
Parent // put at top
Name string
}
Not sure which one is more official and handy yet
Related
I'm coming from a Java background, so I'm pretty lost by Go's approach to OOP. I'm trying to write a logging function that, fundamentally, can accept an array of either one type or another. To clarify: the arrays will not mix type, they will be an array of all either Type1 or Type 2.
I created an interface for both these types to implement, but my IDE said it can't use the type as the interface. What's the better, more Go-like approach here?
type Loggable interface {
GetFirstName() string
GetLastName() string
}
type Person1 struct {
FirstName string
LastName string
}
func (t Person1) GetFirstName() string {
return t.FirstName
}
func (t Person1) GetLastName() string {
return t.LastName
}
type Person2 struct {
FirstName2 string
LastName2 string
}
func (t Person2) GetFirstName() string {
return t.FirstName2
}
func (t Person2) GetLastName() string {
return t.LastName2
}
func performLogging(logger LoggingPackage.Logger, loggingList []Loggable){
for _, person := range loggingList {
logger.Logf("Person is %s %s", person.GetFirstName(), person.GetLastName())
}
}
func relevantFunction() {
personList := handler.PersonRequest() // returns an array of all either Person1, or all Person2
performLogging(logger, personList) // can't use []Person1 or []Person2 as []Loggable
}```
I find it helps in these cases to rip out all code that is not central to the
problem. This example works as expected:
package main
import "fmt"
type Loggable interface {
GetFirstName() string
}
type Person1 struct { FirstName string }
func (t Person1) GetFirstName() string { return t.FirstName }
type Person2 struct { FirstName2 string }
func (t Person2) GetFirstName() string { return t.FirstName2 }
func performLogging(loggingList []Loggable){
for _, person := range loggingList {
fmt.Println(person.GetFirstName())
}
}
func main() {
people := []Loggable{
Person1{"Angela"}, Person2{"Tyrell"},
}
performLogging(people)
}
Hi I'm trying to build a node hierarchy based on the directory structure:
/first/
/first/second
/first/third
/first/third/forth
/first/third/fifth
/first/sixth
/first/sixth/seventh
/first/eighth
/first/ninth
I'm trying to get a node hierarchy similar to this:
first
second
third
forth
fifth
sixth
seventh
eighth
ninth
I'm using Kotlin for this, I'm still relatively new to Java and Kotlin so bear with me.
Note: I'm using FileTreeWalk to get the directories
fun getDirs(directoryName: String): MutableList<String> {
val ret = mutableListOf<String>()
File(directoryName).walk().forEach {
if (it.isDirectory) { ret.add(it.toString()) }
}
return ret
}
Right now all I have is this (Generates a flat hierarchy):
private fun nodesFromPathList(dirPaths: MutableList<String>) : Tree.Node {
val ret = Tree.Node("root")
for (dir in dirPaths) {
ret.add(Tree.Node(dir))
}
return ret
}
Any ideas?
I decided to put all the nodes into a map and connect the nodes together.
/**
* Creates a node hierarchy from list of paths
*/
private fun nodesFromPathList(dirPaths: MutableList<String>) : Tree.Node? {
var ret : Tree.Node? = null
val nodeMap = mutableMapOf<String, Tree.Node>()
// Add a node for each directory path and put it into a map
for (dir in dirPaths) {
val newNode = Tree.Node(nodeName(dir), skin)
if (ret == null)
ret = newNode
nodeMap.put(dir, newNode)
}
// Go through each one and add the child
nodeMap.forEach {
val parent = parentPath(it.key)
try {
nodeMap[parent]!!.add(it.value)
} catch (e: NullPointerException) {
println("Parent not found")
}
}
return ret
}
/**
* Returns current path
* "D:\dir\to\apath" ==> "apath"
*/
fun nodeName(path: String): String {
return path.split("\\").last()
}
/**
* Returns the parent path
* D:\dir\to\apath ==> D:\dir\to
*/
fun parentPath(path: String): String {
val split = path.trim('\\').split("\\")
var ret = ""
for (i in 0..split.size-2) {
ret += split[i] + "\\"
}
return ret.trim('\\')
}
I put the path into the key, and the tree node into the value. Iterated through the map and connected the children based on the parent. Example Map.:
[D:\android\assets=Tree$Node#56eb1af5,
D:\android\assets\Assets\abc=Tree$Node#48e3456d,
D:\android\assets\Assets\abc\bcd=Tree$Node#3e532818,
D:\android\assets\Assets\abc\cde=Tree$Node#16b07083]
I would find the parent from the key (by splitting the string), then set the parent.
I am learning go lang and i was wondering if there is a way to do something like this:
type Foo struct {
...
}
type Bar struct {
Foo
...
}
func getFoo() Foo {
return Bar{...}
}
In an object oriented language, such code should work without problems, but in go it throws me an error, saying that getFoo() must return an instance of class Foo.
Is there a way to do polymorphism similar to what i've described in Go?
Go is not a typical OO language. Also each language has it own way of doing things. You can use interface and composition to achieve what you desire to, as shown below:
package main
import "fmt"
type Foo interface {
printFoo()
}
type FooImpl struct {
}
type Bar struct {
FooImpl
}
type Bar2 struct {
FooImpl
}
func (f FooImpl)printFoo(){
fmt.Println("Print Foo Impl")
}
func getFoo() Foo {
return Bar{}
}
func main() {
fmt.Println("Hello, playground")
b := getFoo()
b.printFoo()
}
http://play.golang.org/p/iR8QkD3DnP
In Go, polymorphism is achieved by implementing interfaces.
type Being interface {
somemethod()
}
type Foo struct {}
type Bar struct {
Foo
}
type Baz struct {
Foo
}
// `Bar` and `Baz` implement `Being`
func (b *Bar) somemethod() {}
func (b *Baz) somemethod() {}
func getAnyFoo(b *Being) Foo {
return b.Foo
}
Therefore, anything implements an empty interface.
type Foo struct {}
type Bar struct {
Foo
}
// Get anything and extract its `Foo` if anything is a Bar
func getAnyFoo(i interface{}) Foo {
// Normally this would need a type switch to check the type
mybar := i.(Bar)
return mybar.Foo
}
If you know the types to use you could put them to an array list to implement a kind of polymorph instancing:
package main
import (
"fmt"
"encoding/json"
)
type Hans struct{
Miau string
}
type Keule struct {
Wuff string
}
func (K Keule)ppp() {
fmt.Printf(K.Wuff)
}
func (K Hans)ppp() {
fmt.Printf(K.Miau)
}
func (K Keule)TypeInfo() int {
return 0
}
func (K Hans)TypeInfo() int {
return 1
}
type Mega interface {
ppp()
TypeInfo() int
}
var j_a = `{
"Kein_Alter": "nix",
"Miau": "lala",
"class": 0
}`
var j_b = `{
"Alter": "nix",
"Wuff": "lolo",
"Class": 1
}`
type Class struct {
Class int
}
func (K *Class)ppp() {
fmt.Printf("%d", K.Class)
}
func Unmarshal_K(b []byte) (Mega, error) {
var k Keule
err := json.Unmarshal([]byte(j_a), &k)
return k, err
}
func Unmarshal_H(b []byte) (Mega, error) {
var k Hans
err := json.Unmarshal([]byte(j_a), &k)
return k, err
}
var UList = []func(b []byte) (Mega, error) {Unmarshal_H, Unmarshal_K}
func main() {
var mv Class
err := json.Unmarshal([]byte(j_a), &mv)
if err != nil {
panic(err)
}
hiho, err := UList[mv.Class]([]byte(j_a))
if err != nil {
panic(err)
}
hiho.ppp()
}
You can use it in the following way. If you give the print function one of the person or secret Agent, it will understand that it came directly from the human interface and run the function inside it.
package main
import "fmt"
type person struct {
firstName string
lastName string
age int
}
type secretAgent struct {
person
ltk bool
}
type human interface {
info() string
}
func (p person) info() string {
return fmt.Sprint("Name:", p.firstName, " Surname:", p.lastName, " Age:", p.age)
}
func (s secretAgent) info() string {
return fmt.Sprint("Name:", s.firstName, " Surname:", s.lastName, " Age:", s.age, " Ltk:", s.ltk)
}
func print(h human) {
switch h.(type) {
case person:
fmt.Println("person struct:")
fmt.Println(h.info())
case secretAgent:
fmt.Println("secretAgent struct:")
fmt.Println(h.info())
}
}
func main() {
p := person{
firstName: "Khanbala",
lastName: "Reshidov",
age: 22,
}
s := secretAgent{
person: p,
ltk: true,
}
//info Method
fmt.Println(p.info())
fmt.Println(s.info())
//polymorphism
print(p)
print(s)
//type
fmt.Printf("%T\n", p)
fmt.Printf("%T\n", s)
}
I'm looking for the equivalent of the following Obj-C code in Swift:
- newInstanceOf:(id)classRef {
return [classRef new];
}
and then to use it:
id instance = [whatever newInstanceOf:NSArray.class]
[instance isKindOfClass:NSArray.class] == YES
I have tried using a Swift template:
func newSomething<T>(classRef:T.Type) -> T {
return classRef()
}
I get the error: error: 'T' cannot be constructed because it has no accessible initializers
You could create a protocol to act as a type constraint for objects initializable by a void-argument initializer, and thereafter extend your types of choice to this protocol.
protocol SimplyInitializable {
init()
}
extension Int : SimplyInitializable { }
extension Double : SimplyInitializable { }
extension String : SimplyInitializable { }
struct MyStruct {
var myInt : Int
init() {
myInt = 0
}
}
extension MyStruct : SimplyInitializable { }
func newSomething<T: SimplyInitializable>(classRef: T.Type) -> T {
return classRef.init()
}
/* Examples */
var a = newSomething(Int)
var b = newSomething(Double)
var c = newSomething("".dynamicType)
var d = newSomething(MyStruct)
var e = newSomething(a.dynamicType)
print(a.dynamicType) // Int
print(b.dynamicType) // Double
print(c.dynamicType) // String
print(d.dynamicType) // MyStruct
print(e.dynamicType) // Int
Actually in Swift, not all classes are guaranteed to have an init() initializer. It can work with NSObject classes though because NSObject does have that requirement.
func newInstanceOf<T:NSObject>(aClass:T.Type) -> NSObject
{ return aClass.init() }
let string = newInstanceOf(NSString) // ""
let date = newInstanceOf(NSDate) // 2016-01-15 05:27:29 +0000
How to implement an abstract class in Go? As Go doesn't allow us to have fields in interfaces, that would be a stateless object. So, in other words, is it possible to have some kind of default implementation for a method in Go?
Consider an example:
type Daemon interface {
start(time.Duration)
doWork()
}
func (daemon *Daemon) start(duration time.Duration) {
ticker := time.NewTicker(duration)
// this will call daemon.doWork() periodically
go func() {
for {
<- ticker.C
daemon.doWork()
}
}()
}
type ConcreteDaemonA struct { foo int }
type ConcreteDaemonB struct { bar int }
func (daemon *ConcreteDaemonA) doWork() {
daemon.foo++
fmt.Println("A: ", daemon.foo)
}
func (daemon *ConcreteDaemonB) doWork() {
daemon.bar--
fmt.Println("B: ", daemon.bar)
}
func main() {
dA := new(ConcreteDaemonA)
dB := new(ConcreteDaemonB)
start(dA, 1 * time.Second)
start(dB, 5 * time.Second)
time.Sleep(100 * time.Second)
}
This won't compile as it's not possible to use interface as a receiver.
In fact, I have already answered my question (see the answer below). However, is it an idiomatic way to implement such logic? Are there any reasons not to have a default implementation besides language's simplicity?
The other answers provide an alternative to your problem, however they proposed solution without using abstract classes/struct, and I guess if you were interested in using abstract class like solution, here is very precise solution to your problem:
Go plaground
package main
import (
"fmt"
"time"
)
type Daemon interface {
start(time.Duration)
doWork()
}
type AbstractDaemon struct {
Daemon
}
func (a *AbstractDaemon) start(duration time.Duration) {
ticker := time.NewTicker(duration)
// this will call daemon.doWork() periodically
go func() {
for {
<- ticker.C
a.doWork()
}
}()
}
type ConcreteDaemonA struct {
*AbstractDaemon
foo int
}
func newConcreteDaemonA() *ConcreteDaemonA {
a:=&AbstractDaemon{}
r:=&ConcreteDaemonA{a, 0}
a.Daemon = r
return r
}
type ConcreteDaemonB struct {
*AbstractDaemon
bar int
}
func newConcreteDaemonB() *ConcreteDaemonB {
a:=&AbstractDaemon{}
r:=&ConcreteDaemonB{a, 0}
a.Daemon = r
return r
}
func (a *ConcreteDaemonA) doWork() {
a.foo++
fmt.Println("A: ", a.foo)
}
func (b *ConcreteDaemonB) doWork() {
b.bar--
fmt.Println("B: ", b.bar)
}
func main() {
var dA Daemon = newConcreteDaemonA()
var dB Daemon = newConcreteDaemonB()
dA.start(1 * time.Second)
dB.start(5 * time.Second)
time.Sleep(100 * time.Second)
}
If this is still not obvious how to use abstract classes/multi-inheritance in go-lang here is the post with comprehensive details. Abstract Classes In Go
If you want to provide a "default" implementation (for Daemon.start()), that is not the characteristic of an interface (at least not in Go). That is a characteristic of a concrete (non-interface) type.
So Daemon in your case should be a concrete type, conveniently a struct since you want it to have fields. And the task to be done can be either a value of an interface type, or in a simple case just a function value (a simple case means it would only have one method).
With interface type
Try the complete app on the Go Playground.
type Task interface {
doWork()
}
type Daemon struct {
task Task
}
func (d *Daemon) start(t time.Duration) {
ticker := time.NewTicker(t)
// this will call task.doWork() periodically
go func() {
for {
<-ticker.C
d.task.doWork()
}
}()
}
type MyTask struct{}
func (m MyTask) doWork() {
fmt.Println("Doing my work")
}
func main() {
d := Daemon{task: MyTask{}}
d.start(time.Millisecond*300)
time.Sleep(time.Second * 2)
}
With a function value
In this simple case this one is shorter. Try it on the Go Playground.
type Daemon struct {
task func()
}
func (d *Daemon) start(t time.Duration) {
ticker := time.NewTicker(t)
// this will call task() periodically
go func() {
for {
<-ticker.C
d.task()
}
}()
}
func main() {
d := Daemon{task: func() {
fmt.Println("Doing my work")
}}
d.start(time.Millisecond * 300)
time.Sleep(time.Second * 2)
}
An easy solution is to move daemon *Daemon to the argument list (thus removing start(...) from the interface):
type Daemon interface {
// start(time.Duration)
doWork()
}
func start(daemon Daemon, duration time.Duration) { ... }
func main() {
...
start(dA, 1 * time.Second)
start(dB, 5 * time.Second)
...
}
You can implement abstract class in go.
The definition:
type abstractObject interface{
print()
}
type object struct{
a int
abstractObject
}
Now object is an abstract class, like java's.
You can inherit it and use its members:
type concreteObject struct{
*object
}
(o *concreteObject) print() {
fmt.Println(o.a)
}
func newConcreteObject(o *object) {
obj := &concreteObject{object: o}
o.abstractObject = obj // all magics are in this statement.
}
And use the object with concreteObject's methods:
o := &object{}
newConcereteObject(o)
o.print()
And cast abstract object to concrete object:
concObj := o.abstractObject.(*concreteObject)
Just like other OOP languages.
The solution by Max Malysh would work in some cases if you don't need a factory. However the solution given by Adrian Witas could cause cyclic dependencies issues.
This is the way I achieved implementing an abstract class the easy way respecting cyclic dependencies and good factory patterns.
Let us assume we have the following package structure for our component
component
base
types.go
abstract.go
impl1
impl.go
impl2
impl.go
types.go
factory.go
Define the definition of the component, in this example it will be defined here:
component/types.go
package component
type IComponent interface{
B() int
A() int
Sum() int
Average() int
}
Now let's assume we want to create an abstract class that implements Sum and Average only, but in this abstract implementation we would like to have access to use the values returned by the implemented A and B
To achieve this, we should define another interface for the abstract members of the abstract implementation
component/base/types.go
package base
type IAbstractComponentMembers {
A() int
B() int
}
And then we can proceed to implement the abstract "class"
component/base/abstract.go
package base
type AbstractComponent struct {
IAbstractComponentsMember
}
func (a *AbstractComponent) Sum() int {
return a.A() + a.B()
}
func (a *AbstractComponent) Average() int {
return a.Sum() / 2
}
And now we proceed to the implementations
component/impl1/impl.go // Asume something similar for impl2
package impl1
type ComponentImpl1 struct {
base.AbstractComponent
}
func (c *ComponentImpl1) A() int {
return 2
}
func (c *ComponentImpl1) A() int {
return 4
}
// Here is how we would build this component
func New() *ComponentImpl1 {
impl1 := &ComponentImpl1{}
abs:=&base.AbstractComponent{
IAbstractComponentsMember: impl1,
}
impl1.AbstractComponent = abs
return impl1
}
The reason we use a separate interface for this instead of using Adrian Witas example, is because if we use the same interface in this case, if we import the base package in impl* to use the abstract "class" and also we import the impl* packages in the components package, so the factory can register them, we'll find a circular reference.
So we could have a factory implementation like this
component/factory.go
package component
// Default component implementation to use
const defaultName = "impl1"
var instance *Factory
type Factory struct {
// Map of constructors for the components
ctors map[string]func() IComponent
}
func (f *factory) New() IComponent {
ret, _ := f.Create(defaultName)
return ret
}
func (f *factory) Create(name string) (IComponent, error) {
ctor, ok := f.ctors[name]
if !ok {
return nil, errors.New("component not found")
}
return ctor(), nil
}
func (f *factory) Register(name string, constructor func() IComponent) {
f.ctors[name] = constructor
}
func Factory() *Factory {
if instance == nil {
instance = &factory{ctors: map[string]func() IComponent{}}
}
return instance
}
// Here we register the implementations in the factory
func init() {
Factory().Register("impl1", func() IComponent { return impl1.New() })
Factory().Register("impl2", func() IComponent { return impl2.New() })
}
The functionality of abstract class has below requirements
1. It should not be possible to create direct instance of abstract class
2. It should provide default fields and methods.
A combination of interface and struct can be used to fulfill above two requirements. For example we can see below
package main
import "fmt"
//Abstract Interface
type iAlpha interface {
work()
common(iAlpha)
}
//Abstract Concrete Type
type alpha struct {
name string
}
func (a *alpha) common(i iAlpha) {
fmt.Println("common called")
i.work()
}
//Implementing Type
type beta struct {
alpha
}
func (b *beta) work() {
fmt.Println("work called")
fmt.Printf("Name is %s\n", b.name)
}
func main() {
a := alpha{name: "test"}
b := &beta{alpha: a}
b.common(b)
}
Output:
common called
work called
Name is test
One important point to mention here is that all default method should have iAlpha as first argument, and if default method needs to call any unimplemented method they they will call on this interface. This is same as we did in common method above - i.work().
Source: https://golangbyexample.com/go-abstract-class/