在以下代码中,将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);
}
答案 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的版本。