2016-06-07 2 views
2

수퍼 유형을 허용하는 언어가 있습니까? B를 A와 같이 사용할 때 useFoo (Bar bar), (bar는 Foo에서 파생 됨) 메소드를 정의하는 A에서 파생 된 B와 같은 useFoo (Foo foo) 바 Foo는 useFoo의 가장 특화된 버전을 실행할 것인가?인수에 동적 바인딩을 허용하는 언어가 있습니까?

자바 예 (불행히도 작동하지) :

내가 아는
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" ? 
} 

이가 (예를 들어 방문자가 사용) "약간"선으로 일어날 수 있도록하는 방법이 있지만 내가 알고 싶습니다 모든 (컴파일 된) 언어가 허용합니다.

나는 이것이 가능한지 알고 싶습니다. 반대로 저를 놀라게하지 않을 것이며, 그것을 막을 수 있습니까?

더 좋은 개념이 있나요?

편집 : 자바에서는 Contravariance로 명명됩니다. 당신이

+1

Java에서는 "공분산"및 "Contravariance", [더보기] (http://stackoverflow.com/a/2501513/244702)입니다. –

답변

1

가 귀하의 질문은 다음과 같은 개념과 관련이 @Kevinrob 감사합니다 :

  1. Covariance는 : 인수는 원래 인수 클래스의 하위 클래스로 서브 클래스에서 재정의 될 수 있습니다. 이 협약은 예를 들어 에 에펠에서 사용됩니다. 이 접근법은 유형 안전성 문제로 이어지는 것으로 알려져 있으며, 유형 시스템 안정성을 유지하기 위해 특별한 방법으로 해결해야하는 CAT 호출 (CAT = 가용성 변경 또는 유형)이 있습니다. covarince에 대한 강한 논쟁은 계약 (예 : 계약 별 설계)과 잘 어울리는 것입니다.
  2. Multiple dispatch : 메소드 호출은 유형을 대상으로 할뿐만 아니라 인수의 유형에도 의존하여 수행됩니다. 이 페이지는이 메커니즘을 지원하는 여러 언어를 나열합니다. 다중 파견은 공분산 및 반 차별을 다루는 방법입니다. 그러나 실행시 예기치 않은 메서드를 실행하지 않도록 메커니즘에 의존하는 메서드 집합을 디자인 할 때는주의해야합니다.
  3. Generic programming : 공급자가 인수 유형을 고정하는 대신 클라이언트에서 수정할 수 있습니다. 메커니즘은 유형에 안전하며 앞의 두 가지 문제는 없습니다. 그러나 클라이언트가 명시 적으로 실제 generic 매개 변수를 지정해야하며 이러한 인수가 너무 많으면 유형 선언이 다루기 힘들어 질 수 있습니다. 요즘에는 언어를 지원하는 언어가 많이 있습니다.
+0

# 1과 # 2의 포인트를 실제로 볼 수 있지만 왜 # 3인가? 내 의견으로는, 코드를 기하 급수적으로 작성하지 않고도 functionnality를 확장 할 수 있다면 (각각의 가능한 모든 경우에 대해 상세히 설명해야하는 방문자를 가정 해 봅시다), 더 좋습니다. (비록 당신의 # 2를 보는 위험한). 좀 더 자세한 정보를 제공 할 수 있다고 생각하십니까? 내가 분명히하자면, 나는이 기술들을 사용한다. 나는 단지 궁금하다. –

+0

@PierreAntoineGuillaume, # 3은 원래 질문과는 조금 다르게 내 개인적인 경험에 따라 추가했습니다. 코드 재사용, 다양한 인수 및 결과 유형 및 유형 안전성이 필요할 때 제네릭 형식을 사용합니다. 예를 들어'B '에서 안전하게 재정의 할 수있는'void useFoo (T foo)'로'A '을 선언 할 수 있습니다. 그런 다음'A b = new B ();'과'b.useFoo (new Bar());'는''B "'를 원하는대로 인쇄합니다. –

+0

나는 더 나은 대답을 얻을 것이라고 생각하지 않는다. 그러므로 나는이 질문을 마친다. 그러나 실제로 다루어 질 수있는 방법이 언어가 사용되는 언어에 따라 약간 조정할 수 있다고 생각하는 경향이있다. C++에서는 템플릿 전문화가 의심의 여지없이 이런 종류의 기능을 제공합니다. 나는 자바 atm 함께 붙어있다. 오 잘, 당신의 통찰력에 대해 대단히 감사합니다! –

관련 문제