创建抽象类的对象。如何实现?

3

为什么这是可能的?:

BitmapSource i = Imaging.CreateBitmapSourceFromHBitmap(...);

我正在编写一个应用程序,发现了这行代码,但我感到困惑,因为MSDN说BitmapSource是一个抽象类。


1
你创建一个从BitmapSource派生的类。 - Gayot Fow
2
抽象类不能被实例化。您需要创建一个派生类的实例。这个例子可以工作,因为静态工厂方法的实现将创建一个派生类。在调试器中检查方法返回的对象的实际运行时类型,您会看到。 - Martin Costello
3个回答

8

BitmapSource 是一个抽象类,因此无法直接创建,但是 Imaging.CreateBitmapSourceFromHBitmap 返回了一些继承自 BitmapSource 的具体类,因此可以将其“强制转换”为 BitmapSource

这类似于拥有一个抽象的 Animal 类,但有一个继承自它的具体的 Giraffe 类:

Animal a = new Animal();  // illegal
Animal a = Zoo.CreateAnimalFromName("Giraffe"); // valid - returns a Giraffe instance

1
我总是惊讶于这个网站上有多少动物园监控软件开发人员。 - Rotem

2
调用 Imaging.CreateBitmapSourceFromHBitmap 返回一个继承自 BitmapSource 的具体类,因此这个调用并不会创建抽象类 BitmapSource 的实例。你只是对此感到困惑。
为了简化情况,这类似于
Animal an1 = DogFactory.createDog();
或者
Animal an2 = CatFactory.createCat();
如果我们假设 Animal 是一个抽象类,而 CatDog 则是继承自 Animal 的具体类。

1

BitmapSource 是一个抽象类,但是 Imaging.CreateBitmapSourceFromHBitmap 创建了一个具体子类 InteropBitmap 的对象,你可以在 .NET reference source 中看到:

unsafe public static BitmapSource CreateBitmapSourceFromHBitmap(
    IntPtr bitmap,
    IntPtr palette,
    Int32Rect sourceRect,
    BitmapSizeOptions sizeOptions)
{
    SecurityHelper.DemandUnmanagedCode();

    // CR: [....] (1681459)
    return CriticalCreateBitmapSourceFromHBitmap(bitmap, palette, sourceRect, sizeOptions, WICBitmapAlphaChannelOption.WICBitmapUseAlpha);
}

unsafe internal static BitmapSource CriticalCreateBitmapSourceFromHBitmap(
    IntPtr bitmap,
    IntPtr palette,
    Int32Rect sourceRect,
    BitmapSizeOptions sizeOptions,
    WICBitmapAlphaChannelOption alphaOptions)
{
    if (bitmap == IntPtr.Zero)
    {
        throw new ArgumentNullException("bitmap");
    } 
    return new InteropBitmap(bitmap, palette, sourceRect, sizeOptions, alphaOptions); // use the critical version
}

你可以将InteropBitmap分配给BitmapSource类型的变量,因为它是其基类(直接或间接),就像这样:

interface ISomeInterface { };
abstract class SomeBaseClass : ISomeInterfac { };
class SomeClass : SomeBaseClass { };

然后你可以:
ISomeInterface var1 = new SomeClass();

或者:

SomeBaseClass var2 = new SomeClass();

最终,您可以创建一些工厂方法来隐藏对象的创建:
class SomeFactoryClass
{
   public SomeBaseClass CreateObject() { return new SomeClass(); }
}

SomeBaseClass var3 = SomeFactoryClass.CreateObject();

除了来自.NET参考源代码外,完全与上述内容相同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接