• ,

Проектирование Классов и Интерфейсов (Перевод статьи)

Исходная статья: www.javacodegeeks.com/2015/09/how-to-design-classes-and-interfaces.html

Эта статья является частью нашего Курса Академии под названием «Продвинутая Java».
Этот курс призван помочь вам наиболее эффективно использовать Java. В нем обсуждаются передовые темы, такие как создание объекта, взаимосовместимость(параллелизм), преобразование в последовательную форму, отражение и многое другое. Это будет вашим путеводителем в вашем путешествии к мастерству в Java. Убедись сам!


Содержание

  1. Введение
  2. Интерфейсы
  3. Интерфейс-маркеры
  4. Функциональные интерфейсы, статические методы и методы по умолчанию
  5. Абстрактные классы
  6. Неизменяемые (постоянные) классы
  7. Анонимные классы
  8. Видимость
  9. Наследование
  10. Множественное наследование
  11. Наследование и композиция
  12. Инкапсуляция
  13. Final классы и методы
  14. Что дальше
  15. Скачать исходный код

Помогите советом, не могу понять с какой целью код написан именно так:

Добрый день! Есть код задачки (задание не имеет значения):

public static void main(String[] args)
    {
        Pet pet = new Cat();
        System.out.println(cat.getName());
    }

    public static class Pet
    {
        здесь был метод
    }

    public static class Cat extends Pet
    {
        здесь было переопределение метода
    }


Так вот что-то меня переклинило, почему при создании экземпляра класса Cat мы используем тип переменной Pet? Что от этого меняется? Почему нельзя было просто Cat имя_переменной = new Cat()? Вроде подобное встречалось и раньше, но я как-то не заострял внимания. Что я пропустил на пути обучения? Подскажите, пожалуйста, что прочитать повторно (сейчас на 12-м уровне). Спасибо!

Вопросы про synchronized

Возникло несколько вопросов по теме synchronized.


Вопрос 1
Предположим, у нас есть объект класса, в коде которого изменяется строка как предложено ниже.
public class Exxample1 extends Thread{
        public String stroka;

        public void run()
        {
            <...>
            stroka=stroka+" "; //(1)
            <...>
            synchronized(stroka)
            {
                stroka=stroka+" ";

            }
        }

    }

Объект этого класса одновременно используют сразу несколько нитей. Первая нить добралась до блока synchronized и заблокировала строку. Это значит, что все другие нити
  • не смогут зайти внутрь этого блока, пока первая нить не закончит свою работу в нем (заснут)
  • не смогут использовать строку stroka, где бы ее не вызвали(заснут). То есть команда (1) не будет выполнена пока первая нить не выйдет из блока.
  • оба пункта
  • другое
Вопрос 2
У нас есть объект класса, который используется одновременно несколькими нитями (код класса ниже)
public class Example2 extends Thread
    {
        public void run()
        {
            <...>
            synchronized(this)
            {
                <...>
            }
        }
    }

Какие утверждения, приведенные ниже верны.
Когда одна из нитей заходит в блок synchronized…
  • все остальные нити, которые уже работают с этим объектом заснут
  • нити, уже использующие этот объект продолжат свою работу, но новые будут ждать разблокировки объекта (заснут)
  • все нити, использующие этот объект или только собирающиеся его использовать заснут (объединение первых двух пунктов)
  • другое

Вопрос 3
Ниже приведен код класса, объект которого используется несколькими нитями одновременно.
public class Example3 extends Thread
    {   public String s;
        public int k;

        private String word;
        public void run()
        {
            <...>
            synchronized (s)
            {
                <...>
            }
            <...>


            synchronized (this)
            {
                <...>
            }
        }
    }

Одна из нитей заходит в первый блок synchronized и блокирует строку. В этот момент другая нить заходит во второй блок и пытается заблокировать весь объект, но строка s уже заблокирована. Что же произойдет?
  • вторая нить все равно заблокирует весь объект, первая — заснет
  • вторая нить все равно заблокирует весь объект, первая продолжит свою работу (а что тогда с s? будет использоваться обеими нитями или заблокирована для всех?)
  • вторая нить заснет, будет ждать выхода первой нити из блока
  • другое

Вопрос 4
Если использовать synchranized в описании метода, то когда нить вызовет этот метод, все треды, использующие объект, в котором описан данный метод, заснут? (Вроде ответ должен быть аналогичен ответу 2ого вопроса)
Спасибо за ваши ответы. Тема, действительно, сложная и несколько мутная. Надеюсь на ваше понимание. Кстати, можете подкинуть доп. ссылок или литературы на эту тему (коме уже указанных в JavaRush).
  • ,

level14.lesson08.home02

package com.javarush.test.level14.lesson08.home02;

/* Дегустация вин
1. Создать абстрактный класс Drink с реализованным методом public void taste(), который выводит в консоль "Вкусно"
2. Создать класс Wine, который наследуется от Drink, с реализованным методом public String getHolidayName(), который возвращает строку "День рождения"
3. Создать класс BubblyWine, который наследуется от Wine, с реализованным методом public String getHolidayName(), который возвращает строку "Новый год"
4. Написать реализацию методов getDeliciousDrink, getWine, getBubblyWine
5. Каждый класс и интерфейс должны быть в отдельных файлах
6. Метод main менять нельзя!
*/



public class Solution {
    public static void main(String[] args) {
        getDeliciousDrink().taste();
        System.out.println(getWine().getHolidayName());
        System.out.println(getBubblyWine().getHolidayName());
        System.out.println(getWine().getHolidayName());
    }

    public static Drink getDeliciousDrink() {
       return new Wine();}

    public static Wine getWine() {
        return new Wine();}

    public static Wine getBubblyWine() {
        return new BubblyWine();}
}


public abstract class Drink {
    public void taste(){
        System.out.println("Вкусно");
    }
}


<code public String getHolidayName(){
return «Новый год»;
}>

public String getHolidayName(){
        return "Новый год";
    }

public String getHolidayName(){
        return "Новый год";
    }