更改 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 以实现安全继承。
我了解私有保护级别旨在阻止任何子级访问私有父变量。
但是没有办法用访问器和修改器(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 以实现安全继承。