4000 грн на місяць

принцип постановки (полиморфизм) на пальцах

  • Автор теми Автор теми beerofeel
  • Дата створення Дата створення
Статус: Офлайн
Реєстрація: 26.07.2010
Повідом.: 52
принцип постановки (полиморфизм) на пальцах

Привет.

Ребята, читаю 7-е издание Java 2 Библиотека профессионала. Основы.
страница 201.

Не могу понять (вникнуть) предложение: объект подкласса можно использовать вместо любого объекта суперкласса.

Пример который приводится ниже строчкой для меня полностью понятен. Подкласс Manager ЯВЛЯЕТСЯ (принадлежит) суперклассу Employee. Т.е. подкласс содержит в себе все члены суперкласса Employee.

Можно какой-то пример? Честно, не очень понял, что такое полиморфизм (я новичок). Понял только:

1) переопределение методов (или замещение методов)

2) переменная суперкласа может ссылаться на объекты суперкласса и на объекты любых объектов подклассов:

Manager manager = new Manager(...);
EmployeeManager[] employee = new EmployeeManager(3);
employee[0] = manager;
employee[1] = new EmployeeManager(...);

3) Объект подкласса можно присвоить переменной суперкласса.

EmployeeManager employee = new Manager(...);

в этом случае нельзя будет использовать методы подкласса Manager, т.к. суперкласс не имеет метода setBonus();

Все три пункта понимаю, но с одним предложением никак не могу разобраться. Можно разжевать? :)
 

Вкладення

  • 28.03.webp
    28.03.webp
    126.7 КБ · Перегляди: 123
  • 12456dfsdf.webp
    12456dfsdf.webp
    66.6 КБ · Перегляди: 72
Останнє редагування:
Поехали.

1. EmployeeManager - это базовый класс, он же суперкласс, не имеет метода setBonus()

2. Manager - унаследованный класс ака подкласс. Хранит бонус, обладает методом setBonus() и перекрывает getSalary(), чтобы учесть бонус.

3. Ты объявляешь массив суперклассов. Злобная ява считает, что там суперклассы и по умолчанию будет думать, что ты обращаешься именно к ним.

4. В один из элементов этого массива внедрился подкласс. Это не смертельно, это LSP, поскольку подкласс умеет все, что умел суперкласс.

5. Если тебе нужно просто получить зарплату сотрудников, ты во всем массиве спокойно вызываешь getSalary(). Он будет вызываться оригинальный, или перекрытый для подкласса.

6. Если ты хочешь установить бонус менеджеру, тебе придется намекнуть, что в этом элементе вообще-то не суперкласс, а подкласс, а он умеет немножко больше. То есть прямым кастингом:

((Manager ) employee[0]).setBonus(1200)

Сработает, потому что на 0-м элементе и сидит подкласс. Не сработает для 1 элемента, выпадет Exception, потому что там суперкласс.

Чтобы Exception не было, лучше так:

if( employee[0] instanceOf Manager ) {
((Manager ) employee[0]).setBonus(1200);
}
 
Achenar

Большое спасибо за ответ, очень доходчиво!

Получается что третий пункт был у меня неправильный.

3) Объект подкласса можно присвоить переменной суперкласса.

EmployeeManager employee = new Manager(...);

в этом случае нельзя будет использовать методы подкласса Manager, т.к. суперкласс не имеет метода setBonus();
можно, по приведённой схеме
((имя подкласса)переменная подкласса, ссылка на объект).getBonus(500);

Странно, что в книге не показано такое обращение к методу. Или это появилось в J2SE 6?

Я всё равно не понимаю это предложение:
объект подкласса можно использовать вместо любого объекта суперкласса.

у нас есть объект подкласса Manager

Manager manager = new Manager("Max", 1000, 2010, 11, 2);

покажите, пожалуйста, несколько примеров, как можно использовать объект подкласса вместо любого объекта суперкласса.

Спасибо за Ваше время. :)

P.S.> Прошу прощения, я новичок в Java. Никогда не имел дела с ООП, поэтому некоторые вещи доходят не сразу. 0=)
 
Останнє редагування:
По-моему, приведение типов есть в любом языке с самых первых версий. Возможно, в книге есть, надо просто поискать.

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

Фактический тип переменной может совпадать с заявленным, а может быть типом подкласса - потому что у подкласса есть те же методы и открытые поля.

Разница между заявленным и фактическим - первый однозначно понятен еще на этапе компиляции, второй известен только в рантайме. Именно поэтому на этапе компиляции нельзя написать setBonus() для элемента массива суперклассов - потому что сама возможность вызова этого метода будет проверяться только после запуска программы.

Чтобы написать корректный пример, мне J# ставить надо, то есть только вечером и дома :)
 
В последнем произведении ,которое вызвало у меня особый интерес ,есть один недостаток, не указан автор книг ,чтение которых воспитывает такое мирозрение в области программирования.Мой интересс вызван предположением о том, что этот автор никому еще не известен ,и книги также от него не существуют
 
Тыемураз,
⚠ Тільки зареєстровані користувачі бачать весь контент та не бачать рекламу.
 
Ребята, читаю 7-е издание Java 2 Библиотека профессионала. Основы.
Переходи на оригиналы как можно скорее.
Будет намного проще и не придется решать ребусы "что и куда имел этот переводчик, а что тот".
 
Не могу понять (вникнуть) предложение: объект подкласса можно использовать вместо любого объекта суперкласса.

тут понимается что в код который работает с объектом класса A, можно передавать объект класса B, при условии что B является наследником от A
 
Переходи на оригиналы как можно скорее.
Будет намного проще и не придется решать ребусы "что и куда имел этот переводчик, а что тот".
Да, перевод извратный, еще и напечатали черт знает на чем, газеты и то качественней делают.
 
Тыемураз,
⚠ Тільки зареєстровані користувачі бачать весь контент та не бачать рекламу.

Безусловно, книги прекрасны ,подстроены под реального читателя.Читай и будь продвинутым , хлопай челси ,ешь колбаса из кожа невыросшего животного ,лакомся курочкой.
Но это так, ничего по сравнению с тем что потеряешь ,и потом уже никогда не вернешся к Ассемблеру. А это то,что помогает вникать в свойства и характеристики обьекта ,программированием которого занимаешся.А все остальное вверх переходящее -есть временное ,переходящее с одного цвета в другой ,пока есть тот,кто сходит по нему со школы.
Я никак не пойму ,как можно подвергать сомнению все это.

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

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

Фактический тип переменной может совпадать с заявленным, а может быть типом подкласса - потому что у подкласса есть те же методы и открытые поля.

Разница между заявленным и фактическим - первый однозначно понятен еще на этапе компиляции, второй известен только в рантайме. Именно поэтому на этапе компиляции нельзя написать setBonus() для элемента массива суперклассов - потому что сама возможность вызова этого метода будет проверяться только после запуска программы.

Чтобы написать корректный пример, мне J# ставить надо, то есть только вечером и дома :)

Мы еще раз внимательно вникли в смысл произведения и пришли к выводу ,что явился зародыш -семечко, с которого прорастет большой подсолнух великого класса базы ,где будут сохранены правила приведения типов .
 
Мураз, уймись, здесь не шла речь о ссылках, указателях и метаданных. У человека был вопрос, я ответил так, как предположительно ему будет проще понять. Можешь объяснить лучше - объясни лучше, он спасибо скажет.
 
Achenar

Большое спасибо. :)
Я ждал от Вас ещё несколько примеров. Наверное были заняты.
 
Был. Вчера устал очень. Может, сегодня осилю, если еще нужны.
 
Мураз, уймись, здесь не шла речь о ссылках, указателях и метаданных. У человека был вопрос, я ответил так, как предположительно ему будет проще понять. Можешь объяснить лучше - объясни лучше, он спасибо скажет.

Не барское это дело ,зачем мне тогда учить кого то и воспитывать.
Пусть они работают и набираются опыта, в отражении своего процесса во вне.
Ты можешь защитить изображение от перекопирования ,выложенное в сетях или где угодно ?
И это возможно.Это целая оправданная система ,представь себе,то что видит твой глаз,невозможно повторить,даже в случае ,если приставить фотоаппарат и сфоткать.
 
Achenar

((имя подкласса)переменная подкласса, ссылка на объект).getBonus(500);

кстати, похоже очень на преобразование из одного типа в другой, например

double i = 1,5;
int x = int(i);
 
И это возможно.Это целая оправданная система ,представь себе,то что видит твой глаз,невозможно повторить,даже в случае ,если приставить фотоаппарат и сфоткать.

Ух ты! Если бы не зажимал системы за 6000 баксов, то службы безопасности всего мира уже давно были бы без работы и наступил бы мир во всем мире. Ай да негодяй жадный .:D Небось ждет когда Израиль 6500 предложит.
 
Парни, боксерский ринг в соседней теме, тут аудитория :)

beerorfeel, кинь взор на этот код. J# express у меня от 2005 года, for ( : ) не понимает, я обычным циклом написал. List<> у нее тоже не видать. Но не в них суть.
Код:
package LSPexample;

import java.util.*;

// человек, у которого есть только имя - и все. Таких в природе не существует, потому что еще зарплата нужна
public abstract class Human
{
	private String _name;

	protected Human(String name)
	{
		_name = name;
	}

	// но мы даже не представляем, как ее платить. Он же просто человек.
	public abstract double getSalary();

	// но представиться он может
	public String getName()
	{
		return _name;
	}
}

// а это уже рабочий. Немножко больше, чем человек
public class Worker extends Human
{
	private double _salary;
	
	// и зарплата в нем имеется
	public Worker(String name, double salary)
	{
		super(name);
		_salary = salary;
	}

	// и он даже может ее показать общественности. 
	public double getSalary()
	{
		return _salary;
	}

	// имя свое он знает и может представиться - как человек.
}

// Менеджер. Ему повезло, он не такой как все, он работает в офисе
public class Manager extends Worker
{
	// ява не понимает, что если не оформлять пустой конструктор, то конструктор берется из суперкласса. Это вам не C#
	// приходится писать такое. И уклоняться от тапков.
	public Manager(String name, double salary)
	{
		super(name, salary);
	}
	
	// бонус нет смысла делать приватным в этом примере, все равно придут и спросят. И установят таким, каким захотят. Даже отрицательным :)
	public double Bonus;

	// его зарплата считается не как у рабочего. Менеджер ведь
	public double getSalary()
	{
		return super.getSalary() + Bonus;
	}

}

public class Department
{
	private Human[] _people;

	// создаем 10 рабочих мест и сразу нанимает 2 рабочих и 2 менеджера
	public Department()
	{
		_people = new Human[10];
		_people[0] = new Worker("worker1", 1000);
		_people[1] = new Worker("worker2", 1200);
		_people[2] = new Manager("manager1", 1500);
		_people[8] = new Manager("manager2", 1700);

		
		// бонус, конечно, лучше было бы в конструкторе потребовать, но тогда нет смысла в этих строчках, а они нужны для примера
		((Manager)_people[2]).Bonus = 200;
		((Manager)_people[8]).Bonus = 150;
		
		double wage = 0;
		double bonus = 0;
		for( int i = 0; i < _people.length; ++i )
		{
			if ( _people[ i ] != null ) 
			{
				// сколько всем им надо заплатить в месяц?
				wage += _people[i].getSalary();

				if (_people[i] instanceof Manager)
				{
					// а сколько из этих денег бонусных ?
					bonus += ((Manager)_people[i]).Bonus;
				}
			}
		}
	}
}

Вот что там в массиве теперь творится:

⚠ Тільки зареєстровані користувачі бачать весь контент та не бачать рекламу.
 
Хтож в гуртожитку хозяин ,я нияк не розумив ,як шо и в сосидний кимнати жарют картоплю ?
 
Achenar

Спасибо, очень доходчиво показана программа. :) Прям, можно в учителя брать.
 
Achenar

Спасибо, очень доходчиво показана программа. :) Прям, можно в учителя брать.

Я присоединяюсь к Вашему пожеланию и также высказываю мнение по включению его в преподовательский состав средней категории.
 
Назад
Зверху Знизу