@UNy

Работа с объектами в java?

Пытаюсь разобраться с созданием объектов. Есть некий класс A для создания объекта мы пишем A a1 = new A(). Вроде бы просто. Затем появляется класс B который наследуется от класса A. Что значит такое создание объекта:
A a2 = new B();
Почему имена классов вначале и конце разные и что это значит?

Так же есть такой код:
class A{
    int q = 33;
    int sum(int a,int b){
        return a+b;
    }
}

class B extends A{
    int q = 32;

    int sum(int a, int b) {
        return a-b;
    }
}

public class beginner {
    public static void main(String[] args) {

        A a = new B();

        System.out.println(a.sum(1,2));
        System.out.println(a.q);

    }
}

Почему при вызове a.sum(1,2) вызывается метод класса B, а при вызове a.q вызывается переменная класса A?
  • Вопрос задан
  • 335 просмотров
Решения вопроса 2
@Cheypnow
1. A a2 = new B(); означает что ты помещаешь объект дочернего класса в переменную родительского. Так можно и зачастую нужно, когда ты не знаешь точно какой из наследников будет использоваться или хочешь абстрагироваться от конкретной реализации.
2. a.sum(1,2) вызывает метод, переопределенный в дочернем классе. Т. к. он не имеет модификатора private, это работает.
3. При вызове a.q вызывается переменная класса A потому что поля не переопределяются.

Советую почитать про базу ООП: наследование. полиморфизм и инкапсуляцию.
Ответ написан
pi314
@pi314
Президент Солнечной системы и окрестностей
Принципиальная ошибка в понимании, видимо, заключается в формулировке "затем появляется"... Он появляется не "затем" - декларации обоих классов "появляются" во время написания кода и, соответственно, известны компилятору (compile time). А вот объекты, например, в результате выполнения строки A a1 = new A(); появляются во время работы программы (run time). Понимание этой разницы фундаментально важно!

А дальше все просто и становится на свои места. В строке A a = new B(); (на которую компилятор, кстати, будет ругаться) происходят сразу две вещи: во-первых, создается экземпляр класса B, во-вторых, он приводится по типу к классу А (что возможно, ибо B унаследован от А, и значит, имеет, как минимум, все те же члены класса) и ссылка на него присваивается переменной типа A. Компилятор код проглотит, но будет ругаться именно на то, что это приведение типа происходит неявно. Правильнее было бы указать его явно, вот так: A a = (А) new B(); Если бы В не был унаследован от А, компилятор выдал бы в этом месте ошибку и ничего бы не скомпилировал.

Чтоб убедиться, правильно ли Вы понимаете это дело, попробуйте теперь ответить на следующий вопрос: я написал, что "B унаследован от А"... Что это конкретно значти и когда это наследование "происходит"?

Последний вопрос, это про полиморфизм... почитайте вот тут: Почему полиморфизм так работает?
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы