추상 함수와 가상 함수의 차이점은 무엇입니까?


1578

추상 함수와 가상 함수의 차이점은 무엇입니까? 어떤 경우에 가상 또는 추상을 사용하는 것이 좋습니다? 가장 좋은 방법은 무엇입니까?


271
추상 기능은 재정의해야하지만 가상 기능은 재정의 될 수 있습니다.
Jordan Parmer

15
가상 함수는 기본 클래스에서 기본 / 일반 구현을 가질 수 있습니다.
Martin

5
여기서 핵심 단어는 추상적입니다 . 그것들은 존재하지 않으며 그 기능이 무엇인지에 대한 모호한 아이디어 일뿐입니다.
Cole Johnson

답변:


2733

추상 함수는 기능을 가질 수 없습니다. 기본적으로 모든 하위 클래스는이 메소드의 자체 버전을 제공해야하지만 상위 클래스에서 구현하려고 시도하는 것은 너무 일반적입니다.

가상 함수 는 기본적으로 외모를 말하고 있습니다. 자식에 충분하거나 충분하지 않을 수있는 기능이 있습니다. 충분하다면이 방법을 사용하고 그렇지 않은 경우 나를 무시하고 고유 한 기능을 제공하십시오.


396
물론 가상 메서드를 재정의하는 경우 항상 base.Foo (...)를 호출하여 부모 메서드를 참조 할 수 있습니다.
Brann

196
감사. . 이것은 MSDN 문서의 어떤 것보다 훨씬 더 쉽게 설명입니다 (: 나는이 글을 읽는 5 분 후 두통이 있었다 msdn.microsoft.com/en-us/library/aa645767(v=vs.71).aspx )
Jake

15
Java에서 왔을 때, 나는 이것을 읽을 때까지 왜 가상으로 만들어야하는지에 대해 조금 당황했습니다. stackoverflow.com/a/1062126/193634
Rosdi Kasim

4
당신이 내 실현하는 것이 사용처럼 날이 : 나보다 더 나은 자신의 쓰기하지 않을 경우 경우 @MeqDotNet 그것은 의미
우스만 Younas

16
이것은 10 분 동안 읽고 여전히 혼란스러워하는 Microsoft 참조 라이브러리에 있어야합니다.
SamChen

303

추상 함수에는 구현이 없으며 추상 클래스에서만 선언 할 수 있습니다. 이렇게하면 파생 클래스가 구현을 제공하게됩니다.

가상 함수는 기본 구현을 제공하며 추상 클래스 또는 비추 상 클래스에 존재할 수 있습니다.

예를 들어 :

public abstract class myBase
{
    //If you derive from this class you must implement this method. notice we have no method body here either
    public abstract void YouMustImplement();

    //If you derive from this class you can change the behavior but are not required to
    public virtual void YouCanOverride()
    { 
    }
}

public class MyBase
{
   //This will not compile because you cannot have an abstract method in a non-abstract class
    public abstract void YouMustImplement();
}

28
샘플 코드를 보는 데 매우 유용합니다-답변의 다양한 설명을 훨씬 더 명확하게합니다.
Simon Tewsi

2
이전 버전에 대한 대답을 롤백했습니다. 두 클래스는 단지 예제이며 첫 번째 클래스는 추상으로 표시되고 두 번째 클래스는 컴파일되지 않으므로 컴파일됩니다. MyBase가 다른 클래스에서 상속되는지 여부는 관련이 없습니다.
Dirk

2
당신하지 않습니다 MyBase클래스는 구현해야 추상적 어떻게 든 클래스를? 나는 이것을 자주하지 않기 때문에 착각 할 수 있습니다. 나는 당신의 예에서 그것을 보지 못합니다.
jp2code

2
위의 예에서 MyBase는 할 수없는 것을 보여줍니다. 그것은 추상 클래스가 아닌 클래스에서 추상 메소드를 가질 수 없다는 것입니다
JoshBerke

80
  1. abstract수업 만 가능abstract 회원 .
  2. abstract클래스한다는로부터 상속 abstract클래스 해야 overrideabstract 구성원.
  3. abstract멤버는 암시 적이다virtual .
  4. abstract멤버는 구현 (제공 할 수 없다 abstract라고 pure virtual일부 언어에서).

3 번은 이해가되지 않습니다. "추상 클래스의 멤버는 내재적으로 가상"이라고 말하려고한다고 생각합니다 (즉, 가상 클래스를 지정하지 않고도 기능을 제공 할 수 있음).
Hobo Spider

5
아니요, 제가 쓴 것을 정확히 의미했습니다. 추상 클래스의 멤버는 virtual또는 아닌 수 있습니다 virtual. abstract멤버 (즉, 추상적 인 특성, 추상적 인 방법은) 그 자체와 기본 구현을 수행하지 않는 것을 제외하고 즉, 당신은 그것을 대체 할 수 있습니다, 단지 가상의 방법과 같다.
Mehrdad Afshari

"추상 회원은"암시 적으로 "가상입니다." 그러나 어딘가에서 누군가 "가상"키워드를 명시 적으로 추가하여 추상 멤버를 만들었습니다. 그것은 필요하지 않으며 실제로 당신의 대답을 읽을 때까지 의심의 여지가있었습니다.
bonCodigo 12

포인트 4에 대한 지원 참조를 포함하십시오. 귀하의 게시물에는 이전 게시물에 없었던 다른 내용이 없습니다.
라파엘

이것은 설명이없는 단지 진술입니다.
리버스 엔지니어링

61

항상 추상 함수를 재정의해야합니다.

그러므로:

  • 추상 함수 - 상속자가 자체 구현을 제공해야하는 경우
  • 가상 - 상속자가 결정해야 할 때

37

추상 기능 :

  1. 추상 클래스 내에서만 선언 할 수 있습니다.
  2. 추상 클래스의 구현이 아닌 메소드 선언 만 포함합니다.
  3. 파생 클래스에서 재정의해야합니다.

가상 기능 :

  1. 비 추상 클래스뿐만 아니라 추상 내부에도 선언 할 수 있습니다.
  2. 메소드 구현을 포함합니다.
  3. 재정의 될 수 있습니다.

29

추상 메서드 : 클래스에 추상 메서드가 포함 된 경우 해당 클래스는 추상으로 선언해야합니다. 추상 메소드에는 구현이 없으므로 해당 추상 클래스에서 파생 된 클래스는이 추상 메소드에 대한 구현을 제공해야합니다.

가상 메소드 : 클래스는 가상 메소드를 가질 수 있습니다. 가상 메소드에는 구현이 있습니다. 가상 메서드가있는 클래스에서 상속하면 가상 메서드 재정의하고 추가 논리를 제공하거나 논리를 자신의 구현으로 바꿀 수 있습니다.

사용시기 : 경우에 따라 특정 유형에 특정 방법이 있어야한다는 것을 알고 있지만이 방법에 어떤 구현이 필요한지 알 수 없습니다.
이러한 경우이 서명이있는 메소드가 포함 된 인터페이스를 작성할 수 있습니다. 그러나 그러한 경우가 있지만 해당 인터페이스의 구현 자에게 또 다른 일반적인 메소드 (이미 구현을 제공 할 수있는)가 있음을 알고 있으면 추상 클래스를 작성할 수 있습니다. 그런 다음이 추상 클래스에는 추상 메소드 (오버라이드해야 함)와 '공통'논리를 포함하는 다른 메소드가 포함됩니다.

직접 사용할 수는 있지만 상속자가 특정 동작을 변경할 수 있기를 원하지만 필수는 아니지만 가상 메서드를 사용해야합니다.


29

설명 : 유추로. 잘하면 그것은 당신을 도울 것입니다.

문맥

나는 건물의 21 층에서 일합니다. 그리고 나는 불에 대한 편집증입니다. 세상 어딘가에서 불이 하늘 긁는 도구를 태우고 있습니다. 그러나 운 좋게도 화재시해야 할 일에 대한 지침서가 여기 있습니다.

비상 계단()

  1. 소지품을 수집하지 마십시오
  2. 화재 탈출을 걸어
  3. 건물 밖으로 걸어

기본적으로 FireEscape () 라는 가상 메소드입니다.

가상 방법

이 계획은 상황의 99 %에 매우 적합합니다. 작동하는 기본 계획입니다. 그러나 화재 탈출구가 막히거나 손상 될 가능성이 1 %입니다.이 경우 완전히 조여져 과감한 조치를 취하지 않으면 축배가됩니다. 가상 메소드를 사용하면 다음과 같이 할 수 있습니다. 기본 버전의 FireEscape () 계획을 자체 버전의 계획으로 재정의 할 수 있습니다.

  1. 창으로 실행
  2. 창문 밖으로 뛰어
  3. 바닥에 안전하게 낙하산

즉, 가상 메소드는 기본 계획을 제공하며, 필요한 경우 대체 할 수 있습니다 . 프로그래머가 적절하다고 생각하면 서브 클래스는 부모 클래스의 가상 메소드를 대체 할 수 있습니다.

추상 방법

모든 조직이 잘 훈련 된 것은 아닙니다. 일부 조직은 소방 훈련을하지 않습니다. 그들은 전반적인 탈출 정책이 없습니다. 모든 사람은 자신을위한 것입니다. 경영진은 기존 정책에만 관심이 있습니다.

즉, 각 사람은 자신의 FireEscape () 메소드를 개발 해야 합니다. 한 사람이 화재 탈출구를 걸어 나갑니다. 다른 사람은 낙하산을 씁니다. 다른 사람은 로켓 추진 기술을 사용하여 건물에서 날아갑니다. 다른 사람이 밖으로 나옵니다. 기본 FireEscape () 계획이있는 한 경영진은 어떻게 탈출 해야하는지 신경 쓰지 않습니다. 그렇지 않은 경우 OHS가 벽돌처럼 조직에 쓰러 질 것입니다. 이것이 추상적 방법입니다.

이 둘의 차이점은 무엇입니까?

추상 메소드 : 하위 클래스는 자체 FireEscape 메소드를 구현 해야 합니다. 가상 메소드를 사용하면 기본 계획이 기다리고 있지만 충분하지 않은 경우 직접 구현 하도록 선택할 수 있습니다 .

이제 그렇게 힘들지 않습니까?


22

추상 메소드는 구체적인 클래스를 만들기 위해 구현해야하는 메소드입니다. 선언은 추상 클래스에 있으며 추상 메서드가있는 클래스는 추상 클래스 여야하며 구체적인 클래스로 구현해야합니다.

가상 메서드는 재정의를 사용하여 파생 클래스에서 재정의 되어 수퍼 클래스의 동작을 대체 할 수있는 메서드입니다 . 재정의하지 않으면 원래 동작이 나타납니다. 그렇게하면 항상 새로운 행동을 얻게됩니다. 이는 가상 메서드가 아니라 재정의 할 수는 없지만 원래 메서드를 숨길 수는 없습니다. 이것은 new수정자를 사용하여 수행됩니다 .

다음 예를 참조하십시오.

public class BaseClass
{
    public void SayHello()
    {
        Console.WriteLine("Hello");
    }


    public virtual void SayGoodbye()
    {
        Console.WriteLine("Goodbye");
    }

    public void HelloGoodbye()
    {
        this.SayHello();
        this.SayGoodbye();
    }
}


public class DerivedClass : BaseClass
{
    public new void SayHello()
    {
        Console.WriteLine("Hi There");
    }


    public override void SayGoodbye()
    {
        Console.WriteLine("See you later");
    }
}

인스턴스화 DerivedClass하고 SayHello, 또는를 호출 SayGoodbye하면 "Hi There"와 "나중에 보자"가 표시됩니다. 전화 HelloGoodbye하면 "Hello"와 "나중에 보자"가 표시됩니다. SayGoodbye가상 이기 때문에 파생 클래스로 대체 될 수 있습니다. SayHello은 숨겨져 있기 때문에 기본 클래스에서 호출하면 원래 메서드를 얻습니다.

추상 메소드는 내재적으로 가상입니다. 인터페이스와 같이 존재해야하는 동작을 정의합니다.


9

추상 메소드는 항상 가상입니다. 구현할 수 없습니다.

이것이 주요 차이점입니다.

기본적으로 '기본'구현이 있고 후손이 동작을 변경하도록하려면 가상 방법을 사용합니다.

추상 메소드를 사용하면 자손이 강제로 구현을 제공하게됩니다.


9

다음 클래스에서 다른 답변을 개선하여이를 단순화했습니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestOO
{
    class Program
    {
        static void Main(string[] args)
        {
            BaseClass _base = new BaseClass();
            Console.WriteLine("Calling virtual method directly");
            _base.SayHello();
            Console.WriteLine("Calling single method directly");
            _base.SayGoodbye();

            DerivedClass _derived = new DerivedClass();
            Console.WriteLine("Calling new method from derived class");
            _derived.SayHello();
            Console.WriteLine("Calling overrided method from derived class");
            _derived.SayGoodbye();

            DerivedClass2 _derived2 = new DerivedClass2();
            Console.WriteLine("Calling new method from derived2 class");
            _derived2.SayHello();
            Console.WriteLine("Calling overrided method from derived2 class");
            _derived2.SayGoodbye();
            Console.ReadLine();
        }
    }


    public class BaseClass
    {
        public void SayHello()
        {
            Console.WriteLine("Hello\n");
        }
        public virtual void SayGoodbye()
        {
            Console.WriteLine("Goodbye\n");
        }

        public void HelloGoodbye()
        {
            this.SayHello();
            this.SayGoodbye();
        }
    }


    public abstract class AbstractClass
    {
        public void SayHello()
        {
            Console.WriteLine("Hello\n");
        }


        //public virtual void SayGoodbye()
        //{
        //    Console.WriteLine("Goodbye\n");
        //}
        public abstract void SayGoodbye();
    }


    public class DerivedClass : BaseClass
    {
        public new void SayHello()
        {
            Console.WriteLine("Hi There");
        }

        public override void SayGoodbye()
        {
            Console.WriteLine("See you later");
        }
    }

    public class DerivedClass2 : AbstractClass
    {
        public new void SayHello()
        {
            Console.WriteLine("Hi There");
        }
        // We should use the override keyword with abstract types
        //public new void SayGoodbye()
        //{
        //    Console.WriteLine("See you later2");
        //}
        public override void SayGoodbye()
        {
            Console.WriteLine("See you later");
        }
    }
}

6

바인딩 은 이름을 코드 단위로 매핑하는 프로세스입니다.

늦은 바인딩 은 이름을 사용하지만 매핑을 연기 함을 의미합니다. 다시 말해, 먼저 이름을 생성 / 멘션하고 일부 후속 프로세스가 해당 이름에 대한 코드 매핑을 처리하도록합니다.

이제 다음을 고려하십시오.

  • 인간과 비교할 때 기계는 검색 및 정렬에 능숙합니다.
  • 기계에 비해 인간은 발명과 혁신에 능숙합니다

따라서 짧은 대답은 다음과 같습니다. virtual기계에 대한 늦은 바인딩 명령입니다 (런타임) abstract. 인간 (프로그래머)에 대한 늦은 바인딩 명령입니다.

즉, 다음을 virtual의미합니다.

런타임 , 최선을 다하여 적절한 코드를이 이름에 바인딩하십시오 : 검색

반면 abstract:

“친애하는 프로그래머 여러분 , 최선을 다하여 최선을 다하여 적절한 코드를이 이름에 바인딩하십시오 : 발명

완전성을 위해 과부하 는 다음을 의미합니다.

컴파일러에게 , 최선의 작업을 수행하여 적절한 코드를이 이름에 바인딩하십시오 : 정렬 ”.


3

상속자가 원하는 경우 기능을 확장하려는 경우 기본적으로 가상 방법을 사용합니다.

상속자가 기능을 구현할 때 추상 메소드를 사용합니다 (이 경우에는 선택 사항이 없습니다).


3

가상 방법 :

  • 가상은 우리가 그것을 무시할 수 있음을 의미합니다.

  • 가상 함수에는 구현이 있습니다. 클래스를 상속하면 가상 함수를 재정의하고 자체 논리를 제공 할 수 있습니다.


  • 자식 클래스 (
    Shadowing 의 개념이라고 할 수 있음)에서 함수를 구현하면서 가상 함수의 반환 유형을 변경할 수 있습니다 .

추상 방법

  • 초록은 반드시 재정의해야 함을 의미합니다.

  • 추상 함수는 구현이 없으며 추상 클래스에 있어야합니다.

  • 선언 만 가능합니다. 이렇게하면 파생 클래스가 해당 클래스의 구현을 제공하게됩니다.

  • 추상 멤버는 암시 적으로 가상입니다. 초록은 일부 언어에서 순수 가상이라고 할 수 있습니다.

    public abstract class BaseClass
    { 
        protected abstract void xAbstractMethod();
    
        public virtual void xVirtualMethod()
        {
            var x = 3 + 4;
        }
    } 
    

2

추상적 인 방법은 다음과 같이 정의되는 곳이 있습니다. **

"추상 메소드는 자식 클래스에서 구현해야합니다"

** 나는 같다고 느꼈다.

자식 클래스가 abstract경우 자식 메서드에서 추상 메서드를 구현할 필요는 없습니다 .

1) 추상적 인 방법은 어차피 개인 방법합니다. 2) 추상 방법 캔트 같은 추상 클래스에서 구현 될 수있다.

.. 추상 클래스를 구현하는 경우 기본 추상 클래스의 추상 메서드를 재정의해야합니다. .. 추상 메소드를 구현하는 것은 대체 키워드로. 가상 메소드 와 유사합니다.

상속 된 클래스에서 가상 메소드를 구현할 필요는 없습니다.

                                 ----------CODE--------------

public abstract class BaseClass
{
    public int MyProperty { get; set; }
    protected abstract void MyAbstractMethod();

    public virtual void MyVirtualMethod()
    {
        var x = 3 + 4;
    }

}
public abstract class myClassA : BaseClass
{
    public int MyProperty { get; set; }
    //not necessary to implement an abstract method if the child class is also abstract.

    protected override void MyAbstractMethod()
    {
        throw new NotImplementedException();
    }
}
public class myClassB : BaseClass
{
    public int MyProperty { get; set; }
    //You must have to implement the abstract method since this class is not an abstract class.

    protected override void MyAbstractMethod()
    {
        throw new NotImplementedException();
    }
}

2

위의 예제 대부분은 코드를 사용하며 매우 좋습니다. 나는 그들이 말하는 것에 덧붙일 필요는 없지만, 다음은 코드 / 기술 용어보다는 유추를 사용하는 간단한 설명입니다.

간단한 설명-유추를 사용한 설명

추상 방법

George W Bush를 생각하십시오. 그는 병사들에게 "이라크에서 싸워라"고 말합니다. 그리고 그게 다야. 그가 지정한 것은 싸움이 반드시 이루어져야한다는 것입니다. 그는 그것이 정확히 어떻게 일어날 지를 명시하지 않았다 . 그러나 나는 당신이 그냥 나가서 싸울 수는 없다는 것을 의미합니다. 그것이 정확히 무엇을 의미합니까? 나는 B-52 또는 내 derringer와 싸울 수 있습니까? 이러한 특정 세부 사항은 다른 사람에게 남아 있습니다. 이것은 추상적 인 방법입니다.

가상 방법

David Petraeus는 군대에서 높은 자리에 있습니다. 그는 싸움의 의미를 정의했습니다.

  1. 적을 찾으십시오
  2. 그를 중립화하십시오.
  3. 나중에 맥주를 마셔

문제는 그것이 매우 일반적인 방법이라는 것입니다. 작동하는 좋은 방법이지만 때로는 구체적이지 않습니다. Petraeus에게 좋은 점은 그의 명령에 여정과 범위가 있다는 것입니다. 그는 특정 요구 사항에 따라 다른 사람들이 "싸움"에 대한 자신의 정의를 변경할 수 있도록 허용했습니다.

Private Job Bloggs는 Petraeus의 명령을 읽고 특정 요구 사항에 따라 자신의 전투 버전을 구현할 수있는 권한을 부여받습니다.

  1. 적을 찾으십시오.
  2. 머리에 쏴
  3. 집에가
  4. 맥주 마셔

누리 알 말리키도 페트라에 우스로부터 동일한 명령을받습니다. 그는 또한 싸워야한다. 그러나 그는 보병이 아닌 정치인입니다. 분명히 그는 머리에 자신의 정치 적을 쏠 수 없습니다. Petraeus는 그에게 가상 방법을 제공했기 때문에 Maliki는 특정 상황에 따라 자신의 버전의 싸움 방법을 구현할 수 있습니다.

  1. 적을 찾으십시오.
  2. BS가 혐의를 받고 체포 됐어
  3. 집에가
  4. 맥주 마셔

다시 말해서, 가상 방법은 상용구 지침을 제공하지만, 이는 일반적인 지침이며, 특정 상황에 따라 군대 계층 구조의 사람들이 더 구체적으로 만들 수 있습니다.

둘의 차이점

  • George Bush는 구현 세부 사항을 증명하지 않습니다. 다른 사람이 제공해야합니다. 이것은 추상적 인 방법입니다.

  • 반면에 페트라 우스는 않습니다 구현 세부 정보를 제공하지만 그는 더 나은 뭔가를 가지고 올 수 있다면, 자신의 버전으로 자신의 명령을 무시하는 자신의 부하 직원에 대한 권한을 부여하고있다.

그것이 도움이되기를 바랍니다.


2

추상 기능 (방법) :

● 추상 메소드는 키워드 abstract로 선언 된 메소드입니다.

● 본체가 없습니다.

● 파생 클래스에서 구현해야합니다.

● 메소드가 추상적이면 클래스가 추상적이어야합니다.

가상 함수 (방법) :

● 가상 메서드는 virtual 키워드로 선언 된 메서드이며 override 키워드를 사용하여 파생 클래스 메서드로 재정의 할 수 있습니다.

● 재정의 여부는 파생 클래스에 달려 있습니다.


1

답은 여러 번 제공되었지만 각각을 언제 사용해야하는지에 대한 질문은 디자인 타임 결정입니다. 일반적인 메소드 정의를 별도의 인터페이스로 묶고 적절한 추상화 레벨의 클래스로 가져 오는 것이 좋은 습관이라고 생각합니다. 일반적인 추상 및 가상 메소드 정의 세트를 클래스에 덤프하면 간결한 인터페이스 세트를 구현하는 비추 상 클래스를 정의하는 것이 가장 좋을 때 클래스를 사용할 수 없게됩니다. 항상 그렇듯이, 그것은 당신의 어플리케이션 특정 요구에 가장 적합한 것에 달려 있습니다.


1

추상 함수 는 본문을 가질 수 없으며 반드시 자식 클래스로 대체되어야합니다.

가상 함수 에는 본문이 있으며 하위 클래스로 대체되거나 대체되지 않을 수 있습니다.


1

일반적인 객체 지향적 관점에서 :

추상 메소드에 관하여 : 부모 클래스에 추상 메소드를 넣을 때 실제로 당신은 자식 클래스에 대해 말하고 있습니다. 그리고 당신이 그것을 사용하려면 자신을 구현해야합니다!

가상 함수 관련 : 부모 클래스에 가상 메소드를 넣을 때 파생 클래스에 말하고 있습니다. 여기서 당신을 위해 무언가를하는 기능이 있습니다. 이것이 유용한 경우 사용하십시오. 그렇지 않다면 이것을 무시하고 코드를 구현하십시오. 심지어 당신의 코드에서 구현을 사용할 수 있습니다!

이것은 일반 OO에서이 두 개념의 차이점에 대한 철학입니다


1

추상 함수는 구현없이 "그냥"서명입니다. 인터페이스에서 클래스 사용 방법을 선언하는 데 사용됩니다. 파생 클래스 중 하나에서 구현되어야합니다.

가상 함수 (실제로 메서드)는 선언하는 함수이며 상속 계층 클래스 중 하나에서 구현해야합니다.

이러한 클래스의 상속 된 인스턴스는 구현하지 않은 경우 하위 계층 클래스에서 구현도 상속합니다.


1

클래스가이 추상 클래스에서 파생 된 경우 추상 멤버를 재정의해야합니다. 이는 멤버를 선택적으로 재정의 할 수 있도록 지정하는 가상 수정 자와 다릅니다.


0

C #에는 가상 클래스를 호출하는 것이 없습니다.

기능

  1. 추상 함수에는 서명 만 있으며 드라이브 클래스는 기능으로 재정의해야합니다.
  2. 가상 기능은 드라이브 클래스가 요구 사항에 따라 기능을 재정의하거나 재정의하지 않을 기능의 일부를 보유합니다.

요구 사항에 따라 결정할 수 있습니다.


0

추상 메소드에는 구현이 없으며 상위 클래스에서 선언됩니다. 자식 클래스는 해당 메소드를 구현할 수 있습니다.

가상 메소드는 상위 클래스에 구현이 있어야하며 하위 클래스가 상위 클래스의 해당 구현을 사용할지 또는 하위 클래스의 해당 메소드에 대한 새 구현을 선택할 수 있도록합니다.


0

C ++ 배경에서 C # 가상은 C ++ 가상에 해당하는 반면 C # 추상 메소드는 C ++ 순수 가상 함수에 해당


0

추상 함수 또는 메소드 는 클래스에 의해 노출되는 공개 "작업 이름"이며, 추상 클래스와 함께 그 목적은 주로 개체가 구현해야하는 구조에 대한 개체 디자인의 제약 조건을 제공합니다.

실제로 추상 클래스에서 상속 된 클래스는이 메소드에 구현을 제공해야합니다. 일반적으로 컴파일러는 그렇지 않은 경우 오류를 발생시킵니다.

클래스를 설계 할 때 구현 세부 사항에 초점을 두어 클래스 구조가 구현과 너무 관련되어 있으므로 클래스 간 종속성 및 결합을 작성하는 경우 클래스와 메소드를 사용하는 것이 중요합니다.

가상 함수 또는 메소드 는 단순히 클래스의 공개 동작을 모델링하는 메소드이지만 상속 클래스에서 클래스를 자유롭게 수정할 수 있습니다. 하위 클래스는 해당 동작에 대한 특정 확장을 구현해야 할 수 있기 때문입니다.

그것들 은 객체 지향 패러다임에서 다원주 의의 형태를 나타냅니다 .

좋은 상속 모델을 지원하기 위해 추상 메소드와 가상 함수를 함께 사용할 수 있습니다.

우리는 솔루션의 주요 객체에 대한 추상 구조를 설계 한 다음, 더 전문화되기 쉬운 위치를 찾아 기본 구현을 작성하고,이를 가상으로 만들고, 결국 기본 구현을 특화하여 상속 된 가상 객체를 "재정의"합니다.


0

여기에 인터페이스, 추상 클래스 및 일반 클래스의 동작을 매우 기본적인 수준으로 볼 수있는 실질적인 예가되기를 희망하는 샘플 코드를 작성하고 있습니다. 데모로 사용하려는 경우 github에서이 코드를 프로젝트로 찾을 수도 있습니다. https://github.com/usavas/JavaAbstractAndInterfaceDemo

public interface ExampleInterface {

//    public void MethodBodyInInterfaceNotPossible(){
//    }
    void MethodInInterface();

}

public abstract class AbstractClass {
    public abstract void AbstractMethod();

    //    public abstract void AbstractMethodWithBodyNotPossible(){
    //
    //    };

    //Standard Method CAN be declared in AbstractClass
    public void StandardMethod(){
        System.out.println("Standard Method in AbstractClass (super) runs");
    }
}

public class ConcreteClass
    extends AbstractClass
    implements ExampleInterface{

    //Abstract Method HAS TO be IMPLEMENTED in child class. Implemented by ConcreteClass
    @Override
    public void AbstractMethod() {
        System.out.println("AbstractMethod overridden runs");
    }

    //Standard Method CAN be OVERRIDDEN.
    @Override
    public void StandardMethod() {
        super.StandardMethod();
        System.out.println("StandardMethod overridden in ConcreteClass runs");
    }

    public void ConcreteMethod(){
        System.out.println("Concrete method runs");
    }

    //A method in interface HAS TO be IMPLEMENTED in implementer class.
    @Override
    public void MethodInInterface() {
        System.out.println("MethodInInterface Implemented by ConcreteClass runs");

    //    Cannot declare abstract method in a concrete class
    //    public abstract void AbstractMethodDeclarationInConcreteClassNotPossible(){
    //
    //    }
    }
}

-4

내 이해에 :

추상 방법 :

추상 클래스 만 추상 메소드를 보유 할 수 있습니다. 또한 파생 클래스는 메서드를 구현해야하며 클래스에는 구현이 제공되지 않습니다.

가상 방법 :

클래스는이를 선언하고 동일한 구현을 제공 할 수 있습니다. 또한 파생 클래스는 메서드를 재정의하기 위해 메서드를 구현해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.