• ,

Уровень 15: план уровня и доп. материалы

План уровня:
  • Перегрузка методов, особенность вызова конструкторов
  • Модифиаторы доступа public, protected, модификатор по умолчанию (package), private
  • Неявная реализация абстрактного метода
  • Расширение видимости
  • Расширение типа результата, возвращаемого методом
  • Перегрузка методов
  • Порядок вызова конструкторов
  • статический блок
  • Порядок инициализации данных

Курс Java

Что еще можно посмотреть на досуге:
Инициализация членов класса

Отличная подборка историй трудоустройства учеников JavaRush. Почитайте обязательно!



Нашли классную ссылку к материалу данной темы? Добавьте ее сюда в виде комментария.
Возможно, именно Ваша ссылка поможет другому человеку стать программистом и улучшить свою жизнь!

Вернуться к плану обучения

Вернуться к обучению java онлайн на JavaRush

32 комментария

demydd
не працює лінк на додатковий матеріал «Инициализация»
phashik
  • phashik
  • 0
  • Комментарий отредактирован 2014-03-12 00:39:02 пользователем phashik
Что-то я не понял в лекции про вызов Cat.print(null)
Показаны две ситуации.
В первой
null не имеет определенного типа и компилятор откажется компилировать этот код
А во второй
ошибки компиляции не будет и вызовется метод print(String s), что несколько неочевидно
И никаких объяснений, почему же случается такая неочевидность :(
Maksim_Bardin
phashik, могу предположить, что в первом случае null можно присвоить как переменной Integer, так и переменной String, в плане приоритета эти два присваивания равнозначны, и возникает неопределенность. Если удалить один из этих методов, то код компилируется без ошибок, как и во втором случае.
MindIbniM
спасибо, тоже интересовал этот вопрос
cyrillkurochkin
  • cyrillkurochkin
  • 0
  • Комментарий отредактирован 2015-01-09 21:53:05 пользователем cyrillkurochkin
Спасибо, неожиданная неопределенность null — это сильно!
Надо бы внести ясность в саму лекцию.
UnLim
Попробую объяснить…
При поиске вызываемого метода, Java ищет самый широкий тип принимаемого параметра,
совместимый с типом передаваемой переменной (или объекта).
В данном случае null совместим и с Object и со String, но String шире Object,
т.к. наследуется от него, поэтому выбирается метод print(String s)
cyrillkurochkin
Спасибо, я уже капнул глубже, но, ИМХО, это все же должно быть в лекции, или в доп. материалах.
ikratkoe
Все бы хорошо в вашем объяснении, если бы в этой же лекции, чуть ранее, про ту же строчку Cat.print(null); было сказано «В четвертом случае у нас неопределенность. null не имеет определенного типа, компилятор откажется компилировать этот код.»…
mrANDERSON
Всегда можно посмотреть, что скажет Идеа, а говорит она, что подходят оба метода и неизвестно какой вызывать. А во втором случае однозначно можно определить, что String «шире» Object и нужно вызывать его. Т.е. String и Integer равнозначны, а
String и Object нет.
Maksim_Bardin
У меня вопрос по лекции «Порядок инициализации переменных».
Вот например если так:
public class Temp1
{
    public int getD()
    {
        return d;
    }

    public int a = getD();
    public int b = d;
    public int d = 4;
}

Почему в случае присваивания переменной a значения переменной d через функцию все нормально (a = 0),
а в случае присваивания переменной b значения переменной d компилятор пишет ошибку?
Если класс загружается сверху вниз, то d неизвестна ни там ни там. Судя по всему в случае использования функции применяется какой-то другой механизм?
Sant9Iga
при использовании метода, переменная d проинициализируется по умолчанию. а если ты просто присваиваешь одну переменную другой(непроинициализированной) тогда выдается ошибка компиляции.
немного похожий баг еще есть вот в такой штуке:
public class Temp1
{
    public int getD()
    {
        boolean s = false;
        while(true){
            if(s){
                break;
            }
        }
        return d;
    }

    public int a = getD();
    public int b = d;
    public int d = 4;
}

в вайле у тебя никогда иф не выполнится, и будет бесконечный цикл. Но если ты иф отсюда уберешь, тогда опять таки будет ошибка компиляции. Тебе подчеркнет эту строку:
return d;

и скажет что никогда не выполнится эта строка.
Maksim_Bardin
Sant9Iga, спасибо.
tarrus
Оставьте хоть какие нибудь ссылки где можно почитать про эти темы в лекции.
Nazgul
Будем ли мы дальше проходить регулярные выражения и что посоветуете почитать на эту тему?
frey
Присоединяюсь к вопросу. Очень актуально.
frey
Отвечаю сам себе — будем. Почитать — вот это www.ozon.ru/context/detail/id/4858175/
Izhak
Спасибо, скачал. Очень даже.
Spitfire
А каким образом происходит расширение типа, для классов-оберток над примитивными типами?
Вот пример кода:
public static void main(String[] args){
        print((Byte)(byte)1);
        
    }

    public static void print(int i)
    {
        System.out.println("int");
    }

    public static void print(Short i)
    {
        System.out.println("Short");
    }

Он выводит на экран
int
что для меня стало неожиданностью — не думал, что объектный тип будет «расширен» до примитивного.
Кто-то может рассказать, какая процедура расширения в таких случаях?
gnev
вообще IDEA подсвечивает кастование в (Byte), считая эту операцию лишней. А если так, то обертывания не происходит.
Izhak
в лекции Создание объектов. Порядок вызова конструкторов два раза повторяется одна и та же таблица.
hhp
  • hhp
  • 0
Помогите разобраться — почему в main метод me.getMyParent() возвращает ссылку на Cat, а не на Tiger?
Ведь me фактически ссылается на Tiger, т.е при вызове метода
getMyParent() в процессе работы программы определяется фактический класс объекта(а он Tiger) и должен вызваться метод именно класса Tiger, который должен вернуть ссылку на Tiger, а не на Cat.
В последней строчке в main при попытке присвоить Tiger myParent = me.getMyParent(); компилятор подчеркивает и пишет:
«Incopatible types. Required: Tiger. Found: Cat»

public class Solution
{
    public static void main(String[] args)
    {
        Tiger parent = new Tiger();

        Cat me = new Tiger();
        me.setMyParent(parent);
        Tiger myParent = me.getMyParent();
    }
}

class Cat
{
    public Cat parent;
    public Cat getMyParent()
    {
        return this.parent;
    }
    public void setMyParent(Cat cat)
    {
        this.parent = cat;
    }
}

class Tiger extends Cat
{
    public Tiger getMyParent()
    {
        return (Tiger)this.parent;
    }
}
Butman
Ты ведь создаешь Cat me = new Tiger();
То есть создаешь объект Tiger но присваиваешь его переменной типа Cat. Соответственно ты можешь вызвать методы только класса Cat. Поэтому при вызове метода me.getMyParent() отрабатывает метод public Cat getMyParent(). Чтобы вызвать именно public Tiger getMyParent() нужно расширить тип переменной.
И именно поэтому выдает ошибку «Incopatible types. Required: Tiger. Found: Cat» так как ты пытаешся присвоить переменной типа Tiger значение переменной типа Cat, здесь опять же требуется расширить тип переменной «me».
Sant9Iga
asolovey
В этой статье по ссылке об инициализации, есть такой пример:

//: initialization/ArraysOfPrimitives.java
// Массивы простейших типов.
import static net.mindview.util.Print.*;
 
public class ArraysOfPrimitives {
  public static void main(String[] args) {
    int[] a1 = { 1, 2, 3, 4, 5 };
    int[] a2;
    a2 = a1;
    for(int i = 0; i < a2.length; i++)
      a2[i] = a2[i] + 1;
    for(int i = 0; i < a1.length; i++)
      print("a1[" + i + "] = " + a1[i]);
  }
}
<spoiler text="Output:">

a1[0] = 2
a1[1] = 3
a1[2] = 4
a1[3] = 5
a1[4] = 6


Не могу понять, почему такой вывод, если мы присваиваем значения элементов массива a1 элементам массива a2. Ведь a1 по идее значения при этом не должны меняться. Объясните, пожалуйста.
German_lbt
все тривиально просто… Вы присвоили к а2 ссылку на a1… другими словами вы объявили две ссылки на массив примитивов… вот скажем у Вас есть имя (да точно есть), и вы объявили что к Вам также можно обращаться по псевдониму…
asolovey
Спасибо. Примерно понял.
artemtimac
В лекции Порядок загрузки классов, статические данные сказано, что статические переменные нельзя инициализировать в конструкторе, поэтому применяются статические блоки. Разъясните этот момент, пожалуйста, т.к. у меня свободно получается делать это в конструкторе, или я, видимо, не понял, что имелось ввиду.
IvanRychkov
  • IvanRychkov
  • +1
  • Комментарий отредактирован 2015-04-15 01:59:49 пользователем IvanRychkov
Здесь имеется в виду то, что класс при загрузке, в отличие от создаваемого объекта, не использует конструктор, но вместо этого можно добавить статические блоки, которые выполняют функцию инициализации статических полей(или делают ещё что-нибудь полезное)

public class Solution {

    static int A;
    static {
        System.out.println("Я - класс, я загрузился");
        A = 5;
    }
    
    public Solution(){
        System.out.println("Я - объект, меня создали");
    }
}
broke
У меня такой вопрос: тоже в лекции Порядок загрузки классов, статические данные
class Cat
{
 public static int catCount = 0 ;
 public static String namePrefix;

 static
 {
  Properties p = new Properties();
  p.loadFromFile("cat.properties");
  namePrefix = p.get("name-prefix");
 }

 <strong>public static int maxCatCount = 50;</strong>

 static
 {
  Properties p = new Properties();
  p.loadFromFile("max.properties");
  if (p.get("cat-max") != null)
   maxCatCount = p.getInt("cat-max");
 }

}

строка public static int maxCatCount = 50; уже проинициализировала переменную почему продолжает выполнятся статический блок? может "= 50" здесь лишнее?
xgrothx
public class Solution {
    public static void main(String[] args) {
        printMatrix((Double) 2.0, (Double) 3.0, "8");
        
    }

    public static void printMatrix(Integer m, Integer n, String value) {
        System.out.println("Integer");
    }
    
    public static void printMatrix(double m, double n, String value) {
        System.out.println("Double");
    }
    
    public static void printMatrix(Number n, Number m, String value) {
        System.out.println("Number");
    }


Да, очень странно. Вывод на экран:
Number


Почему так происходит? Примитивы и обертки очень странно себя ведут с точки зрения обывательской логики)
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.