C# 如何为子级定义访问器?

C# 如何为子级定义访问器?,c#,oop,inheritance,C#,Oop,Inheritance,我有三门课: public interface IParent { String World { get; } } public class Parent : IParent { public String World; { get { return "Hello " + this.World; } } } public class Children : Parent { publ

我有三门课:

public interface IParent
{
    String World { get; }
}

public class Parent : IParent
{
    public String World;
    {
        get
        {
            return "Hello " + this.World;
        }
    }
}

public class Children : Parent
{
    public String World = "World";
}

如何使用
子项的
World
属性调用
父项的get访问器?

这是从后面到前面的

如果需要,继承类将包含重写的基类行为。子类
覆盖了基类行为,但是通过
base
关键字有一个基类的钩子

因此:

public interface IParent
{
    String World { get; }
}

public class Parent : IParent
{
    public virtual String World
    {
        get
        {
            return "Hello";
        }
    }
}

public class Children : Parent
{
    public override String World
    {
        get
        {
            return base.World + " World!";
        }
    }
}

这是背对背的

如果需要,继承类将包含重写的基类行为。子类
覆盖了基类行为,但是通过
base
关键字有一个基类的钩子

因此:

public interface IParent
{
    String World { get; }
}

public class Parent : IParent
{
    public virtual String World
    {
        get
        {
            return "Hello";
        }
    }
}

public class Children : Parent
{
    public override String World
    {
        get
        {
            return base.World + " World!";
        }
    }
}

该属性已经是父级的一部分。但是,您需要一个受保护的集合函数。。。在构造函数中设置它,如下所示:

public interface IParent
{
    String World { get; }
}

public class Parent : IParent
{
    public String World { get; protected set; }
    public Parent() { World = "Hello World"; }
}

public class Children : Parent
{
    public Children() { World = "World"; }
}
然而,也许您正在寻找更像这样的东西:

public interface IParent
{
    String World { get; }
}

public class Parent : IParent
{
    public String World { get; private set; }
    public Parent(String thing) { World = "Hello " + thing; }
}

public class Children : Parent
{
    public Children() : base("World") { }
}
var children = new Children("World");
Console.WriteLine(children.HelloWorld);

该属性已经是父级的一部分。但是,您需要一个受保护的集合函数。。。在构造函数中设置它,如下所示:

public interface IParent
{
    String World { get; }
}

public class Parent : IParent
{
    public String World { get; protected set; }
    public Parent() { World = "Hello World"; }
}

public class Children : Parent
{
    public Children() { World = "World"; }
}
然而,也许您正在寻找更像这样的东西:

public interface IParent
{
    String World { get; }
}

public class Parent : IParent
{
    public String World { get; private set; }
    public Parent(String thing) { World = "Hello " + thing; }
}

public class Children : Parent
{
    public Children() : base("World") { }
}
var children = new Children("World");
Console.WriteLine(children.HelloWorld);

您可以使用虚拟的其他私有字段,以便在子字段中重写它

试试这个:

public interface IParent
{
    string HelloWorld { get; }
}

public class Parent : IParent
{
    protected virtual string World { get; }

    public string HelloWorld
    {
        get
        {
            return "Hello " + World;
        }
    }
}

public class Children : Parent
{
    protected override string World { get; } = "World";
}
也可以通过构造函数传递字符串,然后在运行时设置值

public interface IParent
{
    string HelloWorld { get; }
}

public class Parent : IParent
{
    private readonly string world;

    public Parent(string world)
    {
        this.world = world;
    }

    public string HelloWorld
    {
        get
        {
            return "Hello " + world;
        }
    }
}

public class Children : Parent
{
    public Children(string world) : base(world)
    {
    }
}
像这样使用它:

public interface IParent
{
    String World { get; }
}

public class Parent : IParent
{
    public String World { get; private set; }
    public Parent(String thing) { World = "Hello " + thing; }
}

public class Children : Parent
{
    public Children() : base("World") { }
}
var children = new Children("World");
Console.WriteLine(children.HelloWorld);

您可以使用虚拟的其他私有字段,以便在子字段中重写它

试试这个:

public interface IParent
{
    string HelloWorld { get; }
}

public class Parent : IParent
{
    protected virtual string World { get; }

    public string HelloWorld
    {
        get
        {
            return "Hello " + World;
        }
    }
}

public class Children : Parent
{
    protected override string World { get; } = "World";
}
也可以通过构造函数传递字符串,然后在运行时设置值

public interface IParent
{
    string HelloWorld { get; }
}

public class Parent : IParent
{
    private readonly string world;

    public Parent(string world)
    {
        this.world = world;
    }

    public string HelloWorld
    {
        get
        {
            return "Hello " + world;
        }
    }
}

public class Children : Parent
{
    public Children(string world) : base(world)
    {
    }
}
像这样使用它:

public interface IParent
{
    String World { get; }
}

public class Parent : IParent
{
    public String World { get; private set; }
    public Parent(String thing) { World = "Hello " + thing; }
}

public class Children : Parent
{
    public Children() : base("World") { }
}
var children = new Children("World");
Console.WriteLine(children.HelloWorld);

您可以使用第二个属性作为后缀,并将其设置为虚拟,以允许子体覆盖它

public class Parent : IParent
{
    protected virtual string Suffix => "World";

    public String World => "Hello " + Suffix;
}

public class Children : Parent
{
    protected override string Suffix => "Again";
}
家长将显示“Hello World”,孩子将显示“Hello Reach”。这仅适用于运行时类型。静态(即编译时)类型并不重要

Parent p = new Children();
Console.WriteLine(p.World); // Displays "Hello Again"!
这里,
p
的静态类型是
Parent
。运行时类型是
子类
。这种行为称为


真正的
父级
无法“再次”了解后缀。

您可以为后缀使用第二个属性,并将其设置为虚拟,以允许子级覆盖它

public class Parent : IParent
{
    protected virtual string Suffix => "World";

    public String World => "Hello " + Suffix;
}

public class Children : Parent
{
    protected override string Suffix => "Again";
}
家长将显示“Hello World”,孩子将显示“Hello Reach”。这仅适用于运行时类型。静态(即编译时)类型并不重要

Parent p = new Children();
Console.WriteLine(p.World); // Displays "Hello Again"!
这里,
p
的静态类型是
Parent
。运行时类型是
子类
。这种行为称为



对于真正的
父对象
来说,没有办法知道后缀“再”

这个。World
将递归调用该属性!如果我执行
new Parent().World
,您希望返回什么?下面是解决方案的数量。这个问题非常模糊,有许多不同的方法来解决这个问题。如果以下任何一项不满足您的需要,请添加更多详细信息。
this.World
将递归调用该属性!如果我执行
new Parent().World
,您希望返回什么?下面是解决方案的数量。这个问题非常模糊,有许多不同的方法来解决这个问题。如果以下任何一项不满足您的需要,请添加更多详细信息。这两项都会导致编译时错误,“
Parent
未实现接口
ipart
”。。。孩子们也一样。您也不能在界面中设置辅助功能修饰符。@RonBeyer-是的,有几个输入错误。修正了。我不认为这是OP想要的,你在创建对象时设置了它一次,但是OP使用的是属性,并且想要孩子当前设置的任何东西。在您的情况下,没有父属性可以用来获取要连接到父属性的值的子属性。实际上,这是OP方面的一个X-Y问题,但我不认为这解决了OP所寻找的问题。就解决OP中建模的问题的方法而言,上述方法是正确的。可能OP真正想要的是其他人在上面发布的后缀方法,在这种情况下,该方法应该标记为答案。但是,除非OP提供更多详细信息,否则这些都是所述问题的正确解决方案。这两种解决方案都会导致编译时错误,“
Parent
未实现接口
IParent
”。。。孩子们也一样。您也不能在界面中设置辅助功能修饰符。@RonBeyer-是的,有几个输入错误。修正了。我不认为这是OP想要的,你在创建对象时设置了它一次,但是OP使用的是属性,并且想要孩子当前设置的任何东西。在您的情况下,没有父属性可以用来获取要连接到父属性的值的子属性。实际上,这是OP方面的一个X-Y问题,但我不认为这解决了OP所寻找的问题。就解决OP中建模的问题的方法而言,上述方法是正确的。可能OP真正想要的是其他人在上面发布的后缀方法,在这种情况下,该方法应该标记为答案。但是,除非OP提供更多细节,否则这些都是解决问题的正确方法。您是否忘记编辑一些您打算编辑的内容?您的
Parent.World
现在似乎是递归的。@Chris是的。一个打字错误使我投了反对票。现在修好了(Thx不是我,所以我不能把向下的投票颠倒过来。如果这有什么安慰的话,你现在可以让我向上投票了。:)是的,我讨厌人们这么快就把投票打错了-我也被击中了:/你忘了编辑一些你想编辑的东西了吗?您的
Parent.World
现在似乎是递归的。@Chris是的。一个打字错误使我投了反对票。现在修好了(那不是我,所以我不能把投票结果颠倒过来。你现在可以了哈