Встраивание вместо наследования в Движении

Люди часто стопки вида документов с помощью рекурсивного метода. Например, предположите сортировку 100 документов с именами на них. Документы первого места в груды первой буквой, затем вид каждая груда.

Ищущие слова в словаре часто выполняются подобной двоичному поиску техникой, которая является рекурсивной.

В организациях, боссы часто дают команды начальникам отделов, которые в свою очередь дают команды менеджерам и так далее.

52
задан 2 revs 12 November 2009 в 19:27
поделиться

4 ответа

В комментарии вы задались вопросом, достаточно ли идеи встраивания для «полной замены наследования». Я бы сказал, что ответ на этот вопрос - «да». Несколько лет назад я очень кратко поигрался с OO-системой Tcl под названием Snit , которая использовала композицию и делегирование для исключения наследования. Snit по-прежнему сильно отличается от подхода Go, но в одном отношении у них есть общие философские основания. Это механизм для объединения частей функциональности и ответственности, а не иерархия классов.

Как утверждали другие, на самом деле речь идет о том, какие практики программирования хотят поддерживать разработчики языка. У каждого такого выбора есть свои плюсы и минусы; Я не думаю, что фраза «лучшие практики» здесь обязательно применима. Мы, вероятно, увидим, как кто-то в конце концов разработает уровень наследования для Go.

(Для любого читателя, знакомого с Tcl, я считаю, что Snit немного ближе к «ощущению» языка, чем [incr Tcl] . Tcl - это все, что касается делегирования, по крайней мере по моему мнению.)

29
ответ дан 7 November 2019 в 09:22
поделиться

Решающий принцип Банды 4 - «предпочитать композицию наследованию»; Go заставляет следовать за ним; -).

36
ответ дан 7 November 2019 в 09:22
поделиться

Единственными реальными вариантами использования наследования являются:

  • Полиморфизм

    • Система «статической утиной типизации» интерфейса Go решает эту проблему
  • Заимствование реализации из другого класса

    • Это то, что встраивание предназначено для

Подход Go не совсем отображает 1-к-1, рассмотрим этот классический пример наследования и полиморфизма в Java ( на основе этого ):

//roughly in Java (omitting lots of irrelevant details)
//WARNING: don't use at all, not even as a test

abstract class BankAccount
{
    int balance; //in cents
    void Deposit(int money)
    {
        balance += money;
    }

    void withdraw(int money)
    {
        if(money > maxAllowedWithdrawl())
            throw new NotEnoughMoneyException();
        balance -= money;
    }

    abstract int maxAllowedWithdrawl();
}

class Account extends BankAccount
{
    int maxAllowedWithdrawl()
    {
        return balance;
    }
}

class OverdraftAccount extends BankAccount
{
    int overdraft; //amount of negative money allowed

    int maxAllowedWithdrawl()
    {
        return balance + overdraft;
    }
}

Здесь наследование и полиморфизм вместе, и вы не можете перевести это на Go без изменения базовой структуры.

Я не углублялся в Go, но полагаю, это будет выглядеть примерно так:

//roughly Go? .... no?
//for illustrative purposes only; not likely to compile
//
//WARNING: This is totally wrong; it's programming Java in Go

type Account interface {
    AddToBalance(int)
    MaxWithdraw() int
}

func Deposit(account Account, amount int) {
    account.AddToBalance(amount)
}

func Withdraw(account Account, amount int) error {
    if account.MaxWithdraw() < amount {
        return errors.New("Overdraft!")
    }
    account.AddToBalance(-amount)
    return nil
}

type BankAccount {
    balance int
}

func (account *BankAccount) AddToBalance(amount int) {
    account.balance += amount;
}

type RegularAccount {
    *BankAccount
}

func (account *RegularAccount) MaxWithdraw() int {
    return account.balance //assuming it's allowed
}

type OverdraftAccount {
    *BankAccount
    overdraft int
}

func (account *OverdraftAccount) MaxWithdraw() int {
    return account.balance + account.overdraft
}

Согласно примечанию, это полностью неправильный способ кодирования, поскольку Java выполняется на Go. Если бы кто-то написал такую ​​вещь на Go, она, вероятно, была бы организована иначе, чем эта.

12
ответ дан 7 November 2019 в 09:22
поделиться

Я только сейчас изучаю Go, но, поскольку вы спрашиваете мнение, я предлагаю его на основе того, что мне известно до сих пор. Встраивание, по-видимому, типично для многих других вещей в Go, что является явной языковой поддержкой лучших практик, которые уже применяются в существующих языках. Например, как заметил Алекс Мартелли, «Банда четырех» говорит «предпочитать композицию наследованию». Go не только удаляет наследование, но и делает композицию более простой и мощной, чем в C ++ / Java / C #.

Я был озадачен комментариями типа «Go не предоставляет ничего нового, чего я уже не могу сделать на языке X» и "Зачем нам нужен другой язык?" Мне кажется, что с одной стороны Go не предоставляет ничего нового, чего раньше нельзя было сделать с помощью некоторой работы, но с другой стороны,

3
ответ дан 7 November 2019 в 09:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: