我知道私有保护级别旨在阻止任何孩子访问私有父变量。
但是没有办法使用访问器和修改器(获取并设置)吗?我必须采用某种方式来更改私有字符串,因为这是家庭作业。
我有一个公共抽象宠物课,其中有一个私有字符串来命名。我想创建一条狗并使用该字符串名称。不过我不知道。既然是家庭作业,我知道我无法获得代码或其他任何信息,但是有人可以指出执行此操作的方法,以便我可以在Google上搜索吗?我所有的搜索都暗示这是不可能的。
这是我的代码,如果有帮助的话。
修改 我不能只是保护它。
public abstract class Pet
{
private string name;
private string species;
public abstract void speak();
public abstract void play();
public abstract void info();
}
部分幼犬课程...
class Dog : Pet
{
public Dog(string xname, string xspecies)
{
this.name = xname; // this is where I'm having trouble.
}
答案 0 :(得分:5)
让我们确保您具有清晰准确的理解;许多初学者被教会了一些微妙的错误。
我知道私有保护级别旨在阻止任何孩子访问私有父变量。
这是功能意图的正确摘要。基本上,您是说访问控制修饰符用于控制访问,这不足为奇。
但是,我想在这里指出两个细微之处。
首先,访问修饰符控制对事物名称的访问,而不是对事物的访问。当您有一个名为foo
的成员时,名称foo
只能用于从该成员的可访问性域中引用该成员 。 “可访问性域”是程序文本的区域;私有成员的可访问域是声明成员的类型的文本。
如果您想出某种 other 方式来引用成员,则该机制不受辅助功能修饰符的控制。可访问性修饰符控制的唯一内容是,其中名称可以在程序文本中使用。
确保头脑清晰。
第二,您注意到private
成员不可被“子”访问,我假设您的意思是派生类。 在某些情况下,派生类可以按名称访问私有成员。鉴于我到目前为止所说的,您应该能够推断出它是什么。思考一下,然后继续阅读。
我说过,私有成员只能通过声明类型的文本内的名称进行访问,因此,如果私有成员可以通过派生类的名称进行访问,则派生类必须位于声明文本的内部输入:
class Base
{
private static int x;
class Derived : Base
{
static void M() { Console.WriteLine(Base.x); }
}
}
这是合法的,因为x
在其可访问性域内按名称使用。
那么,您如何处理家庭作业问题?只有两种方法:
(1)将Dog
放在Pet
里面;任何Dog
都可以访问Pet
的所有私有成员。这是C#的“仅适用于高级玩家”功能,几乎可以肯定不是您的教练正在寻找的功能。但这是一项非常强大的技术,我会经常使用,因此在以后的工作中要牢记这一点;尤其是,当您了解“工厂模式”时,您可以从口袋里掏出一些知识,即将派生类放入基类中是使工厂模式正常工作的好技巧。
(2)为私有成员建立一些访问器机制,并使该访问器机制的名称受保护,内部或公开。
通常,您会使用属性。您可以使用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; }
}
请注意,设置员具有神奇的value
名称,这是将分配给该属性的值。
还有其他方法来创建访问器,但这是迄今为止最常见的方法。
在查看您的代码时,还有其他几件事:
(1)
public abstract void speak();
public abstract void play();
public abstract void info();
在C#中,公开方法应为PascalCasedLikeThis
,而不是lowercase
。这只是一个任意约定,使您更容易阅读代码。
(2)
为什么info
无效返回?当然应该返回一些信息。
(3)
class Dog : Pet
您打算进一步继承Dog
的子类吗?可能不是,因为它不是abstract
。考虑将不打算将其子类标记为sealed
的类,这样您就不必担心为安全继承而设计该类。
答案 1 :(得分:2)
我认为您正在寻找protected
访问修饰符,这意味着该变量可以在其类 和派生类实例 中访问:>
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
}