简体   繁体   中英

Create object of abstract class. How possible

Why it is possible? :

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

I'm writing some app ni find this line and im cunfused, because MSDN says that BitmapSource is abstract class.

BitmapSource is an abstract class and thus can't be created directly , but Imaging.CreateBitmapSourceFromHBitmap returns some concrete class that inherits from BitmapSource and thus can be "cast" to a BitmapSource .

It's analagous to having an abstract Animal class, but having a concrete Giraffe class that inherits from it:

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

The call to Imaging.CreateBitmapSourceFromHBitmap returns some concrete class which inherits from BitmapSource . So this call does not create an instance of the abstract class BitmapSource . You were just confused about this.

To simplify the situation, this is similar to
Animal an1 = DogFactory.createDog();
or to
Animal an2 = CatFactory.createCat();
if we assume Animal is an abstract class, while Cat
and Dog are concrete classes which inherit from Animal .

BitmapSource is an abstract class but Imaging.CreateBitmapSourceFromHBitmap creates an object with type of concrete subclass InteropBitmap , you can see it in .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
}

And you can assign InteropBitmap to BitmapSource type variable because it is its base class (directly or not), exactly as in:

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

and then you can:

ISomeInterface var1 = new SomeClass();

or:

SomeBaseClass var2 = new SomeClass();

and eventually you can create some factory method that hides creating an object:

class SomeFactoryClass
{
   public SomeBaseClass CreateObject() { return new SomeClass(); }
}

SomeBaseClass var3 = SomeFactoryClass.CreateObject();

Exactly as in the above exept from the .NET reference source code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM