• ,

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

План уровня:
  • Основы ООП: перегрузка, полиморфизм, абстракция, интерфейсы.
  • Полиморфизм детально
  • Переопределение методов
  • Приведение ссылочных типов: расширение и сужение. type cast
  • Динамическая диспетчеризация методов
  • Доступ к методам базового класса — super
  • instanceof
  • Перегрузка методов
  • Абстрактные классы
  • Интерфейсы

Курс Java

Что еще можно посмотреть на досуге:
Глава «Полиморфизм» в Thinking in Java
Для чего нужен super — официальная версия
Тут можно скачать краткую инструкцию по хоткеям в IntelliJ Idea


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

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

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

47 комментариев

MrOrlov
а где собственно ссылка на лекцию то?
Razor
В адресной строке. :)
Globus51
Ссылка на:
Глава «Полиморфизм» в Thinking in Java
давно уже как не дает возможности прочитать про Полиморфизм.
Может где в другом месте можно почитать?
tsev
Thinking in Java 4th Edition подлинник на английском.
tsev
  • tsev
  • 0
  • Комментарий отредактирован 2015-01-29 13:08:44 пользователем Diana
На том же ресурсе есть альтернативная страница.
Globus51
tsev, спасибо за подсказки.

альтернативная страница — это Глава «Полиморфизм» в Thinking in Java
или это другая статья на эту же тему?
tsev
  • tsev
  • 0
  • Комментарий отредактирован 2014-02-06 00:51:26 пользователем tsev
Судя по первым строкам это она.
оригинал:
Polymorphism is the third essential feature of an object-oriented
programming language, after data abstraction and inheritance.
статья:
Полиморфизм — третья неотъемлемая часть объектно-ориентированного программирования, после абстракции и наследования соответственно.
GreySci
альтернативная страница тоже не работает
Munch
  • Munch
  • 0
  • Комментарий отредактирован 2014-03-21 11:10:07 пользователем Munch
Есть вопрос интересный:

<code>public Container(AbstractMaterial material) {
  if (material instanceof SolidMaterial)
   super(material, cargoWeight);
  // TODO Auto-generated constructor stub
 }</code>

Такой код не проходит компиляцию, так как супер должен быть первым. Что можно предложить в замен? Класс Container является тоже наследником Абстрактного класса.

Смысл в том, чтобы в Контейнер помещались только Твердые_Материалы.
darkstone
  • darkstone
  • 0
  • Комментарий отредактирован 2014-03-21 11:13:02 пользователем darkstone
public Container(AbstractMaterial material) {
  if (material instanceof SolidMaterial)
   this.Cintainer(material, cargoWeight);
  // TODO Auto-generated constructor stub
 }

public Container (SolidMaterial material, int cargoWeight) {
    super(material, cargoWeight);
}

Попробуй конструктор создай Container(SolidMaterial material, int cargoWeight) и его вызови в основном, как-то так. По коду могут быть ошибки, но мысль такая.
Munch
Не хочет так:

The method Container(SolidMaterial, int) in the type Container is not applicable for the arguments (AbstractMaterial, int)
darkstone
Ты уже работаешь смотрю? )) Круто…
Munch
Нет, прохожу тренинги. По результатам и будет решение.
hubert
Ну начнем с того, что super для твоего потомка вызывается в любом случае, пишешь ты его или нет.
Ты можешь написать нужный тебе метод в родительском классе. И вызывать его вместо
super(material, cargoWeight);
Munch
В классе-родитеел супер — конструктор.
darkstone
  • darkstone
  • 0
  • Комментарий отредактирован 2014-03-21 14:49:19 пользователем darkstone
Попробуй то, что hubert говорит. Создай метод в родительском классе, а в if вставь вызов метода из родительского класса(в котором будет соотв-нно использоваться родительский конструктор и произведены нужные действия).
darkstone
  • darkstone
  • 0
  • Комментарий отредактирован 2014-03-21 15:41:22 пользователем darkstone
И да, правильно поправили) Родительский (или другой) конструктор всегда вызывается только первой строкой, по другому нельзя никак. Даже если ты во втором конструкторе класса используешь первый конструктор того же класса, то ссылка на конструктор всё равно должна идти первой строкой:

private String name;
private int age;
public Human(int a) {
    age = a;
}

public Human(String name, int a) {
    this(a);
    this.name = name;
}
darkstone
А почему нельзя проверку перед созданием контейнера сделать? И вообще зачем вызывать конструктор, если уже создан контейнер(раз мы уже в конструкторе находимся)? Если нельзя проверить до вызова, то создай контейнер типа AbstractMmaterial, проверь на instanceof и если да, то new Container(SolidMaterial material).
Munch
  • Munch
  • 0
  • Комментарий отредактирован 2014-03-21 11:32:23 пользователем Munch
Пробую так:

public Container (AbstractMaterial material, int cargoWeight, int width, int length, int heigth) {
		if (material instanceof SolidMaterial){
			this.Container(material, cargoWeight, width, length, heigth);
		}
		  // TODO Auto-generated constructor stub
	}

	public Container (SolidMaterial material, int cargoWeight, int width, int length, int heigth) {
		   super(material, cargoWeight);
		   this.width = width;
		   this.heigth = length;
		   this.length = heigth;
		   this.cargoWeight = cargoWeight;
	}


Ругается:
The method Container(AbstractMaterial, int, int, int, int) is undefined for the type Container
Juggee
Лекция 12, статья «Полиморфизм», таблица.
class abstract ChessItem implements Drawable, HasValue 

не должен ли класс наследовать еще и интерфейс Element(описан выше данного)? или только его. Было бы логично — все методы оттуда реализованы в потомке (getX, getY + из Drawable и HasValue).
adabizha
  • adabizha
  • 0
  • Комментарий отредактирован 2014-04-29 14:32:16 пользователем adabizha
Друзья, помогите, пожалуйста разобраться.
В лекции №12 сказано, что наследовать и переопределять можно только не статические методы. Так же говориться, что статические методы не наследуются и, следовательно, не переопределяются.
Решил проверить. У меня всё наследуется и переопределяется:
<code>
public class Parent {

    public static void method()
    {
        System.out.println("Method.");
    }
    public static void print()
    {
        System.out.println("In Parent.");
    }
}

public class Heir extends Parent
{
    public static void print(String str)
    {
        System.out.println(str);
    }

    public static void print()
    {
        System.out.println("In Heir.");
    }
}

public class Main {
    public static void main(String[] args) throws Exception {

        Heir heir = new Heir();

        heir.method();
        heir.print();
        heir.print("In Main.");
    }
}
</code>
Вот вывод:
«C:\Program…
Method.
In Heir.
In Main.

Process finished with exit code 0

Где ошибка?
igor
Ты неправильно понимаешь, что такое переопределение методов.
igor

     class Parent {

        public static void method()
        {
            System.out.println("Method in Parent.");
        }
            }

    class Heir extends Parent
    {
        public static void method()
        {
            System.out.println("In Heir. Overridden");
        }
    }

    public class Main {
        public static void main(String[] args) throws Exception {

            Parent heir = new Heir();

            heir.method();

        }
    }


Вывод:Method in Parent.

class Parent {

        public void method()
        {
            System.out.println("Method in Parent.");
        }
            }

    class Heir extends Parent
    {
        public void method()
        {
            System.out.println("In Heir. Overridden");
        }
    }

    public class Main {
        public static void main(String[] args) throws Exception {

            Parent heir = new Heir();

            heir.method();

        }
    }

Вывод:In Heir. Overridden
Статик метод, который будет вызываться определяется типом, а не объектом.
И вообще вызывать статик метод от объекта неправильно.=)
adabizha
Это понятно, и объясняется тем, что эти методы расположены в стеке.
Просто, прочитав «что статические методы не наследуются и, следовательно, не переопределяются» я не совсем понял о чем идёт речь.
Спасибо за ответ.
Ruzveld
  • Ruzveld
  • 0
  • Комментарий отредактирован 2014-06-20 19:54:18 пользователем Ruzveld
Думаю, каждый, кто попробует испытать код из уроков про интерфейсы, столкнется с ошибкой компиляции при объявлении методов классов, унаследованных от интерфейсов. Как написали здесь, это происходит потому, что к каждому методу интерфейса неявно приписывается публичный уровень доступа, поэтому попытка объявить метод без модификатора public приведет к ошибке.
Например
<code>interface WallBuilder
{
    void buildWall();
}
class Robot implements WallBuilder
{
    //void buildWall(); - ТАК НЕЛЬЗЯ
    public void buildWall(); //надо так
}</code>

Наверное есть смысл упомянуть об этом в самом уроке.
vector9
  • vector9
  • 0
  • Комментарий отредактирован 2015-02-16 00:38:48 пользователем vector9
Ruzveld до речі цікава примітка з вашого боку. Дійсно варто про це згадати в уроці.
Ну і наостанок потрібно реалізувати метод buildWall
<code>interface WallBuilder
{
    void buildWall();
}
abstract class Robot implements WallBuilder
{
    //void buildWall(); - ТАК НЕЛЬЗЯ
    public abstract void buildWall(){} //надо так
}</code>
або зробити метод і клас абстрактними
<code>interface WallBuilder
{
    void buildWall();
}
abstract class Robot implements WallBuilder
{
    //void buildWall(); - ТАК НЕЛЬЗЯ
    public abstract void buildWall(); //надо так
}</code>
Odnolap
  • Odnolap
  • 0
  • Комментарий отредактирован 2015-03-15 02:25:10 пользователем Odnolap
Все таки считаю некорректным утверждение «Статические методы не наследуются и, следовательно, не переопределяются» в первом уроке «Полиморфизм и переопределение». Потому как если написать класс A со статическим методом method, потом написать класс B extends A, в котором методов не создавать, после чего вызвать B.method(), то мы получим выполнение действий, указанных в реализации этого метода в классе A.
public class A
{
 public static void method()
 { 
 System.out.println(«class A»);
 }
}

public class B extends A 
{
}

public static void main(String[] args)
{
 B.method();
}

Вывод:
class A
Что это, если не наследование статического метода?
С другой стороны, напиши мы реализацию этого метода в B, то есть переопредели его, то при вызове B.method, мы получим выполнение действий, описанных в реализации класса B. Что это, если не переопределение статического метода?
public class A
{
    public static void method()
    { 
        System.out.println("class A");
    }
}

public class B extends A 
{
    public static void method()
    { 
        System.out.println("class B");
    }
}

public static void main(String[] args)
{
    B.method();
}

Вывод:
class B
Да, если в этом случае создать экземпляр класса B в переменной класса A и вызвать у нее этот статический метод, то вызовется реализация, описанная в классе A
A a = new B();
a.method;

Вывод:
class A
Но тут надо просто сказать, что при вызове статического метода у переменной компилятор вместо нее подставляет ее тип, и не смотрит, что в ней содержится. Т.е. следующин 2 вызова статических методов аналогичны:
//1
A a = new B();
a.method();
//2
A.method();
IgorBrest
Возможно, в той лекции имеется ввиду переопределение (замена) и наследование методов на уровне полиморфизма.
Для статических методов механизм динамической диспетчеризации не применим, по определению.
а значит полиморфизм для них не работает. как то так…
mTihiy
Корректен ли пример применяемый в лекции, где кит наследуется от коровы?
в «Философии Java» и других источниках написано, что наследование применяется там, где есть связь «является».
Кит ведь не является коровой.
alhabor
Плюсую, тоже обратил внимание. В Дополнительных материалах к лекции 11 есть линк на статью, откуда цитата: «Если у нас есть классы А и В и если класс А „не является“ разновидностью класса В, то А не должен быть подклассом В. (Grady Booch, Object-Oriented Analysis and Design with Applications)». И в первой же лекции 12 уровня идёт пример про кита, наследующегося от коровы.
crivenco
Ссылка Тут можно скачать краткую инструкцию по хоткеям в IntelliJ Idea — не работает
Akira
Только что скачал себе в закладки)видимо починили либо был временный сбой)
WhiteSteel
В первом уроке этого уровня, 3-й пункт «Приведение типов», по-моему написан с грамм. ошибкой «Т.к. класс при наследовании получает все методы и данные класса родителя, то объект этого класса разрешается сохранять (присваивать) в переменные класса родителя». буква «у» слову ОБЪЕКТ в студию!
mrserfr
нет здесь ошибки
mrserfr
class A {}
class B extends A {}
A a = new B();
WhiteSteel
ну ок. раз уж ты здесь. то смотри. @Override "+ имяМетода" мы пишем, только когда наследуемся от абстрактного класса?
mrserfr
я не понял вопроса…

@Override — означает, что мы переопределяем метод, описанный в суперклассе
mrserfr
class A {
    void move(){
        System.out.println("move");
    }
}

class B extends A {
    @Override
    void move(){
        System.out.println("don't move");
    }
}
DmitryChVW
  • DmitryChVW
  • 0
  • Комментарий отредактирован 2016-03-30 15:04:03 пользователем DmitryChVW
Помогите пожалуйста разобраться в понятиях сужения и расширения ссылочных типов. Есть разногласие в этих понятиях в лекции 12 данного курса и по ссылке http://old.intuit.ru/department/pl/javapl/7/2.html
В лекции сказано следующее:

А на intuit.ru следующее, то есть всё наоборот, поменяны понятия сужения и расширения типов:


То есть в лекции 12 переход от производного класса (дети) к базовому (родители) называют «классическим сужением типа», а на интуите «переход от детей к родителям» называют расширением. Где же правильно, или что-то я не правильно понимаю? Спасибо
Adelaida
  • Adelaida
  • 0
  • Комментарий отредактирован 2016-03-30 17:46:01 пользователем Adelaida
Запомни главное правило:
Набор методов, которые можно вызвать у переменной, определяется типом переменной. А какой именно метод/какая реализация вызовется, определяется типом/классом объекта, ссылку на который хранит переменная
На мой взгляд ДжаваРаш в лекции имели в виду Расширение/Сужение с точки зрения выбора доступных методов у преобразованной переменной (здесь: теперь у Кита будут методы Кита и Коровы).
А вообще да — когда преобразовывают к наследнику это нисходящее преобразование и наоборот.
estetne
Сначала меня запутало
class Child extends (расширяет) Parent

теперь это…
Я считаю правильно так: от общего к конкретному – сужение типов, а с точки зрения доступных методов назвали бы расширение функциональности/ возможностей/ содержимого типа.
Denk
А уровни 11 и 12 пошустрее идут, прошел два за один день, и задачи решил на половину.
mrANDERSON
  • mrANDERSON
  • 0
  • Комментарий отредактирован 2016-06-07 23:06:40 пользователем mrANDERSON
Доброго времени суток!
Как Вы думаете дженерики это все-таки полиморфизм или нет?)
Akira
Имхо-да.
Tatiana_Tatiana
Я тоже прошла уровни 11 и 12 за два дня, с легкостью решала практически все задачки. Меня не отпускает ощущение, что я о полиморфизме, интерфейсах, абстрактных методах узнала только теорию, а тренировалась на написании синтаксиса. На каждую темку несколько одинаковых задачек, расставить кодовые слова и т.п. Задачек по смыслу не было не одной! Или с таким багажом (10 уровней) нельзя пока ничего написать по смыслу, и смысловые задачки будут позже? Может кто-нибудь прокомментировать?
Akira
Сам надолго застрял на последней задачке 20 уровня. Сейчас вот дело сдвинулось с мертвой точки. Про следующие уроки слышал, что они состоят из много мелких, но объединенных в одну большую. Возможно как раз в них и возможно отработать принципы)
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.