Класс, являющийся абстрактным, просто означает, что вы не можете создать такой класс напрямую.Если у вас есть такой класс, вы можете привести его к виду, как будто это любой из его подклассов.Другими словами, все «абстрактные» средства - это то, что вы не можете сделать:
SomeAbstractClass obj = new SomeAbstractClass(...);
У вас может быть ссылка на объект Graphics2D
, как в вашем примере, но если вы попросите Java сообщитьВы настоящий тип объекта, на самом деле он никогда не будет Graphics2D
объектом.Исходя из этого кода, вы не можете быть уверены, что реальный тип рассматриваемого объекта также является 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();
}
}
Результат:
org.littleshoot.proxy.inlet.Concrete
I'm Concrete
Обратите внимание, что если вы спросите у Java тип объекта, он все равно будет конкретным, даже если вы просилитип объекта с помощью абстрактной ссылки.Также обратите внимание, что если вы вызываете метод класса Abstract, который был переопределен в Concrete, будет вызываться версия Concrete.