Вопрос про наследование java

319
20 сентября 2017, 10:41

Почему в задаче, если сравнивать типы в приведенном порядке, то Лев и Тигр имеют тип Кот. Если же в методе строку "o instanceof Cat" сделать после аналогичных строк для Льва и Тигра, то программа работает корректно. Это как то связано с вызовом конструкторов наследуемых классов?

public class Solution {
    public static void main(String[] args) {
        System.out.println(getObjectType(new Cat()));
        System.out.println(getObjectType(new Tiger()));
        System.out.println(getObjectType(new Lion()));
        System.out.println(getObjectType(new Bull()));
        System.out.println(getObjectType(new Cow()));
        System.out.println(getObjectType(new Animal()));
    }
    public static String getObjectType(Object o) {
        if (o instanceof Cat) return "Кот";
        else if (o instanceof Tiger) return "Тигр";
        else if (o instanceof Lion) return "Лев";
        else if (o instanceof Bull) return "Бык";
        else if (o instanceof Cow) return "Корова";
        else return "Животное";
    }
    public static class Cat extends Animal{
    }
    public static class Tiger extends Cat {
    }
    public static class Lion extends Cat {
    }
    public static class Bull extends Animal {
    }
    public static class Cow extends Animal {
    }
    public static class Animal {
    }
}
Answer 1

При наличии иерархии типов сначало нужно сравнивать с более частным случаем и последовательно переходить к более общим, если совпадения не обнаружено. При наследовании вида Animal - Cat - Tiger, тигр будет являться и котом, и животным. Поэтому результат будет зависеть только лишь от порядка сравнения типов в вашем коде.

Answer 2

Оператор instanceof проверяет возможность приведения объекта к заданному классу/интерфейсу, а не то что объект принадлежит к этому классу. Соответственно класс объекта корректнее будет определять через getClass().

public static String getObjectType(Object o) {
        if (o.getClass() == Cat.class) return "Кот";
        else if (o.getClass() == Tiger.class) return "Тигр";
        else if (o.getClass() == Lion.class) return "Лев";
        else if (o.getClass() == Bull.class) return "Бык";
        else if (o.getClass() == Cow.class) return "Корова";
        else return "Животное";
    }
Answer 3

Если просто на пальцах, то когда вы пишете

public static class Tiger extends Cat {
}

Это значит, что класс данный класс принадлежит сразу двум типам: Cat и Tiger. То есть это и тигр и кот одновременно. Далее у вас в методе первым делом проверяется, является ли объект котом? И да, для случая с тигром и львом вернется true, потому что они принадлежат типу кот.

READ ALSO
Вернуть значение в функцию AsyncTask

Вернуть значение в функцию AsyncTask

Вернуть значение "value" из doInBackroundПеребрал множество решений, в том числе и ответы stackoverflow, не подходят

233
Манипуляции с default button

Манипуляции с default button

В Scene имеется три ButtonПервая кнопка подсвечивается, как дефолтная кнопка, из-за чего при нажатии стрелок вправо - влево на клавиатуре происходит...

180
Кнопка в кнопке или двойная кнопка

Кнопка в кнопке или двойная кнопка

Вот стоковый будильникКак видно на скриншоте, есть кнопка шириной MATCH_PARENT, а вот справа есть еще одна кнопка будильника, состояние вкл\выкл

171
Как выводить номер для каждого вызова метода?

Как выводить номер для каждого вызова метода?

Программа должна выводить несколько void методовКак сделать так, чтобы при каждом выводе эта строчка получала номер? Я понимаю, что надо использовать...

206