如果无法实例化一个抽象类,那么为什么可能这样呢?

时间:2019-07-04 21:11:53

标签: java abstract-class

在以下代码中,将Graphics对象传递到以下paintComponent方法中,然后将其转换为Graphics2D对象。图形不是抽象类,为什么下面这样呢?

 public void paintComponent(Graphics comp) {
 Graphics2D comp2D = (Graphics2D) comp;
 Font font = new Font("Comic Sans", Font.BOLD, 15);
 comp2D.setFont(font);
 comp2D.drawString("Potrzebie!", 5, 50);
}

2 个答案:

答案 0 :(得分:2)

仅因为无法实例化一个类并不意味着您无法获得它的实例。

在您的示例中,您所要做的就是将其强制转换为Graphics层次结构中的另一个类。

这是一个例子。


    public class AbstractDemo {

       public static void main(String[] args) {
          Concrete c = new Concrete();
          AClass a = (AClass) c;
          a.me();
       }

    }

    abstract class AClass {
       public void me() {
          System.out.println("Abstract parent");
       }
    }

    class Concrete extends AClass {

    }

答案 1 :(得分:0)

一个抽象的类只是意味着您不能直接创建这样的类。一旦有了这样的类,就可以对其进行强制转换以使其看起来像它的任何子类。换句话说,所有“抽象”的意思是你不能做:

Graphics2D

您可以像示例中那样引用Graphics2D对象,但是如果您要求Java告诉您对象的真实类型,则它实际上不会是Graphics对象。从此代码中,您也不能确定所讨论对象的真实类型还是MyGraphicsObject对象。再次可能是对真实对象的子类的引用,例如abstract class Abstract { public void whatAmI() { System.out.println("I'm Abstract"); } } class Concrete extends Abstract { @Override public void whatAmI() { System.out.println("I'm Concrete"); } } public class X { public static void main(String[] args) { // This won't compile. That's what it means for "Abstract" to be abstract. // Abstract abs = new Abstract(); // You can create a Concrete, and then upcast it to an Abstract reference... Concrete concrete = new Concrete(); Abstract abs = (Abstract)concrete; // But it's stll really a Concrete System.out.println(abs.getClass().getName()); // And it will still act like a Concrete if Concrete has overridden one of Abstract's methods. abs.whatAmI(); } } 或类似的东西。

这是多态性的全部内容和力量。创建对象后,它的行为就像其任何子类一样,并且可以通过上载将其视为任何这些子类的纯实例。

这里有一些代码指出了被cast对象的身份发生了什么:

org.littleshoot.proxy.inlet.Concrete
I'm Concrete

结果:

// Add Reference Shell32.DLL
string sFolder = "e:\\";
string sFile= "01. IMANY - Don't Be so Shy (Filatov & Karas Remix).mp3";
List<string> arrProperties = new List<string>();
Shell objShell = new Shell();
Folder objFolder;
objFolder = objShell.NameSpace(sFolder);
int nMaxProperties = 332;
for (int i = 0; i < nMaxProperties; i++)
{
    string sHeader = objFolder.GetDetailsOf(null, i);
    arrProperties.Add(sHeader);
}
FolderItem objFolderItem = objFolder.ParseName(sFile);
if (objFolderItem != null)
{
    for (int i = 0; i < arrProperties.Count; i++)
    {
        Console.WriteLine((i + ('\t' + (arrProperties[i] + (": " + objFolder.GetDetailsOf(objFolderItem, i))))));
    }
}

请注意,如果您向Java询问对象的类型,即使您通过Abstract引用询问了对象的类型,它仍然是具体的。还要注意,如果您在Abstract类上调用了在Concrete中已重写的方法,则将调用Concrete的版本。