更改 child class 中的私有变量

Changing a private variable inside child class

我了解私有保护级别旨在阻止任何子级访问私有父变量。

但是没有办法用访问器和修改器(get 和 set)来做到这一点吗?我必须有某种方法来更改私有字符串,因为那是作业。

我有一个 public 抽象宠物 class,它的名字有一个私有字符串。我想创建一只狗并使用该字符串名称。不过我想不通。由于这是家庭作业,我知道我无法获得代码或任何东西,但是有人可以指出执行此操作的方法以便我可以 google 吗?我所有的搜索都只是暗示这是不可能的。

这是我的代码,如果有帮助的话。

编辑 我不能只保护它。

public abstract class Pet
    {

        private string name;
        private string species;

        public abstract void speak();
        public abstract void play();
        public abstract void info();

    }

部分童犬class...

 class Dog : Pet
    {

        public Dog(string xname, string xspecies)
        {
            this.name = xname; // this is where I'm having trouble.
        }                     

我认为您正在寻找 protected 访问修饰符,这意味着该变量可以在其 class 中访问,并且可以通过派生的 class 实例:

public abstract class Pet
{
    protected string name;
    protected string species;

    public abstract void Speak();
    public abstract void Play();
    public abstract void Info();
}

class Dog : Pet
{
    public Dog(string xname, string xspecies)
    {
        name = xname;
        species = xspecies;
    }

    // Implementation of Pet here
}

让我们确保您有一个清晰准确的理解;许多初学者都被教导了微妙的谎言。

I understand that a private protection level is meant to stop any child accessing private parent variables.

这是对该功能意图的正确总结。基本上你是说 访问控制修饰符用于控制访问 ,这应该不足为奇。

不过,我想在这里指出两个微妙之处。

首先是访问修饰符控制对事物名称的访问,而不是对事物的访问。当您有一个名为 foo 的成员时, 名称 foo 只能用于从 可访问性域 中引用该成员成员。 "accessibility domain" 是一段程序文本;私有成员的可访问域是声明成员的类型的文本

如果您提出了一些其他 方式来引用成员,该机制不受可访问性修饰符 控制。 可访问性修饰符控制的是可以在程序文本中使用名称的地方

确保你头脑清楚。

其次,您注意到 private 成员无法访问 "child",我假设您指的是派生的 class。 有一种情况派生的 class 可以通过名称访问私有成员。 鉴于我到目前为止所说的,您应该能够推断出它是什么。想一想,然后继续阅读。



我说过私有成员只能在声明类型的文本中通过名称访问,所以如果私有成员可以通过派生的名称访问 class,派生的 class 必须在声明类型的文本中:

class Base
{
  private static int x;
  class Derived : Base
  {
      static void M() { Console.WriteLine(Base.x); } 
  }
}

这是合法的,因为 x 在其可访问性域中按名称使用。

那么,你的作业问题是怎么做的呢?只有两种方式:

(1) 把Dog放在Pet里面; any Dog 然后可以访问 Pet 的所有私有成员。这是 C# 的 "for advanced players only" 功能,几乎可以肯定不是您的讲师想要的。但这是一个非常强大的技术,我经常使用它,所以在你以后的职业生涯中记住它;特别是,当您了解 "factory pattern" 时,您可以从口袋里掏出这样的知识:将派生的 classes 放入基础 class 中是制作工厂模式的好技巧工作顺利。

(2) 为私有成员创建一些访问器机制,并使该访问器机制的名称受保护、内部或public.

通常您会使用 属性。在 C# 中使用只读访问器创建 属性,如下所示:

class Base
{
  private int x;
  public int X { get { return x; } }
}

或者,在更现代的 C# 版本中,您可以使用这种缩写形式:

  public int X => x;

现在 Base 之外的代码不能按名称使用 x,因为它在 Base.x 的可访问域之外。但是 X 有一个不受限制的可访问域,所以 可以在任何你喜欢的地方使用。

这是一个只读访问器。要创建写访问器,请添加 setter:

  public int X 
  { 
    get { return x; } 
    set { x = value; } 
  }

请注意 setter 有一个神奇的 value 名称,它是要分配给 属性 的值。

还有其他制作访问器的方法,但这是迄今为止最常见的方法。


在我们查看您的代码时,还有一些其他事情:

(1)

    public abstract void speak();
    public abstract void play();
    public abstract void info();

Public 方法在 C# 中应该是 PascalCasedLikeThis,而不是 lowercase。这只是一种任意约定,可以让您更轻松地阅读您的代码。

(2)

为什么返回 info void?肯定应该 返回一些信息 .

(3)

 class Dog : Pet

你打算进一步分classDog吗?可能不是,因为它不是abstract。考虑将 class 不打算被子 class 标记为 sealed,这样您就不必担心设计 class 以实现安全继承。