문제

가 추상적인 기본 클래스고 싶을 선언하는 분야 또는 속성이 있는 것에서 다른 값을 상속받는 각 클래스에서는 이 부모 클래스입니다.

나는 그것을 정의에서 공공 무 그래서 내가 참조할 수 있습니다 그것은 기본 클래스에서 방법을 예를 들어 재정의 ToString"말하는 이 물체의 형식 제공/드".내가 세 가지 방법으로는 볼 수 있습니다 이 일을 하지만,나는가 무엇인지 가장 또는 받아들의 방식이었는지 설명하려고 노력합니다.초보자 문제,죄송합니다.

옵션 1:
사용상 속성 및 대체에서 상속되는 클래스입니다.이 혜택에 적용되고 있는(당신은 그것을 무시)및 그것은 깨끗합니다.하지만,그것은 느낌이 약간 잘못을 반환하는 하드 값보다는 캡슐화 분야 그리고 몇 줄의 코드 대신니다.나는 또한 선언을 위한 몸"설정"그러나는 덜 중요한(그리고 아마을 방지하는 방법을 내가 알지 못).

abstract class Father
{
    abstract public int MyInt { get; set;}
}

class Son : Father
{
    public override int MyInt
    {
        get { return 1; }
        set { }
    }
}

옵션 2
나는 선언할 수 있다 공용 분야(이나 보호된 필드)그리고 명시적으로 재정의 그것에는 상속받은 클래스.아래 예에게 경고를 사용하"새로운"나는 아마 그렇지만,그것은 잘못된 느낌이 끊고 다형성되었습니다.보이지 않는 좋은 생각처럼...

abstract class Mother
{
    public int MyInt = 0;
}

class Daughter : Mother
{
    public int MyInt = 1;
}

옵션 3
내가 사용할 수있는 보호된 필드 값을 설정에서 생성자입니다.이 아주 깔끔하지만 의존하는 나에게 생성자를 항상이고 여러 오버로드 생성자를 기회는 항상있다 일부 코드의 경로를 설정하지 않습니다.

abstract class Aunt
{
    protected int MyInt;
}

class Niece : Aunt
{
    public Niece()
    {
        MyInt = 1;
    }
}

그것은 약간의 이론적인 질문에 대답을 추측을 수 있는 옵션 1 로 안전 옵션이 있지만 나는 그냥 그립 C#고 물어보고 싶은 이 사람의 더 많은 경험을 가진.

도움이 되었습니까?

해결책

세 가지 솔루션 중 하나 옵션 1 ~이다 다형성.

그 자체로 필드는 무시할 수 없습니다. 그것이 바로 그 이유입니다 옵션 2 반환합니다 새로운 키워드 경고.

경고에 대한 해결책은 "새로운"키워드를 추가하는 것이 아니라 옵션 1을 구현하는 것입니다.

당신이 당신의 분야가 다형성이 필요한 경우, 당신은 그것을 속성에 랩핑해야합니다.

옵션 3 다형성 행동이 필요하지 않으면 괜찮습니다. 그러나 런타임에 속성에 액세스 할 때 파생 클래스는 반환 된 값을 제어 할 수 없음을 기억해야합니다. 기본 클래스 자체는이 값을 반환 할 수 있습니다.

이것이 귀하의 재산의 진정한 다형성 구현이 어떻게 보이는가이며, 파생 클래스가 제어.

abstract class Parent
{
    abstract public int MyInt { get; }
}

class Father : Parent
{
    public override int MyInt
    {
        get { /* Apply formula "X" and return a value */ }
    }
}

class Mother : Parent
{
    public override int MyInt
    {
        get { /* Apply formula "Y" and return a value */ }
    }
}

다른 팁

옵션 2는 스타터가 아닌 것입니다 우세하다 필드, 당신은 만 할 수 있습니다 숨다 그들을.

개인적으로, 나는 매번 옵션 1을 먹을 것입니다. 나는 항상 필드를 비공개로 유지하려고 노력합니다. 물론 재산을 전혀 무시할 수 있어야합니다. 다른 옵션은 생성자 매개 변수에서 설정된 기본 클래스에 읽기 전용 속성을 갖는 것입니다.

abstract class Mother
{
    private readonly int myInt;
    public int MyInt { get { return myInt; } }

    protected Mother(int myInt)
    {
        this.myInt = myInt;
    }
}

class Daughter : Mother
{
    public Daughter() : base(1)
    {
    }
}

값이 인스턴스의 수명 동안 변경되지 않으면 아마도 가장 적절한 접근법 일 것입니다.

옵션 2는 나쁜 생각입니다. 그것은 그림자라고 불리는 것을 초래할 것입니다. 기본적으로 당신은 두 개의 다른 "myint"멤버, 하나는 어머니에, 다른 하나는 딸에 있습니다. 이것의 문제점은 어머니에게 구현되는 방법은 어머니의 "myint"를 참조하는 반면 딸에 구현 된 방법은 딸의 "myint"를 참조한다는 것입니다. 이로 인해 심각한 가독성 문제가 발생하고 나중에 혼란스러워 할 수 있습니다.

개인적으로, 나는 최선의 선택은 3이라고 생각합니다. 명확한 중앙 집중식 값을 제공하고 자신의 필드를 정의하는 번거 로움없이 어린이가 내부적으로 참조 할 수 있기 때문에 옵션 1의 문제입니다.

다음과 같은 것을 정의 할 수 있습니다.

abstract class Father
{
    //Do you need it public?
    protected readonly int MyInt;
}

class Son : Father
{
    public Son()
    {
        MyInt = 1;
    }
}

값을 Readonly로 설정함으로써 해당 클래스의 값이 객체의 수명 동안 변경되지 않도록합니다.

다음 질문은 다음과 같습니다. 왜 필요한가요?

당신은 이것을 할 수 있습니다

class x
{
    private int _myInt;
    public virtual int myInt { get { return _myInt; } set { _myInt = value; } }
}

class y : x
{
    private int _myYInt;
    public override int myInt { get { return _myYInt; } set { _myYInt = value; } }
}

가상을 사용하면 무언가를 수행하고 하위 클래스가이를 무시할 수있는 신체에 속성을 얻을 수 있습니다.

수업을 구축하고 속성에 대한 기본 가치가 있기를 원한다면 virtual 기본 클래스의 키워드. 이를 통해 선택적으로 속성을 무시할 수 있습니다.

위의 예제 사용 :

//you may want to also use interfaces.
interface IFather
{
    int MyInt { get; set; }
}


public class Father : IFather
{
    //defaulting the value of this property to 1
    private int myInt = 1;

    public virtual int MyInt
    {
        get { return myInt; }
        set { myInt = value; }
    }
}

public class Son : Father
{
    public override int MyInt
    {
        get {

            //demonstrating that you can access base.properties
            //this will return 1 from the base class
            int baseInt = base.MyInt;

            //add 1 and return new value
            return baseInt + 1;
        }
        set
        {
            //sets the value of the property
            base.MyInt = value;
        }
    }
}

프로그램에서 :

Son son = new Son();
//son.MyInt will equal 2

나는 옵션 3과 함께 갈 것이지만 서브 클래스가 구현 해야하는 추상적 인 setmyint 방법이 있습니다. 이렇게하면 생성자에 설정하는 것을 잊어 버린 파생 클래스의 문제가 없습니다.

abstract class Base 
{
 protected int myInt;
 protected abstract void setMyInt();
}

class Derived : Base 
{
 override protected void setMyInt()
 {
   myInt = 3;
 }
}

그건 그렇고, 옵션 1과 함께 세트를 지정하지 않는 경우; 추상 기본 클래스 속성에서 파생 클래스는이를 구현할 필요가 없습니다.

abstract class Father
{
    abstract public int MyInt { get; }
}

class Son : Father
{
    public override int MyInt
    {
        get { return 1; }
    }
}

당신이 갈 수있는 옵션과 함께 3 를 수정하는 경우 추상적인 기본 클래스를 필요로 제공 가치 생성자에서,당신은 당신이 놓치지 않고 어떤 경로입니다.나는 정말 이 옵션을 고려하십시오.

abstract class Aunt
{
    protected int MyInt;
    protected Aunt(int myInt)
    {
        MyInt = myInt;
    }

}

물론 당신은 여전히 할 수있는 옵션의 분야를 만드는 개인 그리고,필요에 따라 노출 보호 또는 공공의 재산 getter.

난 이걸했다...

namespace Core.Text.Menus
{
    public abstract class AbstractBaseClass
    {
        public string SELECT_MODEL;
        public string BROWSE_RECORDS;
        public string SETUP;
    }
}

namespace Core.Text.Menus
{
    public class English : AbstractBaseClass
    {
        public English()
        {
            base.SELECT_MODEL = "Select Model";
            base.BROWSE_RECORDS = "Browse Measurements";
            base.SETUP = "Setup Instrument";
        }
    }
}

이렇게하면 여전히 필드를 사용할 수 있습니다.

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