>

최근 제공자 와 협력하고 있습니다. 그리고 나는 추상 정적 메소드를 가진 추상 클래스를 갖고 싶었던 흥미로운 상황을 발견했습니다. 주제에 대한 몇 가지 게시물을 읽었으며 이해가 되긴하지만 명확한 설명이 있습니까?


  • 답변 # 1

    정적 메소드는인스턴트 화되지 않으므로 객체 참조없이 사용할 수 있습니다.

    정적 메소드에 대한 호출은 객체 참조가 아닌 클래스 이름을 통해 수행되며이를 호출하기위한 IL (Intermediate Language) 코드는이를 정의한 클래스 이름을 통해 추상 메소드를 호출합니다. 사용한 수업 이름.

    예를 보여 드리겠습니다.

    다음 코드로 :

    public class A
    {
        public static void Test()
        {
        }
    }
    public class B : A
    {
    }
    
    

    B.Test에 전화하면 다음과 같이됩니다 :

    class Program
    {
        static void Main(string[] args)
        {
            B.Test();
        }
    }
    
    

    Main 메소드 내부의 실제 코드는 다음과 같습니다 :

    .entrypoint
    .maxstack 8
    L0000: nop 
    L0001: call void ConsoleApplication1.A::Test()
    L0006: nop 
    L0007: ret
    
    

    알다시피, 코드를 그런 식으로 작성할 수 있지만 A.Test는 B.Test가 아닌 A 클래스이기 때문에 A.Test가 호출됩니다.

    델파이처럼클래스 유형을 가지고 있다면 객체가 아닌 유형을 참조하는 변수를 만들 수 있습니다. 여기서 가상 메소드와 추상 정적 메소드에 더 많이 사용할 것입니다. 생성자)를 사용할 수 없지만 .NET에서는 정적 호출이 가상이 아닙니다.

    IL 디자이너가 코드를 컴파일하여 B.Test를 호출하고 런타임에 호출을 해결할 수 있다는 것을 알고 있지만 여전히 일종의 클래스 이름을 작성해야하므로 가상적이지는 않습니다. 거기 요.

    가상 메소드와 추상 메소드는 런타임에 여러 유형의 오브젝트를 포함 할 수있는 변수를 사용하는 경우에만 유용하므로 현재 오브젝트에 대해 올바른 메소드를 호출하려고합니다. 변수. 정적 메소드를 사용하면 어쨌든 클래스 이름을 거쳐야하므로 호출 할 정확한 메소드는 컴파일 타임에 알 수 없으며 변경 될 수 없으므로 변경되지 않습니다.

    따라서 가상/추상 정적 메서드는 .NET에서 사용할 수 없습니다.

  • 답변 # 2

    고정 메서드는 상속되거나 재정의 될 수 없으므로 추상적 일 수 없습니다. 정적 메소드는 클래스의 인스턴스가 아닌 유형에 정의되므로 해당 유형에서 명시 적으로 호출해야합니다. 따라서 자식 클래스에서 메소드를 호출하려면 해당 이름을 사용하여 호출해야합니다. 이것은 상속을 무의미하게 만듭니다.

    잠시 동안 정적 메소드를 상속 할 수 있다고 가정하십시오. 이 시나리오를 상상해보십시오.

    public static class Base
    {
        public static virtual int GetNumber() { return 5; }
    }
    public static class Child1 : Base
    {
        public static override int GetNumber() { return 1; }
    }
    public static class Child2 : Base
    {
        public static override int GetNumber() { return 2; }
    }
    
    

    Base.GetNumber ()를 호출하면 어떤 메소드가 호출됩니까? 어떤 값이 반환 되었습니까? 객체 인스턴스를 만들지 않으면 상속이 어렵다는 것을 쉽게 알 수 있습니다. 상속이없는 추상 메서드는 본문이없는 메서드이므로 호출 할 수 없습니다.

  • 답변 # 3

    다른 응답자 (McDowell)는 다형성이 개체 인스턴스에만 작동한다고 말했다. 그것은 자격이 있어야합니다. 클래스를 "클래스"또는 "메타 클래스"유형의 인스턴스로 취급하는 언어가 있습니다. 이 언어는 인스턴스 및 클래스 (정적) 메소드 모두에 다형성을 지원합니다.

    C #은 이전의 Java 및 C ++과 같은 언어가 아닙니다. static  키워드는 메소드가 동적/가상이 아니라 정적으로 바인드됨을 나타 내기 위해 명시 적으로 사용됩니다.

  • 답변 # 4

    이전 설명에 추가하기 위해 정적 메소드 호출은컴파일 타임에 특정 메소드에 바인드됩니다, 다형성 동작을 배제합니다.

  • 답변 # 5

    정적 필드와 메소드에 대한 상속이 필요한 상황은 다음과 같습니다 :

    abstract class Animal
    {
      protected static string[] legs;
      static Animal() {
        legs=new string[0];
      }
      public static void printLegs()
      {
        foreach (string leg in legs) {
          print(leg);
        }
      }
    }
    
    class Human: Animal
    {
      static Human() {
        legs=new string[] {"left leg", "right leg"};
      }
    }
    
    class Dog: Animal
    {
      static Dog() {
        legs=new string[] {"left foreleg", "right foreleg", "left hindleg", "right hindleg"};
      }
    }
    
    public static void main() {
      Dog.printLegs();
      Human.printLegs();
    }
    
    //what is the output?
    //does each subclass get its own copy of the array "legs"?
    
    

  • 이전 두 마커가 서로 가까이있을 때 마커 레이블이 겹칩니다 Google지도 마커에 배경색을 부여하는 방법은 무엇입니까?
  • 다음 scala - 수신 된 메시지를 두 가지 다른 흐름으로 브로드 캐스트하는 방법