有人可以解释一下通过引用基类来实例化派生类和通过派生类名本身实例化派生类之间的区别。
请完成此计划
using System;
abstract class Test
{
public int _a;
public abstract void A();
}
class Example1 : Test
{
public override void A()
{
Console.WriteLine("Example1.A");
base._a++;
}
}
class Example2 : Test
{
public override void A()
{
Console.WriteLine("Example2.A");
base._a--;
}
}
class Program
{
static void Main()
{
// Reference Example1 through Test type.
Test test1 = new Example1();
test1.A();
Example2 test2 = new Example2();
test2.A();
}
}
这又是一个问题,在Main()方法中创建了两个对象。
第一个对象test1是通过Test(基类)类型引用的,它实际上意味着什么?它与第二个基于派生类的对象有什么区别?
在首选的程序中,引用基类或派生类,它有什么帮助?
我知道我的问题有点模糊,但对此有任何想法对我进一步学习非常有帮助。提前谢谢。
答案 0 :(得分:1)
Test test1 = new Example1();
当您使用基类类型创建派生类对象时,您正在使用多态的概念。
在您的示例中,我们看不到使用多态的优势,但应用多态可以帮助我们在其他一些情况下编写简洁的代码。例如,当你需要许多不同派生类的对象来调用它们的虚拟(或抽象)方法时,你可以创建一个基类列表,但是将每个对象作为不同的派生类,这样你就可以遍历列表并调用方法简洁明了。
可能很难用文字来理解它,但你可以在this page的第一个示例代码中找到一般的多态性使用,我们可以在这里压缩调用不同派生类的许多虚方法的代码只有1行(s.Draw();)。因此,在不应用多态的情况下,我们只能单独新建多个对象并分别调用方法Draw(),这显然不是在这种情况下编码的好方法。
答案 1 :(得分:0)
当接近使用继承和一般的抽象时,我会考虑你需要在类中使用什么,然后使用其类型表示的最通用(抽象)版本来保存变量和方法签名(例如Example1)。
Test test1 = new Example1();
test1.A();
只要你没有违反SOLID原则,这将会给你带来的是以最小阻力重构的自由,确保你不要一眼就认为代码依赖于任何特定于派生类的辅助方法。
示例2给出的印象是代码完全依赖于该实现,这可能是合适的,但通常表示紧耦合。
Example2 test2 = new Example2();
test2.A();
这是设计/编译时的差异,而不是运行时。在运行时,它们都产生相同的结果,唯一的例外是使用反射时。在equals右侧发生的事情不受equals左侧类型定义的影响。