mercredi 6 janvier 2016

Idiomatic Go equivalent to subclasses

I have a lot more experience in C++ than Go. I'm trying to understand how the Composite design pattern is expressed idiomatically Go, in particular with reference to attributes. In C++, I'd use a parent class to hold attributes and methods that are common to a set of subclasses. I'm not seeing how this works in Go. An interface lets me define which methods to implement, but it doesn't let me provide a default implementation. I have to reimplement the method in every struct that implements the interface, and replicate all of the attributes in each struct. I can't keep common attributes in an interface, because interfaces don't have data elements. How do you do this sort of refactoring in Go?

Here's an example (in C++) of what I'd like to be able to do in Go:

#include <string>

/*
 * Parent class for edible things. Holds the "name" attribute.
 */

class Edible {
public:
        Edible(const std::string &aName):
                ed_Name(aName) { }
        const std::string &name() const { return ed_Name; }

protected:
        void setName(const std::string &aName) { ed_Name = aName; }

private:
        std::string ed_Name;
};

/*
 * Subclass of Edible for fruits. Depends on Edible to store the name.
 */

class Fruit: public Edible {
public:
        Fruit(const std::string &aName,
              const std::string &aPlant):
                Edible(aName),
                fr_Plant(aPlant) { }
        const std::string &plant() const { return fr_Plant; }

protected:
        void setPlant(const std::string &aPlant) { fr_Plant = aPlant; }

private:
        std::string fr_Plant;
};

/*
 * Subclass of Edible for meats. Depends on Edible to store the name.
 * Has attributes for the animal and the cut of meat.
 */

class Meat: public Edible {
public:
        Meat(const std::string &aName,
             const std::string &aAnimal,
             const std::string &aCut):
                Edible(aName),
                me_Animal(aAnimal),
                me_Cut(aCut) { }
        const std::string &animal() const { return me_Animal; }
        const std::string &cut() const { return me_Cut; }
protected:
        void setAnimal(const std::string &aAnimal) { me_Animal = aAnimal; }
        void setCut(const std::string &aCut) { me_Cut = aCut; }
private:
        std::string me_Animal;
        std::string me_Cut;
};

Aucun commentaire:

Enregistrer un commentaire