为什么虚拟元素必须是公共的并且可以';在C#中不受保护?

为什么虚拟元素必须是公共的并且可以';在C#中不受保护?,c#,overriding,virtual,public,protected,C#,Overriding,Virtual,Public,Protected,我是C#的新手,目前正在学习OOP。我正在努力学习所有这些关键字是如何工作的。我现在正在学习虚拟关键词,我上了这门课: // Animal class public class Animal { // Class propreties public string name { get; set; } public int age { get; set; } public double happiness {

我是C#的新手,目前正在学习OOP。我正在努力学习所有这些关键字是如何工作的。我现在正在学习虚拟关键词,我上了这门课:

    // Animal class
    public class Animal
    {
        // Class propreties
        public string name { get; set; }
        public int age { get; set; }
        public double happiness { get; set; }

        public static int AnimalCounter = 0;

        // Class constructor
        public Animal(string name_ = "Spotty", int age_ = 4, double happiness_ = 3)
        {
            this.name = name_;
            this.age = age_;
            this.happiness = happiness_;
        } 

        // Virtual methods
        public virtual void Print() { }
        public virtual void Woof () { }
        public virtual void Meow () { }
    }
我不明白的是,当我使用virtual时,为什么不能写protected而不是public。 例如在

public virtual void Print() {}
当我写作时,它给了我一个错误

protected virtual void Print() {}
据我所知,protected意味着只能在基类和所有其他由基类生成的类中访问属性

所以我有了一个新的类:,它是由基础动物

//狗类
公营狗:动物
{
/*类专有*/
受保护的双点计数{get;set;}
受保护的双纬快乐增加{get;set;}
//SpotCount=>get和set//get返回SpotCount//set 20(如果大于或等于20)。如果小于或等于0,则设置0。否则,将其设置为给定值
公众双点计数
{
得到
{
返回SpotCount;
}
设置
{
如果(值>=20)
{
点计数=20;
}
else if(值get和set//get返回woof_happines如果大于或等于100,则增加//设置100。如果小于或等于0,则设置0。否则,将其设置为给定值
公众双纬快乐增加
{
得到
{
回报你,快乐增加;
}
设置
{
如果(值>=100)
{
追求幸福增加=100;
}

else if(value公共虚拟方法应该没有问题

确保基本方法是
public virtual
,并且扩展类(覆盖该方法)将其标记为
public virtual

公共类动物
{
公共虚拟空打印(){}
}
公猫:动物
{
public override void Print(){Console.WriteLine(“喵”);}
}
这是不受支持的:

公共类动物
{
受保护的虚拟空打印(){}
}
公猫:动物
{
public override void Print(){Console.WriteLine(“Meow”);}//Base受保护,因此这没有意义。
}

Q:你能用编译错误更新你的帖子吗?你必须使覆盖也受到保护,它告诉你不能更改访问修饰符(public、protected、private)。如果
Print
受保护,则无法在子类上公开它,因为您正试图更改基类定义的约定。如果基类说某个内容是公开的,则它必须在派生类中公开。您可以执行
protected virtual
操作,但基类也必须将该字段设置为
protected
。如果我在基类中将
Print()
Woof()
Meow()
更改为
protectedvirtualvoid
,在派生类中将
protectedoverride void
更改为
关键字派生类应该使用
覆盖
,除非您想隐藏父实现,在这种情况下,它应该使用
新建
。您不能使用覆盖来更改父实现的访问级别,这正是他试图做的。。
// Dog class
    public class Dog : Animal
    {
        /* Class Propreties */
        protected double SpotCount_ { get; set; }
        protected double woof_happinessIncrease_ { get; set; }

        // SpotCount = > get and set // GET returns SpotCount // SET 20 if bigger or equal to 20 . SET 0 if less or equal to 0 . otherwise set it to the given value
        public double SpotCount
        {
            get
            {
                return SpotCount_;
            }
            set
            {
                if(value >= 20)
                {
                    SpotCount_ = 20;
                }
                else if(value <= 0)
                {
                    SpotCount_ = 0;
                }
                else
                {
                    SpotCount_ = value;
                }
            }
        }
        // woof_happinessIncrease = > get and set // GET returns woof_happinessIncrease // SET 100 if bigger or equal to 100. SET 0 if less or equal to 0 . otherwise set it to the given value
        public double woof_happinessIncrease
        {
            get
            {
                return woof_happinessIncrease_;
            }
            set
            {
                if(value >= 100)
                {
                    woof_happinessIncrease_ = 100;
                }
                else if(value <= 0)
                {
                    woof_happinessIncrease_ = 0;    
                }
                else
                {
                    woof_happinessIncrease_ = value;
                }
            }
        }

        /* Class Constructor */
        public Dog(string name_ = "Spotty", int age_ = 4, double happiness_ = 3, double SpotCount_=3, double woof_happinessIncrease_=2) : base(name_, age_, happiness_)
        {
            this.SpotCount_ = SpotCount_;
            this.woof_happinessIncrease = woof_happinessIncrease_;
        }

        /* Class Override Methods */
        public override void Print()
        {
            Console.WriteLine(String.Format("Name : {0}", this.name.ToString()));
            Console.WriteLine(String.Format("Age : {0}", this.age.ToString()));
            Console.WriteLine(String.Format("Happiness : {0}", this.happiness.ToString()));
            Console.WriteLine(String.Format("Spot count : {0}", this.SpotCount.ToString()));

            Animal.AnimalCounter++; // Increase the animal counter size by 1 every time we have a new instance of the class Dog.
        }
        public override void Woof()
        {
            // Woof and increase happiness
            this.happiness += woof_happinessIncrease;
            Console.WriteLine(String.Format("{0} woofed. His happiness increased by {1}. His happiness now is : {2}", this.name.ToString(), this.woof_happinessIncrease.ToString(), this.happiness.ToString()));
        }
    }