2016-06-07 1 views
2

Есть ли язык, допускающий супертип A, определяющий метод useFoo (Foo foo), такой как B, полученный из A, определяющий метод useFoo (Bar bar), (Bar выводится из Foo) при использовании B как A с Foo, который является баром, он будет запускать наиболее специализированную версию useFoo?Есть ли язык, позволяющий динамическое связывание для аргументов?

Java пример (не работает, к сожалению):

public class Foo { 

} 

public class Bar extends Foo { 

} 


public class A { 
    void useFoo (Foo foo) { 
     System.out.println("A"); 
    } 
} 

public class B extends A { 
    void useFoo (Bar bar) { 
     System.out.println("B"); 
    } 
} 

public static void main(String[] args) { 
    A b = new B(); 
    b.useFoo(new Bar()); // actually returns "A", is there one returning "B" ? 
} 

Я знаю, что есть способ, чтобы это произошло с «несколько» линий (с использованием посетителя к примеру), но я хотел бы знать, если любой (скомпилированный) язык позволил бы это сделать.

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

Есть ли лучшее название для этой концепции?

Редактировать: В java это называется контравариантность. спасибо @Kevinrob

+1

В Java это «ковариация» и «контравариантность», [см. Больше] (http://stackoverflow.com/a/2501513/244702). –

ответ

1

Ваш вопрос связан со следующими понятиями:

  1. Covariance: аргумент может быть переопределен в подклассах, чтобы быть подкласс исходного класса аргумента. Это соглашение используется, например, в Eiffel. Известно, что этот подход приводит к проблемам безопасности типа, CAT-вызовы (CAT = Изменение доступности или тип), которые необходимо решать особым образом, чтобы сохранить устойчивость системы типа. Сильным аргументом для covarince является то, что он прекрасно сочетается с контрактами (например, с Design by Contract).
  2. Multiple dispatch: вызовы методов выполняются, полагаясь не только на тип цели вызова, но и на типы аргументов. На этой странице перечислены несколько языков, поддерживающих этот механизм. Многократная отправка - это способ справиться с ковариацией и контравариантностью. Однако нужно быть осторожным при разработке наборов методов, которые полагаются на механизм, чтобы избежать выполнения неожиданного метода во время выполнения.
  3. Generic programming: вместо определения типов аргументов поставщиками они могут быть исправлены клиентами. Механизм безопасен по типу и свободен от проблем предыдущих двух, но требует, чтобы конкретные общие параметры явно указывались клиентами, и если таких аргументов слишком много, объявления типов могут стать громоздкими. В настоящее время существует много языков, которые его поддерживают.
+0

Я действительно вижу точку # 1 и # 2, но почему № 3? На мой взгляд, если можно расширить функциональность без необходимости писать код экспоненциально (скажем, посетителя, который должен быть детализирован для каждого случая), это лучше. (хотя и рискованно, видя ваш №2). Как вы думаете, вы можете предоставить мне дополнительную информацию? Позвольте мне быть ясными, я использую эти методы, мне просто интересно. –

+0

@PierreAntoineGuillaume, # 3 действительно немного отличается от первоначального вопроса, я добавил его на основе моего личного опыта: когда есть необходимость повторного использования кода, различных аргументов и типов результатов и типа безопасности, это может быть достигнуто путем используя общие типы. Например, вы могли бы объявить 'A ' с 'void useFoo (T foo)', который можно безопасно переопределить в 'B '. Затем вы должны написать 'A b = new B ();' и 'b.useFoo (new Bar());' будет печатать '' B "', как вы хотели. –

+0

Я не думаю, что получу лучший ответ, поэтому я закрываю этот вопрос, но я склонен думать, что он может быть обработан, действительно, дает небольшую настройку, в зависимости от того, какой язык используется: в C++ специализация шаблона несомненно, обеспечивают такую ​​функцию. Я застрял с java atm. О, хорошо, спасибо вам за понимание! –

 Смежные вопросы

  • Нет связанных вопросов^_^