2015-01-31 2 views
1

Я прочитал программу GUI, как это:Почему абстрактный метод fillOval() может использоваться непосредственно?

import java.awt.*; 

public class TestPaint{ 
    public static void main(String[] args){ 
     new PaintFrame().launchFrame(); 
    } 
} 

class PaintFrame extends Frame{ 

    public void launchFrame(){ 
     setBounds(200,200,640,480); 
     setVisible(true); 
    } 

    public void paint(Graphics g){ 
     Color c = g.getColor(); 
     g.setColor(Color.red); 
     g.fillOval(50,50,50,50); 
     g.fillRect(80,80,40,40); 
     g.setColor(c); 
    } 

} 

Это программа, которая может работать в памяти, вот результаты, [К сожалению у меня не хватает репутации размещать изображения, но может работать]

, когда я прочитал APIfile, я нашел fillOval() метод определен в классе Graphics, как это:

public abstract void fillOval(int x, 
           int y, 
           int width, 
           int height) 

Почему я могу напрямую использовать абстрактную fillOval() в программе? Кроме того, где я могу найти конкретные реализации fillOval() в этой программе?

ответ

2

Для того, чтобы какой-либо абстрактный класс был создан там должен быть конкретным воплощением где-то. Это реализация, которая вызывается.

Как и в случае с интерфейсом, договор - это все, что указано.

Таким образом, вы можете безопасно вызывать метод (потому что контракт должен быть удостоен любой реализации).

0

Поскольку абстрактные методы не могут быть в абстрактном классе Graphics класс должен быть абстрактным. Вы не можете создать экземпляр абстрактного класса, и ни один из методов fillOval() не является статическим. Таким образом, нет способа вызвать метод.

Теперь подходит к фактам. Абстрактные методы в абстрактном классе должны быть реализованы 1-м конкретным классом, который расширяет абстрактный класс. Поэтому вам нужно создать не абстрактный класс, который extends Graphics и обеспечить реализацию fillOval(). Затем создайте и укажите его в своей программе и вызовите его.

+0

Никогда не нужно переходить от «Графика», чтобы обеспечить реализацию, если только вы серьезно не рассматриваете возможность написания реализации для другого графического драйвера или что-то в этом роде, но тогда вам нужно будет повторно реализовать весь core AWT-библиотека для поддержки ... просто говоря;) – MadProgrammer

+0

В этом случае я уверен, что в AWT-библиотеке реализована реализация по умолчанию :) @ZHI проверить и использовать ее, –

+0

Пожалуйста, проверьте всю мою программу, я предоставляю ее на вопрос. Теперь я задаю вопрос, где можно найти конкретную реализацию fillOval()? –

0

Graphics объект, который получает передается этому методу на самом деле подкласс этого класса (так как любой объект, который проходит от SomeClass «является разновидностью» SomeClass, и что конкретный подкласс реализует логику метода fillOval.

. Например:.

abstract class A { 
    abstract void doStuff(); 
} 

class B extends A { 
    void doStuff() { 
     System.out.println("B::doStuff()"); 
    } 
} 

class Main { 
    public static void main(String[] args) { 
     A obj = new B(); 
     obj.doStuff(); // prints B::doStuff() 
    } 
} 

Если вы хотите, чтобы увидеть фактический тип объекта, вы можете использовать g.getClass().getCanonicalName(), который в этом случае оценивает в sun.java2d.SunGraphics2D исходный код можно найти here

+0

* ", которая в этом случае оценивает sun.java2d.SunGraphics2D" * - Да и нет, он оценивает это на вашей реализации JVM;) – MadProgrammer

0

Наконец, я узнал, что существует полиморфизм для вызова функции fillOval(), Графика g, которая передается в функцию, является ссылкой подкласса.