2012-08-03 11 views
9

Bir BufferedImage (ana), kendim genişletilmiş bir AdvancedBufferedImage (alt) için bir döküm yapmaya çalıştığımda bir ClassCastException alıyorum, herhangi bir yöntem geçersiz kıldım ve ben tüm yüklenicilerialt yapı çocuğa döküm - BufferedImage nesnesi

değiştirmeden uyguladıysanız Imageio.read() yöntemini kullanarak bir Dosyadan AdvancedBufferedImage oluşturmaya çalıştığımda bu özel durumu atayım.

File file = new file(path); 
AdvancedBufferedImage image = (AdvancedBufferedImage) ImageIO.read(file); 

Herhangi bir sorun olmayacak gibi görünüyor, Sorun ne olabilir?

cevap

15

Bunun gibi aşağı akışa izin verilmez.

Tercih edilen çözüm, bir TamperedImage parametresi olarak alınarak, bir AdvancedBufferedImage yapıcısının oluşturulması olacaktır. Bununla aşağıdakileri yapabilirsiniz.

File file = new file(path); 
AdvancedBufferedImage image = new AdvancedBufferedImage(ImageIO.read(file)); 

İşte AdvancedBufferedImage yapıcısı düzgün gelişmiş birinde bir BufferedImage dönüştürmek için nasıl karar verebilir ..

+0

Bu yüzden AdvancedBufferedImage'ın BufferedImage ile ilişkisini değiştirmenizi öneririz. –

+0

Tam olarak. Bu yaklaşım, kendiniz uygulamak istemediğiniz yöntemleri delege etmenize ve yine de fazladan işlevsellik eklemenize izin verir. Mevcut sınıfı sadece sararsınız. –

+6

sadece bir tutuklama yapmak için kullanışlı bir araç var, tutuklamak için, temsil etmek istediğiniz sınıfın örneğine sahip bir sınıf oluşturmak, üye 'delegate yöntemleri' üzerine sağ tıklayın. büyük sınıflar –

-1

Aşağı yayınlamanız, yalnızca yayınlamaya çalıştığınız nesne aslında yayınladığınız sınıfın bir örneğiyse başarılı olur.

4

PARENT sınıfının başvurusu, CHILD sınıfının veya onun türetilmiş sınıflarının bir örneğini tutmazsa, bir CHILD sınıfına bir PARENT sınıfı atayamazsınız.

Sizin durumunuzda, ImageIO.read(file), temel sınıf olan BufferedImage örneğini döndürür. ImageIO.read(file), AdvancedBufferedImage veya alt sınıflarının örneğini döndürürse, bu yalnızca çalışır.

Bazı sınıfları genişletdiğinizde, türetilmiş sınıf bazı özellikleri temel sınıftan miras alır, ancak temel sınıf hiçbir şey kazanmaz. Bunun sonucu olarak, türetilmiş sınıfın bir örneği temel sınıfın tüm özelliklerine sahip olduğundan, temel sınıfın bir referansı türetilmiş sınıfın örneğini tutabilir, yani BASE sınıfına bir DERIVED sınıfı atayabilirsiniz. Şimdi, türetilmiş sınıf bazı yeni özellikler ekleyebilir ve taban sınıfı bu özelliklerin hiçbir zaman farkında değildir. Yani BASE sınıfından DERIVED'e yapılan bir döküm açıkça yanlıştır.

3

Downcasting in Java

downcasting böyle işe gitmiyor. Yukarıdaki mesajdaki cevaba bakınız. Alternatif olarak, BufferedImage alan ve ImageIO.read() tarafından döndürülen nesne ile oluşturulan sınıfınızın bir örneğini döndüren statik bir fabrika yöntemi oluşturmaya ne dersiniz? Örneğin

:

private AdvancedBufferedImage(BufferedImage bi) { 
    // build your AdvancedBufferedImage from bi 
    ... 
} 

public static AdvancedBufferedImage buildABI(BufferedImage bi) { 
    return new AdvancedBufferedImage(bi) 
+0

Ne demeye çalışıyorsun görmek, ancak bu durumda getters yok oldukları yüklenici içinde parametreler vardır, Bu yüzden de –

+0

'u uygulamak zorunda kalıyor. O zaman kompozisyonun sizin durumunuzdaki mirastan daha iyi bir fikir olduğunu düşünüyorum. Sınıfınızın onu genişletmek yerine BufferedImage nesnesine sahip olmasını ister misiniz? – Carl

0

BufferedImagebirAdvancedBufferedImage ve bundan sonra da dökülen başarısız değildir.

BufferedImage işlevlerini genişletebilirsiniz, ancak read yöntemi hala yalnızca BufferedImage değerini döndürür. Döküm, referansın istenen tipte olmasını veya davranmasını zorlamaz.

Muhtemelen AdvancedBufferedImage sınıfında bir BufferedImage sarmak isteyebilirsiniz, daha sonra ileri sınıfınızı geçirip değiştirebilirsiniz.

2

Genel olarak, ebeveyn sınıflarını çocuk sınıflarına atayamazsınız. Bir Hayvansı bir Köpeğe dökme yapmak gibi bir şey. Bir Köpek bir hayvandır, ancak diğer yol her zaman doğru değildir, bu yüzden Java derleyicisi bunu yapmanıza izin vermeyecektir.

Bkz. object inheritance.

2

mahzun izin verilmekte, fakat o olmalı çocuğun gerçek örneği:

class A { 
    String name = "a"; 
    A(){}; 
} 

class B extends A { 
} 

public class Main { 
    public static void main(String[] args) { 
    A a = new B(); // must a b instance 
    B b = new B(); 
    b = (B)a; 
    System.out.println(b.name); 

    } 
}