派生类对象分配给Base类变量

时间:2018-02-22 03:54:06

标签: c# polymorphism

在代码下面,A是基类,B是派生类。当我A a1 = new B();并调用a1可以看到的内容时,我看到它只能看到A类字段,因为a1是A类型,所以它看不到B特定成员,这也是我所期望的。但是当我调用a1.Display()时,它会打印出B的显示方法。为什么a1看不到B场却可以达到B的显示方式?

using System;    

namespace Test
{
class A
{
    public int varOfClassA = 5;

    public virtual void Display()
    {
        Console.WriteLine("I am Class A");
    }
}

class B : A
{
    public int varOfClassB = 10;

    public override void Display()
    {
        Console.WriteLine("I am class B");
    }
}

class Program
{
    static void Main(string[] args)
    {
        A a1 = new B();
        Console.WriteLine(a1.varOfClassA);  //prints out "5"
        a1.Display();   //prints out "I am class B" why???
    }
}
}

1 个答案:

答案 0 :(得分:1)

这是因为方法Display()B中声明为overrides
无论引用类型是派生类型还是基类类,都将执行覆盖基类成员的每个成员。

执行A a1 = new B();时,您所拥有的是B的实例,而不是A的实例。
但是,由于引用的类型为A,因此您只能访问B中存在的A的任何方法,这些方法既可以原样继承,也可以重写。

通常,在这种情况下,当您的代码在a1上执行方法时,执行的方法是B方法,因为这是您拥有的实例类型。但是,此规则确实有例外 - 即override而不是B时,new中的方法被声明为A。在这种情况下,即使您的实例属于B类型,也会执行class A { public virtual void Display() { Console.WriteLine("I am Class A"); } public int MyIntValue { get{ return 5; } } } class B : A { public override void Display() { Console.WriteLine("I am class B"); } public new int MyIntValue { get{ return 5; } } } 的方法(或属性):

A a1 = new B();

a1.Display(); // Displays "I am class B"
Console.WriteLine(a1.MyIntValue.ToString()); // Displays "5"

使用上述类:

CREATE LOGIN [app_usr] WITH PASSWORD=N'password', DEFAULT_DATABASE=[databaseName], DEFAULT_LANGUAGE=[us_english], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
GO

USE [databaseName]
GO
CREATE USER [app_usr] FOR LOGIN [app_usr]
GO

/**** You can choose to only run the following statements that you want***/
-- The following gives the user the ability to read all tables in the db
USE [master]
GO
EXEC sp_addrolemember N'db_datareader', N'app_usr'
GO

-- The following gives the user the ability to write to all tables in the db
USE [master]
GO
EXEC sp_addrolemember N'db_datawriter', N'app_usr'
GO

-- The following gives the user the ability to do anything in the db
USE [master]
GO
EXEC sp_addrolemember N'db_owner', N'app_usr'
GO

You can see a live demo on rextester.