为什么我应该使用带继承的受保护变量(成员/属性)?使用它有什么好处?

Sim*_*ons 3 .net c# oop inheritance c#-3.0

我正在浏览Begining 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);
Run Code Online (Sandbox Code Playgroud)

但是我在父类的开头声明了保护属性的用途是什么.当我试图通过使用派生类的对象或直接按照书中的指示访问它们时:

只是为了驱动点回家,在clsBuilding(父类)中给出一行:

protected decimal purchase price;
Run Code Online (Sandbox Code Playgroud)

你可以拥有这条线:

你可以买lineprice = 150000M; 在家里,它是完全可以接受的.(第4章,第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);
    }
Run Code Online (Sandbox Code Playgroud)

dou*_*ald 8

如果我没记错的话,可以从类的派生类访问受保护的变量/属性.

通常,您将使用一个来阻止该属性可以公开访问其他不从您的类继承的类.


Dar*_*g8r 2

以道格所说的为基础。Protected 使属性、变量或函数可供子类使用,但不能从类外部使用。如果您要使用 private,则仍然无法从类外部访问它,也无法从其子类访问它。