Почему я должен использовать защищенные переменные (члены / свойства) с наследованием?Каковы преимущества его использования? - PullRequest
2 голосов
/ 03 октября 2011

Я просматривал примеры кода Начиная с C # 3.0 и следовал примеру кода вместе.

Когда я создал публичный / защищенный метод, я смог получить доступ к этому методу, используяобъект производного класса.Пример:

class clsBuilding
    {
    protected string address { get; set; }
    protected Decimal purchasePrice { get; set; }
    protected decimal monthlyPayment { get; set; }
    protected Decimal taxes { get; set; }
    protected decimal insurance { get; set; }
    protected DateTime datePurchased { get; set; }
    protected int buildingType { get; set; }


     public void PropertySummary(string[] desc)
        {
            desc[0] = "Property Type:  "+whichType[buildingType] +
                        "," + address +
                        ",Cost: " + purchasePrice.ToString("C")+
                        ", Monthly Payment:" + monthlyPayment.ToString("C");
            desc[1] = "Insurance: " + insurance.ToString("C") +
                        " Taxes:  " + taxes.ToString("C")+
                            "Date Purchased: " + datePurchased.ToShortDateString();
            desc[2] = "";
        }
..............
}

class clsApartment : clsBuilding
    {
      ........................
}
.......
myApt = new clsApartment();

myApt.PropertySummary(desc);

Но что такое использование защищенного свойства, которое я объявил в начале родительского класса.Когда я пытался получить к ним доступ, используя объект производного класса или напрямую, как указано в книге:

Просто для того, чтобы привести точку домой, указав строку в clsBuilding (родительский класс):

protected decimal purchase price;

у вас может быть строка:

вы можете иметь строку buyprice = 150000M;в классе дома, и это было бы вполне приемлемо.(Глава 15, стр. 447 после 4-го абзаца), ни одна из них не была успешной при попытке.

Я уверен, что, должно быть, я неправильно понял концепцию или что-то упустил.Если нет, то почему кто-либо может объявить защищенную переменную или свойство?

РЕДАКТИРОВАТЬ:

public class clsBuilding
{
    //--------------------- Symbolic constants -------------------
    public const int APARTMENT = 1;
    public const int COMMERCIAL = 2;
    public const int HOME = 3;

    private string[] whichType = { "", "Apartment", "Commercial", "Home" };

    //--------------------- Instance variables -------------------
    protected string address;
    protected decimal purchasePrice;
    protected decimal monthlyPayment;
    protected decimal taxes;
    protected decimal insurance;
    protected DateTime datePurchased;
    protected int buildingType;
    //--------------------- Constructor --------------------------
    public clsBuilding()
    {
        address = "Not closed yet";
    }

    public clsBuilding(string addr, decimal price, decimal payment,
                       decimal tax, decimal insur, DateTime date, int type):this()
    {
        if (addr.Equals("") == false)
            address = addr;
        purchasePrice = price;
        monthlyPayment = payment;
        taxes = tax;
        insurance = insur;
        datePurchased = date;
        buildingType = type;
    }
    //--------------------- Property Methods ---------------------

    public string Address
    {
        get
        {
            return address;
        }
        set
        {
            if (value.Length != 0)
                address = value;
        }
    }
    public decimal PurchasePrice
    {
        get
        {
            return purchasePrice;
        }
        set
        {
            if (value > 0M)
                purchasePrice = value;
        }
    }

    public decimal MonthlyPayment
    {
        get
        {
            return monthlyPayment;
        }
        set
        {
            if (value > 0M)
                monthlyPayment = value;
        }
    }

    public decimal Taxes
    {
        get
        {
            return taxes;
        }
        set
        {
            if (value > 0M)
                taxes = value;
        }
    }

    public decimal Insurance
    {
        get
        {
            return insurance;
        }
        set
        {
            if (value > 0M)
                insurance = value;
        }
    }

    public DateTime DatePurchased
    {
        get
        {
            return datePurchased;
        }
        set
        {
            if (value.Year > 2008)
                datePurchased = value;
        }
    }

    public int BuildingType
    {
        get
        {
            return buildingType;
        }
        set
        {
            if (value >= APARTMENT && value <= HOME)
                buildingType = value;
        }
    }
    //--------------------- General Methods ----------------------

    /*****
     * Purpose: Provide a basic description of the property
     * 
     * Parameter list:
     *  string[] desc       a string array to hold description
     *  
     * Return value:
     *  void
     *  
     * CAUTION: Method assumes that there are 3 elements in array
     ******/
    public void PropertySummary(string[] desc)
    {

        desc[0] = "Property type: " + whichType[buildingType] + 
                  ", " + address + 
                  ", Cost: " + purchasePrice.ToString("C") + 
                  ", Monthly payment: " + monthlyPayment.ToString("C");
        desc[1] = "     Insurance: " + insurance.ToString("C") + " Taxes: " + taxes.ToString("C") + 
                  "  Date purchased: " + datePurchased.ToShortDateString();
        desc[2] = " ";
    }

    /*****
     * Purpose: To call someone for snow removal, if available
     * 
     * Parameter list:
     *  n/a
     *  
     * Return value:
     *  string
     ******/
    public virtual string RemoveSnow()
    {
        return whichType[buildingType] + ": No snow removal service available.";
    }
}

class clsCommercial : clsBuilding
{
    //--------------------- Instance variables -------------------
    private int squareFeet;
    private int parkingSpaces;
    private decimal rentPerSquareFoot;

    //--------------------- Constructor --------------------------
    public clsCommercial(string addr, decimal price, decimal payment,
                        decimal tax, decimal insur, DateTime date, int type) :
                        base(addr, price, payment, tax, insur, date, type)
    {
        buildingType = type;   // Commercial type from base
    }
    //--------------------- Property Methods ---------------------
    public int SquareFeet
    {
        get
        {
            return squareFeet;
        }
        set
        {
            if (value > 0)
                squareFeet = value;
        }
    }
    public int ParkingSpaces
    {
        get
        {
            return parkingSpaces;
        }
        set
        {
            parkingSpaces = value;
        }
    }
    public decimal RentPerSquareFoot
    {
        get
        {
            return rentPerSquareFoot;
        }
        set
        {
            if (value > 0M)
                rentPerSquareFoot = value;
        }
    }

    //--------------------- General Methods ----------------------
    public override string RemoveSnow()
    {
        return "Commercial: Call Acme Snow Plowing: 803.234.5566";
    }

}


public frmMain()
    {
        InitializeComponent();
        myTime = DateTime.Now;

        myApt = new clsApartment("123 Ann Dotson Dr., Lexington, KY 40502", 550000, 6000,
                                             15000, 3400, myTime, 1);
        myComm = new clsCommercial("4442 Parker Place, York, SC 29745", 1200000, 9000,
                                        22000, 8000, myTime, 2);
        myHome = new clsHome("657 Dallas St, Ringgold, GA 30736", 260000, 1100,
                                    1750, 900, myTime, 3);
    }

Ответы [ 3 ]

7 голосов
/ 03 октября 2011

Защищенная переменная / свойство доступно из класса, к которому относятся производные классы, если я правильно помню.

Обычно вы используете его, чтобы предотвратить общедоступность свойства другим классам, которые не наследуются от вашего класса.

2 голосов
/ 03 октября 2011

Защищенные участники могут получить доступ к другим членам класса так же, как частные члены. Защищенные члены также могут быть доступны членам производных классов. Это единственное различие между частным и защищенным.

В этом случае автор clsBuilding намеревался сделать защищенные свойства доступными для любых производных классов. Это не особенно хороший пример без конкретной демонстрации производного класса. Возможно, детали clsApartment, которые вы пропустили, содержат эту демонстрацию - я, безусловно, надеюсь, что это так.


Вот искусственный пример ситуации, когда вы можете использовать защищенный.

abstract class Preference
{
    protected abstract void Load();
    protected abstract void Save();

    public Preference()
    {
        Load();
    }

    ~Preference()
    {
        Save();
    }
}

class IntPreference : Preference
{
    protected override void Load()
    {
        //load from registry or config file
    }

    protected override void Save()
    {
        //save to registry or config file
    }

    public int Value { get; set; }
}

class StringPreference : Preference
{
    ...
}

class FloatPreference : Preference
{
    ...
}

Защищая методы Load и Save, мы можем быть уверены, что они не вызываются извне класса Preference или одного из его потомков. Но мы можем вызывать Load и Save из базового класса и при этом иметь фактические реализации, предоставляемые производными классами, которые знают, как обрабатывать персистентность.

Надеюсь, вы уже рассмотрели виртуальные методы!

1 голос
/ 03 октября 2011

Опираясь на то, что сказал Даг.Защищенный делает свойство, переменную или функцию доступными для подкласса, но не снаружи класса.Если бы вы использовали private, он все равно не был бы доступен извне класса и не был бы доступен из его подклассов.

...