Вопрос о приведении объектов к типу и доступе к методу

Я немного запутался в синтаксисе приведения типов и создания объектов. Вот у меня есть код

class OverridingTest{
public static void main(String [] args){
    Dog dog = new Hound();
    ((Hound)dog).sniff();
   }
}

class Dog{
    public void bark(){
        System.out.println("woof ");
    }
}

class Hound extends Dog{
    public void sniff(){
        System.out.println("sniff ");
    }
    public void bark(){
        System.out.println("bowl");
    }
}

У меня есть некоторые сведения о синтаксисе и кастинге. Однако, когда я попытался не использовать объект «собака», он отправляет ошибку. Я немного смущен тем, почему компилятор это делает.

Я прочитал несколько ссылок об этом и увидел синтаксис создания экземпляров объектов в контексте приведения. Он сказал, что в этой строке кода:

Dog dog = new Hound();

«Собака» в начале строки определяет «Тип» объектов. В частности, он определяет операции, которые может выполнять объект, а «собака», которая является подклассом класса «собака», является «классом» и определяет реализацию методов, доступных для экземпляра объекта.

Теперь это та часть, где я начал путаться. Разве не так, как объект «собака», был создан уже со ссылкой на класс «гончая»? Это означает, что объект «собака» имеет реализацию класса Hound и, следовательно, может получить доступ к его методам? Зачем мне нужно добавлять оператор приведения типов при доступе к его методам? Как это?

((Hound)dog).sniff();

Кроме того, у меня есть еще один вопрос по этому поводу, который является отдельным вопросом, но ссылается на тот же код. Я попытался создать экземпляр объекта «собака» со ссылкой на класс класса «Собака», как это.

Dog dog = new Dog();

И затем я помещаю его в подкласс новой строки, где

Hound newdog = (Hound) dog;

Это соответствует синтаксису приведения типов и прекрасно компилируется. Однако я получаю ошибку времени выполнения. Разве это не соответствует методам литья? Если нет, то как бы я сделал это по-другому?


person Zidane101    schedule 19.10.2019    source источник
comment
Компилятор знает тип объявленной переменной, а не тип объекта, который ей был присвоен, который, кстати, может измениться позже в программе. В вашем последнем примере вы приводите объект Dog к более конкретному дочернему типу Hound, когда исходный объект не является Hound, так что да, ожидайте исключение приведения класса при запуске этого кода.   -  person Hovercraft Full Of Eels    schedule 19.10.2019
comment
Также обратите внимание, что наличие корректного синтаксиса не означает, что можно предположить отсутствие ошибок при выполнении кода.   -  person Hovercraft Full Of Eels    schedule 19.10.2019
comment
Я понимаю, и спасибо за дополнительные ссылки!! Однако у меня есть вопрос о части методов переопределения. Как мне в этом случае получить доступ к методу коры в суперклассе без изменения реализации? Потому что на выходе java запускает метод подкласса через переопределение метода. Я знаю, что есть суперметод, но для этого потребуется изменить некоторую реализацию методов. Можно ли как-нибудь вызвать метод суперкласса?   -  person Zidane101    schedule 19.10.2019