【问题标题】:C# accsess derive method from main..C# 从 main.. 访问派生方法
【发布时间】:2018-01-18 19:32:53
【问题描述】:

“我尝试使用两个类编写程序,一个称为“Door”和“AdvanceDoor”(派生类),现在 AdvanceDoor 具有函数“ChangeCode”,我尝试使用以下语法创建一个 AdvanceDoor 对象:

门广告 = new AdvanceDoor(必填参数...);而且我看不到她的方法(ChangeCode)..”

    class Program 
    {
        static void Main(string[] args)
        {

            Door ad = new AdvanceDoor(222, 55, "Iron", "223");
          // "here im try to call ChangeCode method from ad and its not exist"

            Console.ReadLine();
        }
    }

如果我现在写:

AdvanceDoor d = new AdvanceDoor(222, 55, "Iron", "223");

这是工作......我的问题是为什么我不能使用基类创建对象然后如果我通过“新的advanceDoor”它给我advacneDoor选项......

【问题讨论】:

  • 因为变量ad 的类型为Door。而Door 没有ChangeCode 方法。您只能与您正在使用的类型上存在的事物进行交互。您可以将该方法添加到父类,可以为变量使用派生类型,可以将变量强制转换为派生类型等。但问题的根源是您的设计被破坏了,您需要更好了解并建模您要使用的对象。
  • 编译器应该如何知道运行时ad中存储了哪种Door?也许你会有一个NotSoAdvancedDoor,没有ChangeCode,你存储在ad 中。 C# 是一种具有出色类型安全性 的语言。所以如果你说它是一个Door,它只是一个Door,而不是一个AdvancedDoor
  • 是的,但是当我声明基类然后是子类时,它应该将其识别为子类类型不是吗?
  • @ShlomiTubul:内存中的对象可能是AdvancedDoor 类型,但变量Door 类型。它们是两种不同的东西。
  • @David 好的,谢谢!!!

标签: c# inheritance polymorphism


【解决方案1】:

您正在尝试访问特定类的方法,但是当您创建 AdvanceDoor 的对象时,您将其分配给基类,因此 ChangeCode 方法对您的实例不可用。

正确的做法是 AdvanceDoor d = new AdvanceDoor(222, 55, "Iron", "223");

或者使用所有方法创建接口而不是基类。

【讨论】:

    【解决方案2】:

    想更深入地回答一下:

    MyBaseClass bob = new SubClass();
    bob.OnlyBaseClassMethods();
    

    ... 这样做的原因是变量 bob 只是 确定 是一个 MyBaseClass。如果有帮助,请想象一下:

    MyBaseClass bob;
    if (something)
        bob = new SubClass();
    else
        bob = new SecondSubClass();
    bob.OnlyBaseClassMethods();
    

    ...此时,bob 可能是这些子类中的任一个

    那么你对你想做的事情不走运吗?

    视情况而定。看看这段代码:

    public class Door
    {
        public void Open() { /* ... code ... */ }
        public void Close() { /* ... code ... */ }
    }
    public interface PasswordEncoded
    {
        void ChangeCode();
    }
    public class AdvancedDoor : Door, PasswordEncoded
    {
        public void ChangeCode() { /* ... code ... */ }
    }
    
    // ... elsewhere
    
    public void SomeFunction(Door someDoor)
    {
        if (someDoor is PasswordEncoded)
            ((PasswordEncoded)someDoor).ChangeCode();
    }
    

    这里发生了什么?我添加了一个名为“PasswordEncoded”的接口。如果您编写一个实现此接口的类,它有一个名为“ChangeCode”的函数。

    好的,所以你有一个“门”变量——你不能按照当前的方式调用 ChangeCode。但是您可以检查该变量是否包含确实具有该 ChangeCode 函数的实例 - 它是否是 PasswordEncoded 的东西。

    如果有呢?然后,您可以将其转换为 PasswordEncoded 对象(它就是 - 您刚刚检查过该行)并从那里调用 ChangeCode() 方法。

    【讨论】:

    • 我不了解interface...你能简单地给我解释一下他是做什么的吗?
    • 有时会使用“合同”这个词,但我喜欢“描述符”这个词。基本上,您确定一个或多个类需要的一些功能,然后为该功能编写一个接口。之后,你让那些适当的类实现了那个接口(就像我的例子一样。)很难在评论中加入更多细节,但是这个概念对于编写好的、长期的代码非常重要——你应该做一些谷歌搜索来研究: “抽象类”、“接口”和“依赖倒置原则”以获得更多背景知识。
    猜你喜欢
    • 1970-01-01
    • 2017-11-28
    • 2014-05-01
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    • 2018-11-03
    • 1970-01-01
    • 2021-11-19
    相关资源
    最近更新 更多