Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737 Форумы портала PHP.SU :: помогите с наследованием
Покинул форум
Сообщений всего: 17
Дата рег-ции: Май 2011
Помог: 0 раз(а)
Здравствуйте! Начинаю разбираться с ООП, и вот бьюсь уже не первый день:
задача: создать такой экземпляр класa Ship, чтобы он имел методы fly() и Shoot(), определенные в классах Weapons и Engines, свойство mass, определенное в классах Weapons и Engines, а Weapons и Engines могли пользоваться свойством ID (типа parent::$ID)
объекта Ship, определенное в его конструкторе.
Но как я не бьюсь-ничего не выходит, то дочерний класс не знает ID экземпляра родительского класса, то родительский класс не знает методов дочерних классов, в общем я окончательно запутался и зашел в тупик Помогите пожалуйста разобраться и изящным способом решить задачу
DlTA
Отправлено: 27 Января, 2012 - 11:10:37
Постоянный участник
Покинул форум
Сообщений всего: 2952
Дата рег-ции: Окт. 2010
Помог: 53 раз(а)
Цитата:
function Weapons () {
parent::$mass += 20;
}
это не правильный конструктор
если хотелось чет типа подобного
то надо было у базового объявить __construct($ID=0)
с функционалом function Ship
а у дочерних
__construct($ID=0){
parent::__construct($ID);
parent::$mass += 20;
...
}
как то так
а лучше наверное даже
__construct($ID=0){
parent::__construct($ID);
$this->$mass += 20;
...
}
Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009 Откуда: Россия, Санкт-Петербург
Помог: 618 раз(а)
pome, вы совсем не поняли идеи наследования.
Наследование используется, когда у вас главное орудие какое-нибудь и пулемёт. Между ними много общего, это общее объединяют в базовый класс "оружие" и расширяют и конкретизируют в дочерних. Базовый класс зачастую вообще не используется в явном виде нигде.
А когда что-то включает в себя что-то другое - это ни в коем случае не наследование, это - включение. У корабля есть оружие, но оружие не есть корабль (впрочем, для торпеды это спорное утверждение ).
Так, вы создаёте корабль, затем (например, в конструкторе) определяете внутренний член (рационально использовать массив, ведь на корабле не 1 орудие?) оружием (new turrel, являющаяся дочерним классом от weapon), от этого оружия уже получаете его массу и прибавляете его к массе корабля.
В методе shoot корабля вы проверяете, есть ли у него оружие и, если есть, производите выстрел методом уже именно объектом орудия.
----- PostgreSQL DBA
pome
Отправлено: 27 Января, 2012 - 11:46:58
Новичок
Покинул форум
Сообщений всего: 17
Дата рег-ции: Май 2011
Помог: 0 раз(а)
Цитата:
а зачем пользоваться именно родительским ID?
пользуйтесь тем что было наседовано
через $this->ID
Вся идея в том, что объект Ship должен быть единым объектом и иметь в себе много разных методов, которые подключаются "навешиванием" всякого оборудования, и, например, выстрелив, оружие должно отнять у Ship, например, энергию, а у другому экземпляру Ship нанести повреждение. При этом хочется добиться двусторонней связью между наследниками Ship
//загружаем параметры оружия пользователя parent::$ID
$this->power=-25;
$this->energy=-10;
}
function shoot ($targetID){
parent::Energy->get_energy($this->energy);
$ship[$targetID]->set_shoot($this->power);
}
}
$ship[5]->Weapons->shoot(7);//корабль 5 стреляет в корабль 7
PS. Представленные коды прошу не рассматривать как рабочий код без ошибок, а лишь как пример для того чтобы показать чего я хочу добиться
Самогонщик
Отправлено: 27 Января, 2012 - 12:00:15
Посетитель
Покинул форум
Сообщений всего: 495
Дата рег-ции: Окт. 2011
Помог: 8 раз(а)
pome, создай класс оружия и навешивай его наследников на корабль. То, что в первом посте, совершенно не неверное использование наследования, как и сказал Мелкий.
У вас есть два пути:
1. создать наследников оружия с различными параметрами, но наследоваться ради переопределения параметров не круто, проще использовать один класс и настраивать его параметры.
2. Оружие инициализировать указателем на корабль, тогда оно (оружие) сможет совершать с кораблём хитрые манипуляции.
Т.к. во втором случае образуется циклическая ссылка (корабль содержит оружие, оружие ссылается на корабль), Для разрешения цикла, для корабля создаётся интерфейс, с которым и работает оружие ничего не зная о реализации корабля. (Добавление)
Во втором случае можно будет переопределять поведение, скажем одно оружие просто забирает энергию и наносит урон, а другое стреляет ракетами и требует наличия ракет на складе нужного типа, треть оставляет мину и т.д. Учитывать все эти вариации поведения в классе корабля, не очень хорошо. Проще перенести в оружие, наследники класса оружие могут переопределять метод апдате (к примеру) и вести себя по разному в зависимости от реализации.
pome
Отправлено: 27 Января, 2012 - 12:06:25
Новичок
Покинул форум
Сообщений всего: 17
Дата рег-ции: Май 2011
Помог: 0 раз(а)
Цитата:
Наследование используется, когда у вас главное орудие какое-нибудь и пулемёт. Между ними много общего, это общее объединяют в базовый класс "оружие" и расширяют и конкретизируют в дочерних. Базовый класс зачастую вообще не используется в явном виде нигде.
Да, видимо не догнал маленько...
теперь получается каждый предмет оборудования должен хранить в явном виде ID корабля на котором он установлен для того чтобы обращаться к другим предметам этого корабля и делать это через
$this->Energy->get_energy($enrgy);//вот это, по идее, можно было сделать в Weapon->shoot, но тогда нужно иметь ссылку на объект Energy...
$ship[$targetID]->set_shoot($hit);
}
function set_shoot ($hit){
$this->hit+=$hit;
}
}
Но в этом случае класс Ship будет перегружен кодом, так как частично функционал оборудования нужно будет описывать в самом классе Ship (Добавление) Самогонщик То есть вот так будет правильно:?
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.