2013-02-12 1 views
18

static 메서드가 암시 적으로 final이고 따라서 재정의 할 수 없다고 들었습니다. 그게 사실이야?정적 메서드를 C#에서 재정의 할 수 있습니까?

  1. 누군가 정적 메서드를 재정의하는 더 나은 예를 제공 할 수 있습니까?

  2. 정적 메소드가 클래스 메소드 일 경우, 실제로 사용하는 것은 무엇입니까?

+1

아니요, 재정의 할 수 없습니다. 그것들은 클래스가 아니라 객체와 연관되어 있습니다. 실제 사용을위한 –

+0

: 클래스 인스턴스없이 정적 메서드를 호출 할 수 있습니다. – Najzero

+0

감사합니다. SLaks가 제공 한 가장 좋은 예는 [정적 메소드 란 무엇인가] (http://stackoverflow.com/a/4124118/2061309)입니다. 그래서 정적 메서드를 재정의하는 방법에 대한 내 질문에 대한 (bydefault 그것이 최종, 사용자가 최종하지 않는 경우) - 정적을 보유하고있는이 클래스의 하위 클래스가 동일한 서명으로 정적 메서드를 정의 할 수 있다는 것을 의미합니까? – aspiring

답변

17

(1) 정적 메서드는 재정의 할 수 없지만 'new'키워드를 사용하여 숨길 수 있습니다. 대부분 재정의하는 메서드는 기본 형식을 참조하고 파생 된 메서드를 호출하기를 원한다는 것을 의미합니다. 정적은 형식의 일부이므로 의미가없는 vtable 조회가 적용되지 않습니다.

예. 정적은 수행 할 수 없습니다 정적이 인스턴스에서 작동하지 않기 때문에, 당신은 항상 명시 적으로 Foo.Bar 또는 Bar.Bar를 지정

public class Foo { 
    public virtual void Bar() { ... } 
} 
public class Bar : Foo { 
    public override void Bar() { ... } 
} 

// use: 
Foo foo = new Bar(); // make an instance 
foo.Bar(); // calls Bar::Bar 

. 따라서 우선 적용은 의미가 없습니다 (코드로 표현 해보세요 ...).

(2) 정적 방법에는 여러 가지 용도가 있습니다. 예를 들어, Singleton 패턴에서 단일 인스턴스 인스턴스를 가져 오는 데 사용됩니다. 또 다른 예는 프로그램의 주요 액세스 지점 인 'static void Main'입니다.

기본적으로 사용하기 전에 개체 인스턴스를 만들고 싶지 않거나 만들지 않을 때마다 사용합니다. 예를 들어, 정적 메소드가 객체를 생성 할 때.

[업데이트]

간단한 숨어 예 : 당신이 클래스 static을 할 경우, 당신은이 작업을 수행 할 수

public class StaticTest 
{ 
    public static void Foo() { Console.WriteLine("Foo 1"); } 
    public static void Bar() { Console.WriteLine("Bar 1"); } 
} 

public class StaticTest2 : StaticTest 
{ 
    public new static void Foo() { Console.WriteLine("Foo 2"); } 
    public static void Some() { Foo(); Bar(); } // Will print Foo 2, Bar 1 
} 

public class TestStatic 
{ 
    static void Main(string[] args) 
    { 
     StaticTest2.Foo(); 
     StaticTest2.Some(); 
     StaticTest.Foo(); 
     Console.ReadLine(); 
    } 
} 

참고. 정적 클래스는 object에서 파생되어야합니다.

이 상속의 주된 차이점은 컴파일러가 컴파일 타임에 static을 사용할 때 호출 할 메소드를 결정할 수 있다는 것입니다. 객체의 인스턴스가있는 경우 런타임에이를 수행해야합니다 (이를 vtable 조회라고 함).

+0

무시 무시한 예를 들어 주셔서 감사합니다. 예, 코드에서 시도하고 있습니다. 그래서이 권리를 얻으려면, 1) ** 우리는 다른 비 정적 클래스 **처럼 정적 클래스를 서브 클래스로 만들 수 있습니까? 2) 부모 클래스의 정적 메서드를 재정의하지 않고 정적 메서드를 사용할 수 있지만 새 키워드를 사용하여 숨 깁니다. – aspiring

+0

몇 가지 설명과 예제를 추가했습니다. (1) 정적 클래스를 하위 클래스로 분류 할 수는 없지만 정적 멤버를 숨길 수는 있습니다. (2) 예, 두 번째 예제를 시도해 봐야 어떻게 동작하는지 알 수 있습니다. – atlaste

+3

언제이 Foo <-> 바 넌센스 끝 ??? 예를 들어 FoorBar 사용을 중지하십시오. 각각의 경우 Bar 및 Foo는 클래스 또는 하위 클래스 또는 함수 또는 메소드입니다. 그래서 whats 요점 ??? 서브 클래 싱을위한 Animals와 오버라이드를위한 액션을 사용하십시오. 10x –

5

정적 메서드를 재정의하지 마십시오. 당신은 그것을 숨 깁니다. 자세한 내용은 this answer을 참조하십시오.

이유로는 정적 인 방법을 사용합니다 :

  1. 그들은 인스턴스 메서드보다 little bit faster이다. 또한이 수치를 뒷받침 할 성능 수치를 제공하는 msdn article을 참조하십시오 (인라인 된 정적 호출 평균 0.2 ns, 정적 호출 평균 6.1 ns, 인라인 인스턴스 호출 평균 1.1 ns, 인스턴스 호출 평균 6.8 ns)
  2. 더 적은 정보를 쓸 수 있습니다. (그리고 인스턴스화가 성능에 영향을 줄 수도 있습니다.)
+0

인스턴스 메서드에 문제가 없습니다. static 클래스는 인스턴스화 될 수 없다는 것을 알게되었습니다. 하지만 당신은 "정적 메소드는 앱에서 한 번만 인스턴스화된다는 것"이라고 언급했습니다. 지금은 혼란 스럽습니다. 당신은'Using System.Math;'를 언급하고 있습니까? 정적 메소드가 인스턴스화되었다고 말하고 있습니까? 저는 Math 클래스 멤버 인 Math.Abs ​​()를 동일한 클래스에서 여러 번 사용했습니다. 한번도 인스턴스화하지 않았습니다. 1) 그래서 *** 당신이 의미하는 바를 명확히 해 주시겠습니까? 2) 정적 클래스가 하위 클래스 일 수 있습니까? 하위 클래스에 정적 클래스를 사용하는 것이 합리적입니까? – aspiring

+1

내 편집을 참조하십시오. 정적 메소드로 "인스턴스화"라는 용어를 사용해서는 안됩니다. 더 정확한 것은 단 한 번만 만들어 졌다는 것입니다. –

+1

모든 * 방법 *은 한 번만 "생성"됩니다. 비 정적 메소드 라 할지라도 존재하는 코드의 복사본은 단 하나뿐입니다 (IL 코드는 컴파일 타임에 생성되고 런타임에 기계 코드 *로 변환됩니다). 코드와 데이터를 혼동하지 마십시오! 비 정적 메소드는 객체의 인스턴스를 통해서만 호출 가능하지만, 이는 전달 된 숨겨진 "this"포인터 때문입니다. 코드 자체는 고정되어 있고 싱글 톤이라는 점에서 "정적"입니다. –

5

음 정적 메서드를 재정의 할 수 없습니다. 정적 메소드는 클래스의 인스턴스와 관련이 없기 때문에 가상 일 수 없습니다.

파생 클래스의 "overriden"메서드는 실제로 기본 메서드 (새 키워드)에 정의 된 메서드와 관련이없는 새로운 메서드입니다.

유형을 다른 유형에서 상속 할 때 유형이 공통 계약을 충족시키는 반면 정적 유형은 모든 계약 (순수 OOP 관점에서)에 구속되지 않는다는 점을 이해하는 것이 중요합니다. 두 가지 정적 유형을 "상속"계약과 함께 묶는 기술적 방법은 없습니다. 두 가지 다른 위치에서 Log 메소드를 "오버라이드"하는 경우.

정적 메서드를 너무 많이 사용한다고 생각하면 실제로 이해할 수 없습니다. 가상 디스패치를하려면 검사 할 객체의 실제 인스턴스가 필요합니다.

정적 메서드도 인터페이스를 구현할 수 없습니다. 이 클래스가 IRolesService 인터페이스를 구현하고 있다면 메서드가 정적이 아니어야한다고 주장 할 것입니다. 인스턴스 메소드를 사용하는 것이 더 좋으므로, 준비가되면 실제 서비스로 MockRoleService를 바꿀 수 있습니다.

+0

감사합니다. 그것은 소량으로 나에게 약간 위로 비트지만, 길을 따라 나는 그것을 얻을 것입니다 :) 추신 : 그리고 분명히 당신의 수업에 참여하고 싶습니다. 발견 [이 게시물도 자바 컨텍스트에서.] (http://www.xyzws.com/Javafaq/can-static-methods-be-overridden/1) – aspiring

+1

hehe도 나는 C#을 배우고 있습니다 .. 나는 22 년입니다. 늙고 회사에서 근무하고 있습니다. 간단한 일을 통해 계속해서 단계별로 이해할 수 있습니다. – Neel

관련 문제