문제

공통 기능을 위해 기본 클래스에서 상속 받기를 원하는 여러 클래스가있는 경우 클래스 나 추상 클래스를 사용하여 기본 클래스를 구현해야합니까?

도움이 되었습니까?

해결책

그것은 당신이 기본 클래스를 인스턴스화하고 싶지 않다면, 그것을 추상적으로 만드십시오. 그렇지 않으면 정상적인 클래스로 두십시오.

다른 팁

기본 클래스가 인스턴스화되지 않아야한다면 추상 클래스로 만드십시오. 기본 클래스를 인스턴스화해야한다면 추상적으로 만들지 마십시오.

이 예에서는 기본 클래스에 구체적인 의미가 없으므로 기본 클래스를 추상화하는 것이 합리적입니다.

abstract class WritingImplement
{
    public abstract void Write();
}

class Pencil : WritingImplement
{
    public override void Write() { }
}

그러나이 다음 예에서는 기본 클래스가 어떻게 구체적인 의미를 갖는지 알 수 있습니다.

class Dog
{
    public virtual void Bark() { }
}

class GoldenRetriever : Dog
{
    public override void Bark() { }
}

그것은 모두 꽤 주관적입니다. 특정 영역의 요구에 따라 꽤 좋은 판단을 내릴 수 있어야합니다.

문제의 기본 클래스가 파생되지 않고 자체적으로 존재하는 것이 합리적입니까? 대답이 예라면 정규 수업이어야합니다. 그렇지 않으면 추상 클래스 여야합니다.

제안 :

  • 인터페이스를 만드십시오.
  • 기본 클래스에서 인터페이스를 구현하십시오.
  • 기본 클래스를 초록이 아닌 실제 클래스로 만드십시오 (이유는 아래 참조).

추상 클래스 대신 실제 클래스를 선호하는 이유는 추상 클래스를 인스턴스화 할 수 없으므로 향후 옵션을 제한하기 때문입니다. 불필요하게. 예를 들어, 나중에 나는 기본 클래스가 제공 한 상태와 방법이 필요할 수 있지만 상속 할 수 없으며 인터페이스를 구현할 필요가 없습니다. 기본 클래스가 추상적 인 경우 운이 좋지 않지만 기본 클래스가 일반 클래스라면 기본 클래스의 인스턴스를 만들어 다른 클래스의 구성 요소로 유지하고 인스턴스를 재사용 할 수 있습니다. 제공된 상태/방법.

그렇습니다. 이것은 자주 발생하지 않지만 요점은 다음과 같습니다. 기본 클래스를 추상화하면 이유가 없을 때 이런 종류의 재사용/솔루션을 방지합니다.

이제 기본 클래스를 인스턴스화하는 것이 어떻게 든 위험 할 것이라면, 그것을 추상적으로 만들거나, 가능하다면 덜 위험하게 만드십시오. ;-)

은행 계좌처럼 생각하십시오.

"계정"이라는 일반적인 추상 기본 계정을 만들 수 있습니다. 이는 고객 세부 정보와 같은 기본 정보를 보유합니다.

그런 다음 "SavingAccount"또는 "DebitAccount"라는 두 개의 파생 클래스를 만들 수 있으며, 이는 기본 클래스 동작의 혜택을받는 동안 고유 한 특정 동작을 가질 수 있습니다.

이는 고객이 저축 계좌 또는 직불 계좌를 가져야하는 상황이며, 일반 "계정"은 실제 세계에서 설명이없는 계정을 가지고 있지 않기 때문에 허용되지 않습니다.

필요에 대해 유사한 시나리오를 만들 수 있다면 초록이 갈 길입니다.

초록 클래스는 부분적으로 구현 된 클래스를위한 것입니다.

그 자체로는 추상 클래스의 인스턴스를 갖는 것이 합리적이지 않으므로 파생되어야합니다. 기본 클래스를 만들 수 있기를 원한다면 추상적 일 수 없습니다.

나는 추상 클래스를 모든 하위 클래스에 공통적이기 때문에 일부 회원이 미리 정의 된 인터페이스로 생각하고 싶습니다.

이것을 다른 방식으로 생각하십시오

내 기본 클래스가 자신의 완전한 개체입니까?

대답이 아니오라면 추상적으로 만드십시오. 그렇다면 구체적인 클래스로 만들고 싶을 것입니다.

기본 클래스를 자체적으로 호출 할 계획이 없다면 추상 클래스로 정의해야합니다.

기본 클래스가 자체적으로 구현되기를 원하는지 여부에 따라 다릅니다.

추상적 인 클래스로서, 당신은 그것으로부터 객체를 만들 수 없습니다.

예를 들어 초록 클래스는 사전 정의 된 기능에 적합합니다. 예를 들어, 클래스가 노출되어야하는 최소한의 정확한 동작을 알고 있지만 수행하는 데 사용해야하는 데이터 또는 정확한 구현이 아닙니다.

abstract class ADataAccess
{
    abstract public void Save();
}

정상 (비 초록) 클래스는 비슷한 것들에 좋을 수 있지만 구현 세부 사항을 알아야합니다.

public class DataAccess
{
    public void Save()
    {
        if ( _is_new )
        {
            Insert();
        }
        else if ( _is_modified )
        {
            Update();
        }
    }
}

또한 인터페이스 (개별 또는 클래스에서 추상적이든 아니든)를 사용하여 동일한 종류의 프로토 타입 정의를 정의 할 수 있습니다.

interface ISaveable
{
    void Save();
    void Insert();
    void Update();
}

class UserAccount : ISavable
{
    void ISavable.Save() { ... }
    void ISavable.Insert() { ... }
    void ISavable.Update() { ... }
}

또 다른 옵션은 제네릭을 사용하는 것일 수 있습니다

class GenDataAccess<T>
{
    public void Save()
    {
        ...
    }
}

이 모든 방법을 사용하여 클래스와 함께 작업 할 특정 프로토 타입을 정의 할 수 있습니다. 코드 A가 코드 B와 대화 할 수 있는지 확인하는 방법. 물론 위의 모든 것을 원하는 것과 혼합하고 일치시킬 수 있습니다. 명확한 올바른 방법은 없지만 인터페이스와 추상 클래스를 정의한 다음 인터페이스를 참조하는 것을 좋아합니다. 이렇게하면 최대의 유연성을 유지하면서 더 높은 수준의 클래스에서 "배관"에 대한 사고 요구 사항 중 일부가 제거됩니다. (인터페이스를 갖는 것은 추상 기본 클래스를 사용해야하는 요구 사항을 없애지 만 옵션으로 남겨 둡니다).

많은 사람들이 기본 OO 수업을 다시 해결해야한다고 생각합니다.

OOA/OOD의 기본 기본 원리는 더 이상 추상적이지 않을 때까지 초록 초록을 추상적으로하는 것입니다. 당신이 보는 것이 추상화라면, 그렇게하십시오. 그것이 당신의 ooa/ood가 이미 당신에게 말한 것입니다. 그러나 "코드"가 추상적인지 아닌지 궁금해하는 경우, 그 용어가 무엇을 의미하는지 알지 못하고 기본 OOA/OOD/OOP를 다시 배우게됩니다 :-)

디자인 패턴과 고조파 이론을 배워야 할 때까지, 이것은 OO 디자인에 엄청나게 도움이 될 것입니다!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top