4

Прежде всего, я почти ничего не знаю о теории языка, и я почти не знаю каких-либо других языков, кроме Java, но у меня была идея, что я думаю, что это круто, но мне нужно, чтобы вы сказали мне:
a: why это отстой
б: как язык х были, что в течение многих лет
с: как мой ум сосет
D: все вышеперечисленноеМожет ли синтаксис композиции быть полезным дополнением к Java?

идея дала бы сОСТАВУ ту же легкость повторного использования кода, что делает extends.

Так что, если у вас есть класс вроде этого:

 
public interface A { 
    public void methodInA(); 
} 

И тогда вы имели класс вроде этого:

 
public class B { 
    private composed A; 
    public B() { 
     // construct A within constructor 
    } 
} 

Вы бы тогда быть в состоянии сделать это:

 
B myB = new B(); 
myB.methodInA(); 

Без необходимости добавлять делегацию в класс B. Но вы также можете сделать то же самое, как с наследованием, то есть:

 
@Overrides 
public void methodInA(){ 
    // B's own delegation method 
} 

К недостаткам можно отнести:

  • методы скрыты в исходном коде, что делает его менее очевидным, когда вызов приходит, но это также в случае с extends
  • если составленные поля одни и те же сигнатуру метода там должен быть конфликт решен (как противоречащие друг другу интерфейсы решить эту проблему?)
  • , если вы хотите иметь несколько составленных полей одного и того же типа, было бы очевидно, что конфликт, для которого поле делегировать
  • вероятно 100 другие вещи, которые я не думал о

Как я уже сказал, я не буду, очевидно, ни один язык теоретиком, и я не имею потраченные возрасты думали об этом, идея только что появилась у меня в голове, и я хотел знать, насколько я ошибаюсь. Я просто думаю, что это было бы круто.

ответ

0

Я думаю, что если бы вы ограничили его таким, чтобы класс мог использовать эту функцию только для создания одного класса, это было бы несколько полезно и позволило бы избежать множества обсуждаемых головных болей.

Лично я ненавижу наследование конкретных классов. Я большой сторонник пункта 14 от Bloch's Эффективная Java, Favor composition over inheritence. Я думаю, что что-то вроде этого облегчит реализацию идиомы, которую он рекомендует в этом пункте.

Честно говоря, если вы действительно знали, что делаете, я готов поспорить, что вы могли бы написать аннотацию компилятора, которая бы справилась с этим. Так если вы имели класс Bar, который реализован интерфейс IBar, ваш класс будет выглядеть следующим образом:

public class Foo { 

    @Delegate(IBar.class) 
    private Bar bar; 

    // initialize bar via constructor or setter 
} 

Затем во время компиляции Foo может быть сделано для реализации IBar и любой из методов этого интерфейса, которые не были уже осуществляется Foo бы в конечном итоге генерируется выглядеть следующим образом:

public Baz method1(Qux val) { 
    return bar.method1(val); 
} 

Как упоминалось выше, вы хотели бы сделать ограничение, что только одно поле в классе может использовать эту аннотацию. Если у нескольких полей была эта аннотация, вы, вероятно, захотите выбросить ошибку компиляции. В качестве альтернативы вы можете определить способ кодирования какой-либо модели приоритета в переданные ей параметры.

Теперь, когда я написал это, кажется, что это круто. Может быть, я буду играть с ним на следующей неделе. Я обновлю это, если мне удастся что-то выяснить.

+0

«Честно говоря, если вы действительно знали, что делаете ...» - и в этом и заключается мой друг! :-D – Grundlefleck

+0

Подход, который я бы одобрил, должен был позволить классу обозначать два члена (например, «первый» и «второй»), так что попытка доступа к 'foo.someMemberName', когда' foo' не имеет такого члена, переписывать как 'foo.first(). someMemberName' [без использования такого поиска рекурсивно при возврате из' first'], и если это не удалось, 'foo.first(). someMemberName' [позволяющий рекурсивный поиск по возврату из' second']. Обратите внимание, что не требуется «укладка» рекурсивного поиска. – supercat

0

Я не уверен, что вижу ясное преимущество в этом. Я понимаю, что вы делаете. На данный момент для вызова метода на A вы должны использовать myB.getAInstance(). MethodInA(), но вы хотите сделать это myB.methodInA().

Но что произойдет, если у вас есть несколько экземпляров A? Как будет разрешен вызов метода? Много раз композиция подразумевает от одной до многих ассоциаций, поэтому B имеет много экземпляров A. Что происходит тогда?

Я согласен с вашими недостатками. Это может просто вызвать слишком много путаницы, чем это стоит.

+0

Это не совсем то, что я хотел бы myB.getAInstance(). MethodInA(), я могу использовать скомпилированное поле для реализации интерфейса, поэтому класс должен иметь сам метод. – Grundlefleck

1

Звучит круто, но я думаю, что это создает некоторые ужасные языковые конструкции. Очевидно, что существует проблема, если вы объявляете несколько «композиций» одного и того же класса, но даже если вы запрещаете, что в случае, когда вызов соответствует методу в более чем одном из (разных) составленных классов? Вам нужно будет указать, какой из них был вызван в основном классе, и для этого вам понадобится дополнительный синтаксис. Ситуация становится еще хуже, если в классах есть публичные участники.

Композиция используется для предотвращения проблем с множественным наследованием. Разрешение такой композиции эффективно разрешает множественное наследование, по крайней мере, с точки зрения разрешения способа вызова. Поскольку ключевое дизайнерское решение с Java должно было запретить множественное наследование (по уважительным причинам), я считаю маловероятным, что это когда-либо будет представлено Java.

+0

«.. Я думаю, маловероятно, что это когда-нибудь появится на Java». - Я слышал, что, если я смогу сформировать идею добавления к одному из, если не самому широко используемому языку программирования, то, что было довольно медленным днем ​​... ну, у нас и у Солнца есть проблемы: -D – Grundlefleck

+0

Что, если компилятор обнаружит конфликт, это заставит вас переопределить его? Таким образом, вы вынуждены разрешать его одним способом, без чрезмерной стоимости синтаксиса, поскольку он не выглядел бы неуместным. Но публичные участники ... да, они вообще не думали о них ... хммм. – Grundlefleck

-1

Существует также разница между составом и агрегацией для рассмотрения. Как компилятор знает, имеете ли вы отношения «is-a» или «has-a»?

  • Имеет ли весь граф объекта право на сбор мусора или только на графу?

Парочка инструментов и механизмов отображения ORM над/вокруг них обеспечивает belongsTo или has-many отношений между постоянными объектами и некоторые из них также обеспечивает для каскадного удаления (для композиции). Я не знаю об одной раздаче, которая обеспечивает простой синтаксический сахар, который вы ищете.

На самом деле, с другой стороны, идиомы Groovy's MetaClass и MetaProgramming могут предоставить что-то очень похожее, с делегацией «автомагия».

-1

Множественное наследование разрешено на C++, я знаю, что оно отличается от другого, но оно происходит по одному и тому же мыслительному процессу. Java была разработана так, чтобы не допускать множественного наследования, чтобы было меньше путаницы, а значит, ошибок и эксплойтов.

То, что вы предложили, прямо противоречит принципам java.

Сказав это, было бы здорово (не обязательно полезно). Я программист Java, который переключился с C++. Мне нравится, когда я могу совершать свои собственные ошибки.

0

Ознакомьтесь с тем, что называется «Mixins» на некоторых языках, и «Роли» в системе Perl 5 Moose OO.