Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Зачем вводят слово super? 
:(
    Опции темы
bogomol
Дата 18.3.2007, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 7.3.2007

Репутация: нет
Всего: нет



  И для чего оно нужно? И к чему прикладывается?
PM MAIL   Вверх
powerOn
Дата 18.3.2007, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 47
Всего: 159



Цитата(bogomol @  18.3.2007,  12:13 Найти цитируемый пост)
И для чего оно нужно? И к чему прикладывается? 

для обращения к полю/методу суперкласса (класса родителя).

Код

public class A extends B
{
    public A()
    {
    }
    
    public void meth()
    {
        super.meth();
        System.out.println("A::meth()");
    }
    
    public static void main(String[] args)
    {
        A a = new A();
        a.meth();
    }
}

class B
{
    public void meth()
    {
        System.out.println("B::meth()");
    }
}



--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
JUncle
Дата 18.3.2007, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 162
Регистрация: 6.4.2006
Где: Казань, РФ

Репутация: нет
Всего: 1



Цитата(powerOn @  18.3.2007,  12:28 Найти цитируемый пост)
для обращения к полю/методу суперкласса (класса родител

И к конструкторам.

Код

public class Base {

  public Base() {
     ...
  }

  public Base(String parameter) {
     ...
  }
}


public class Derived extends Base {

  public Derived() {
     super(); //  вызов суперконструктора - строго до остальных действий в этом конструкторе
     ... //  остальные действия
  }

  public Derived(String parameter) {
     super(parameter);  // аналогично
     ... //  остальные действия
  }
}


Это сообщение отредактировал(а) JUncle - 18.3.2007, 15:00
--------------------
class JUncle extends Man // singleton{/*...*/}
PM MAIL   Вверх
JVM
Дата 19.3.2007, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 189
Регистрация: 30.10.2006

Репутация: нет
Всего: 5



Цитата(powerOn @  18.3.2007,  12:28 Найти цитируемый пост)
для обращения к полю/методу суперкласса (класса родителя).

Цитата(JUncle @  18.3.2007,  14:49 Найти цитируемый пост)
И к конструкторам.


Мне кажется это очевидно, но не дает полного ответа на вопрос bogomol. Ну обратились мы к методы супер класса, ну и что? Зачем это надо? Не рискну отвечать на этот вопрос - не тот уровень знаний - но думаю ответ лежит в основах ООП: наследование, полиморфизм, переопределение и т.д. и понимание, и уж тем более правильное применение придет не сразу.

Уж коль начали обсуждать эту тему задам и свой вопрос, на который ответ пока не нашел(может плохо искал ...)
Есть два класса - один супер класс, другой дочерний:
Код

package p1;

class A1{
    
    A1(){
    testSuper();
  }

  void testSuper(){
    System.out.println("Method testSuper() class A1");
  }

Код

package p1;

class A2 extends A1{

  A2(){
    super();//Вот здесь не понятно. Вызываю конструктор супер класса, но вызывается метод testSuper() не супер класса А1,
 а дочернего класса А2. Почему?
    testSuper();
  }

  void testSuper(){
    System.out.println("Method testSuper() class A2");
  }

  public static void main(String[] args){
    new A2();
  }
}


Не могу понять почему, при вызове конструктора супер класса А1 вызывается метод дочернего класса А2? Подскажите или где можно найти ответ?
PM MAIL   Вверх
y3u
Дата 19.3.2007, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 440
Регистрация: 9.9.2006
Где: Москва

Репутация: 5
Всего: 13



все же очевидно. Во-первых, ты забыл перечислить еще один из главных принципов ООП - это инкапсуляция, собственно, этот термин и отвечает на твой вопрос. Мы часть логики скрываем (инкапсулируем, прячем в капсулу) в одних классах, чтобы потом эту логику ненароком не поломать в наследниках или еще где (ну и чтобы часть логики была доступна в определенных местах кода), для этого есть, в частности, приватные методы. А еще есть такая штука, как протектед методы, которые доступны в наследниках, которые мы можем перекрывать (ну и пэкедж локал методы тоже). Если нам надо при перекрытии метода сохранить логику метода предка, то надо обязательно дернуть внутри него super.thisOwerwrittenMethod(), иначе произойдет то, что произошло в этом "непонятном" примере выше - метод будет переопределен в потомке "полностью". А в примере выше, мы вызываем конструктор предка, в данном случае, чтобы отработал функционал по его созданию, но, реально, мы создаем инстанс объекта A2, где метод у нас уже переопределен, поэтому все правильно.


--------------------
В нашей стране настаивать на кореньях, черной смородине, лимонных корках - гораздо эффективнее, чем на правах
PM MAIL   Вверх
JVM
Дата 19.3.2007, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 189
Регистрация: 30.10.2006

Репутация: нет
Всего: 5



Т.е. к тому, что переопределено из дочерних классов нельзя обратиться?
 smile наверно это логично, а то зачем тогда переопределял
PM MAIL   Вверх
y3u
Дата 19.3.2007, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 440
Регистрация: 9.9.2006
Где: Москва

Репутация: 5
Всего: 13



Цитата(JVM @  19.3.2007,  13:00 Найти цитируемый пост)
Т.е. к тому, что переопределено из дочерних классов нельзя обратиться?
  наверно это логично, а то зачем тогда переопределял 


почему это нельзя, как раз, таки, можно - используя super smile


--------------------
В нашей стране настаивать на кореньях, черной смородине, лимонных корках - гораздо эффективнее, чем на правах
PM MAIL   Вверх
JVM
Дата 19.3.2007, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 189
Регистрация: 30.10.2006

Репутация: нет
Всего: 5



y3u, еще раз посмотрел свой пример и твой ответ. Мне все же не понятно, почему вызывается метод дочернего класса из конструктора. Ведь когда создается объект А2
Код

new A2();

вызывается конструктор класса А2, который сначала должен вызвать конструктор супер класса, т.е. объект класса А2 еще не создан, а его метод уже вызывается. Почему? Что не понимаю?

Результат рабты программы
Код

Method testSuper() class A2
Method testSuper() class A2

PM MAIL   Вверх
y3u
Дата 19.3.2007, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 440
Регистрация: 9.9.2006
Где: Москва

Репутация: 5
Всего: 13



а почему ты решил, что он еще не создан? smile Он-то как раз создан, но не доинициализирован. Если б это был конструктор с параметрами мы бы тут как раз сетили бы поля объекта, читай - инициализировали. Так что объект уже есть, и метод у него переопределен...

Это сообщение отредактировал(а) y3u - 19.3.2007, 17:02


--------------------
В нашей стране настаивать на кореньях, черной смородине, лимонных корках - гораздо эффективнее, чем на правах
PM MAIL   Вверх
JVM
Дата 19.3.2007, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 189
Регистрация: 30.10.2006

Репутация: нет
Всего: 5



Цитата(y3u @  19.3.2007,  17:02 Найти цитируемый пост)
Если б это был конструктор с параметрами мы бы тут как раз сетили бы поля объекта, читай - инициализировали.

Не понял ...
PM MAIL   Вверх
y3u
Дата 19.3.2007, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 440
Регистрация: 9.9.2006
Где: Москва

Репутация: 5
Всего: 13



Код

public class MyClass {
    private Integer f1;
    private Integer f2;

    public MyClass (Integer f1, Integer f2) {
        this.f1 = f1;
        this.f2 = f2;
    }
}

public class MyClass2 extends MyClass {
   private String f3;

   public MyClass2(Integer f1, Integer f2, String f3) {
       super(f1, f2);
       this.f3 = f3;
   }
}


Это сообщение отредактировал(а) y3u - 19.3.2007, 18:44


--------------------
В нашей стране настаивать на кореньях, черной смородине, лимонных корках - гораздо эффективнее, чем на правах
PM MAIL   Вверх
JVM
Дата 20.3.2007, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 189
Регистрация: 30.10.2006

Репутация: нет
Всего: 5



y3u, я тебя не понял. Что ты этим примером хочешь сказать? Ведь из супер класса не вызывается никакой дочерний объект ...

Цитата(y3u @  19.3.2007,  17:02 Найти цитируемый пост)
Если б это был конструктор с параметрами мы бы тут как раз сетили бы поля объекта, читай - инициализировали. Так что объект уже есть, и метод у него переопределен...

Что такое 'сетили'?
Может есть статья, в которой объясняется мой вопрос?
PM MAIL   Вверх
y3u
Дата 20.3.2007, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 440
Регистрация: 9.9.2006
Где: Москва

Репутация: 5
Всего: 13



Цитата(JVM @  20.3.2007,  09:51 Найти цитируемый пост)
y3u, я тебя не понял. Что ты этим примером хочешь сказать? Ведь из супер класса не вызывается никакой дочерний объект ...


во-первых, из супер класса, как ты его назвал, никакие дочерние объекты не вызываются... наследование - это отношение is as, т.е. это тот же самый объект, но несколько иной, никогда не проектируют код, чтобы предок вызывал наследников, для работы с объектом нужного типа из множества однотипных существует класс паттернов проектирования Factory.
Во-вторых, я отвечаю на конкретный вопрос. Задай подробно вопрос, постараюсь ответить конкретно, я отвечал на 
Цитата(JVM @  19.3.2007,  18:03 Найти цитируемый пост)
Если б это был конструктор с параметрами мы бы тут как раз сетили бы поля объекта


Цитата(JVM @  20.3.2007,  09:51 Найти цитируемый пост)
Что такое 'сетили'?

от слова Set/Setup - есть такое понятие, как дерево объектов, все объекты в Java наследуются от Object, когда отрабатывает конструктор, то объект конструируется снизу вверх, сначала создаются объеты по иерархии, начиная с Object, таким образом, к моменту создания твоего A2, объект A1 уже создан, но не до конца, так сказать... это я к слову о 
Цитата(JVM @  19.3.2007,  16:11 Найти цитируемый пост)
вызывается конструктор класса А2, который сначала должен вызвать конструктор супер класса, т.е. объект класса А2 еще не создан, а его метод уже вызывается.

А вызывается метод класса A2, потому что ты пишешь 
Цитата(JVM @  19.3.2007,  10:53 Найти цитируемый пост)
 public static void main(String[] args){
    new A2();
  }

ты создаешь инстанс объекта A2, где метод УЖЕ переопределен, поэтому он и дергается из конструктора A1 уже переопределенный

Это сообщение отредактировал(а) y3u - 20.3.2007, 12:20


--------------------
В нашей стране настаивать на кореньях, черной смородине, лимонных корках - гораздо эффективнее, чем на правах
PM MAIL   Вверх
JVM
Дата 20.3.2007, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 189
Регистрация: 30.10.2006

Репутация: нет
Всего: 5



Цитата(y3u @  20.3.2007,  12:18 Найти цитируемый пост)
А вызывается метод класса A2, потому что ты пишешь 

Цитата(JVM @  19.3.2007,  10:53 )
 public static void main(String[] args){
    new A2();
  }


ты создаешь инстанс объекта A2, где метод УЖЕ переопределен, поэтому он и дергается из конструктора A1 уже переопределенный

Вот это объяснение мне и не понятно. Как может быть переопределен метод в объекте который еще не создан(объект)?

Мои рассуждения следующие. Когда я создаю объект А2
Код

new A2();
вызывается конструктор
Код

  A2(){
    super();
    testSuper();
  }

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

A1(){
    testSuper();
  }
т.к. объект класса А2 еще не создан, то вызывается метод не А2.testSuper(), а А1. testSuper().

Но судя по результату работы программы в этой логике есть ошибка. Мне как раз и хочется понять где она?
PM MAIL   Вверх
sergejzr
Дата 20.3.2007, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 6
Всего: 360



Цитата(JVM @  20.3.2007,  12:59 Найти цитируемый пост)
Но судя по результату работы программы в этой логике есть ошибка. Мне как раз и хочется понять где она? 

Методы как таковые в обьектах не существуют. Есть только указатели на них. Эти указатели расставлены естественно ещё до вызова конструктора в зависимости от имени класса. Поэтому все они указывают на методы от A2.

Добавлено @ 14:05 
если хочешь метод родителя, то ссылайся super.testSuper();


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Omut
Дата 23.3.2007, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 22.12.2005

Репутация: нет
Всего: нет



Цитата

Может есть статья, в которой объясняется мой вопрос?

Может это поможет
Поведение полиморфных методов внутри конструкторов
Вот оттуда
Цитата

В качестве результата, хорошие руководящие принципы для конструктора "Делайте в конструкторе настолько меньше, насколько можете и если это возможно, то не вызывайте никаких методов". Существует только один тип методов, которые безопасно вызывать из конструктора, это final методы из базового класса. (Это так же применимо и к private методам, которые так же являются final.) Они не могут быть переопределены и поэтому не могут преподнести своего рода сюрприз

PM MAIL   Вверх
pompei
Дата 18.10.2007, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 7.9.2007

Репутация: 1
Всего: 6



Цитата(JVM @ 20.3.2007,  13:59)
Мои рассуждения следующие. Когда я создаю объект А2
Код

new A2();
вызывается конструктор
Код

  A2(){
    super();
    testSuper();
  }

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

A1(){
    testSuper();
  }
т.к. объект класса А2 еще не создан, то вызывается метод не А2.testSuper(), а А1. testSuper().

Но судя по результату работы программы в этой логике есть ошибка. Мне как раз и хочется понять где она?

Объясняю популярно: конструктор - это не метод который сам создаёт объект. Конструктор - это почти обычный (не статический) метод, который отличается от обычного метода тем, что:
1) вызывается особым образом (через оператор new);
2) не наследуется (т.е. конструктор делать обязательно нужно, а если Вы не указали ни одного конструктора, то компилятор создаёт конструктор по умолчанию);
3) между оператором new и вызовом конструктора происходят какие-то действия.

Теперь давайте посмотрим что детально происходит в строчке: new A2();

1) создаётся инстанция объекта класса A2 с пустыми полями (т.е. = null);
2) вызываются инициализаторы этих полей, если они есть;
3) вызывается метод-конструктор (как видите объект уже давно существует, а конструктор его только вызвался);
4) возвращается ссылка на объект, если небыло необработанных исключений.

Важно знать, что если первой строкой не стоит оператор super( ... ) в конструкторе, то там по умолчанию ставиться оператор super(); т.е. вызывается родительский конструктор по умолчанию. Если у родителя нет конструктора по умолчанию (или он не доступен), то генерируется исключение уровня компиляции.

Важно знать, что если в классе не указать ни одного конструктора, то создаётся конструктор по умолчанию, который ни чего не делает.

Важно знать, что если Вы определили какой-нибудь конструктор, отличный от конструктора по умолчанию, то конструктор по умолчанию НЕ создаётся.

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

Теперь посмотрим что же происходить в нашем случае:
1) Создаётся инстанция объекта класса А2
2) Вызывается конструктор А2
3) вызывается конструктор А1 (потому что есть super)
4) вызывается родительский к А1 конструктор по умолчанию
5) этот конструктор отрабатывает и управление возвращается к конструктору А1
6) в конструкторе А1 вызывается у объекта this метод с именем testSuper
7) т.к. this - это ссылка на объект класса А2, то поиск метода начинается с А2 - сразу находиться и вызывается метод А2.testSuper и в качестве аргумента this передается ему наш объект.
8) дорабатывает конструктор А1
9) управление возвращается в конструктор А2
10) у объекта this вызывается метод с именем testSuper
11) т.к. this - это ссылка на объект класса А2, то поиск метода начинается с А2 - сразу находиться и вызывается метод А2.testSuper и в качестве аргумента this передается ему наш объект.
12) дорабатывает конструктор А2
13) возвращается наш объект.

А вообще чтобы не париться с этими мелочами, не вызывайте в конструкторе никаких своих методов. Исключением могут быть статические методы, методы других классов, или финальные методы, которые нельзя переопределять и подобных изъянов не будет.


Это сообщение отредактировал(а) pompei - 18.10.2007, 13:28
--------------------
А всё оказывается гораздо проще: пассивные наноструктуры - активные наноструктуры - системы наносистем - молекулярные наносистемы - сингулярность! По пять лет на каждый этап.
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0759 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.