как проверить, принадлежит ли экземпляр абстрактного объекта определенному подклассу - PullRequest
1 голос
/ 04 июня 2019

Я ссылаюсь на этот дубликат вопроса здесь:
Проверка, является ли объект класса подклассом другого объекта класса в Java

У меня есть абстрактный родительский класс с именем 'Figure', у меня есть два подкласса, 'Circle' и 'Rectangle', которые расширяют этот абстрактный родительский класс. Я пытаюсь определить, имеет ли объект Figure тип Circle или тип Rectangle.

Мой оригинальный код:

 public boolean isInstanceOfRectangle(Figure figure)
 {
     boolean isInstance = figure instanceof Rectangle;
     System.out.println("instance of rectangle!");

     return isInstance;
  }

Изучив связанный вопрос выше, я переписал свой код следующим образом:

public boolean isRectangle()
{
    boolean isInstance = Figure.class.isAssignableFrom(Rectangle); 
    System.out.println("instance of rectangle!");
    return isInstance;  
 }

По какой-то причине это не работает, если я не включу в свой основной класс следующее:

public Class<?> Rectangle;
public Class<?> Circle1;

Я не уверен, стоит ли включать это в мой класс, если нет, то мне кажется, что я должен включить его в качестве параметра в свой метод. Я не могу правильно вызвать и протестировать этот метод, потому что я не уверен, какой параметр передать в метод при вызове. Я хотел бы написать что-то вроде:

public void mouseReleased(MouseEvent e)
{
    if ((isRectangle(shape1)))
    addRectangle((Rectangle)shape1, e.getComponent().getForeground());

    else if ((isCircle(shape1)))
    addCircle((Circle) shape1, e.getComponent().getForeground());   
 }

где 'shape1' - объект Figure, для которого создан экземпляр в виде круга или прямоугольника. Поскольку параметр имеет тип Figure, я не уверен, как определить метод isRectangle, чтобы взять объект Figure (абстрактный родительский объект) и определить, для какого именно подкласса он является экземпляром. Или предпочтительно не принимать никаких параметров и просто выполнять работу, используя объект Figure для вызова метода. Я немного запутался, как поступить.

* Редактировать: по предложению пользователя я переписал следующее , которое НЕ работает, потому что в обоих случаях вывод ЛОЖЬ.

Figure circleObj = new Circle(Color.BLUE);

System.out.println(isInstanceOfRectangle(circleObj));
System.out.println(isInstanceOfCircle(circleObj));

public static boolean isInstanceOfRectangle(Figure figure)
{
    boolean isInstance = figure instanceof Rectangle;
    if (isInstance == true)
        System.out.println("instance of rectangle!");
    else
        System.out.println("is NOT a rectangle");
    return isInstance;
}


public static boolean isInstanceOfCircle(Figure figure)
{
    boolean isInstance = figure instanceof Circle;
    if (isInstance == true)
        System.out.println("instance of circle!");
    else
        System.out.println("is NOT a circle");
    return isInstance;
}

Ответы [ 4 ]

2 голосов
/ 04 июня 2019

Это всегда будет возвращать false, поскольку экземпляр Figure Class не является подклассом экземпляра Rectangle Class:

boolean isInstance = Figure.class.isAssignableFrom(Rectangle.class); 

Вы хотите вообще вызвать isAssignableFrom()для класса переменной, который вы не знаете тип времени выполнения.
Это будет иметь больше смысла:

Figure figure = ...;
boolean isInstance = Rectangle.class.isAssignableFrom(figure.getClass()); 

Это позволяет узнать, является ли экземпляр класса переменной figure IS a Rectangle.

Введение метода для обработки требования будет иметь еще больший смысл, поскольку он динамический, а также позволяет обрабатывать проверки совместимости различных классов:

  public static boolean isInstanceOf(Figure figure, Class<?> clazz){
    boolean isInstance = clazz.isAssignableFrom(figure.getClass());
    return isInstance;
  }

И вы можете использовать его, например::

System.out.println(isInstanceOf(new Rectangle(), Rectangle.class));    
System.out.println(isInstanceOf(new Circle(), Rectangle.class));    
System.out.println(isInstanceOf(new Figure(), Rectangle.class));    

Это печатает:

true

false

false

И, конечно, всеиз них выведите true как Figure, Circle и Rectangle: Figure s:

System.out.println(isInstanceOf(new Rectangle(), Figure.class));    
System.out.println(isInstanceOf(new Circle(), Figure.class));    
System.out.println(isInstanceOf(new Figure(), Figure.class));    
1 голос
/ 04 июня 2019

Я собираюсь перезвонить здесь и указать на ошибку в этих методах:


public static boolean isInstanceOfRectangle(Figure figure)
{
    //boolean isInstance = figure instanceof Rectangle;
    boolean isInstance = figure instanceof Rectangle;
    if (isInstance == true)
        System.out.println("instance of rectangle!");
    else
        System.out.println("is NOT a rectangle");
    return isInstance;
}


public static boolean isInstanceOfCircle(Figure figure)
{
    //boolean isInstance = figure instanceof Rectangle;
    boolean isInstance = figure instanceof Rectangle;
    if (isInstance == true)
        System.out.println("instance of circle!");
    else
        System.out.println("is NOT a circle");
    return isInstance;
}

Во втором методе вы хотите, чтобы поведение проверяло, является ли оно кругом.,Но вместо этого вы проверяете, является ли это прямоугольником.

Вместо figure instanceof Rectangle вы должны проверять figure instanceof Circle

PS.допустимо использовать instanceof.Все остальное излишне.

1 голос
/ 04 июня 2019

Ваша первоначальная реализация верна и проста до тех пор, пока мы не получим сопоставление с образцом в Java.

Более подробное объяснение: оператор

instanceof может использоваться для проверки, является ли объектэкземпляр определенного класса.Это соответствует вашим намерениям.

Вы можете достичь аналогичной функциональности с ClassA.isAssignableFrom(ClassB).Здесь ClassA является суперклассом, а ClassB является подклассом.Обратите внимание, что эта функция сравнивает два класса (экземпляры Class<?>), а не экземпляр с классом.

Вы можете получить класс из экземпляра, используя метод getClass, и, следовательно, полученный код будет выглядеть следующим образом:

Rectange.class.isAssignableFrom(figure.getClass())

Предлагаемый вами чек

Figure.class.isAssignableFrom(Rectangle);

имеет несколько проблем:

  • синтаксическая ошибка: вам нужен экземпляр Class<?> справа, вы можете использовать литерал класса Rectangle.class, но это проверяет тривиальный факт и всегда верно.
  • , чтобы исправить эту ошибку, вы определили переменную Class<?> Rectangle, но эта переменная не имеет никакого отношения к классу Rectangle, если явно не инициализирована литералом класса Rectangle.class
  • , который вы не используетеэкземпляр фигуры в любом месте
1 голос
/ 04 июня 2019

Я не вижу особых причин усложнять ваш код с помощью присваиваемого.Ваш оригинальный код работает.Более того, проверка класса переменной не является хорошей практикой, попробуйте реструктурировать свой код.(Проверьте полиморфизм, принцип Барбары Лисков и принцип сегрегации интерфейса). И для пояснения: рисунок не является объектом, поскольку он абстрактный, это тип.Тип - это то, что стоит слева от объявления переменной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...