Правила     Закладки     Карма    Календарь    Журналы    Помощь    Поиск    PDA    Чат   
        СМС-ки
   
Пейджер выключен!
Страницы: (2) [1] 2  ( Перейти к первому непрочитанному сообщению )  
Фильтр авторов:    показать 
  скрыть
  Ответ в темуСоздание новой темыСоздание опроса

> Простая задача для реализации в ООП
glock18  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Be prepared
******

Профиль
Группа: Эксперт
Группа переписки
Сообщений: 5199
Пользователь №: 17723
На форуме: 7 лет, 8 месяцев, 5 дней
Карма: 57




Не далее как недавно мне товарищ, Krevedko напомнил про задачу по ООП, которую я ему давал месяца два назад. А сейчас он мне предложил выложить ее здесь, чтобы любой мог ее попробовать. Идея понравилась - почему бы и нет smile.gif

Постановка задачи:
Реализовать структуру классов геометрических фигур для подсчета их периметра и площади.
Необходимые фигуры - круг, квадрат и треугольник.
Обязательные условия:
1. Использовать наследование (один родительский класс)
2. Полиморфизм. Кто не знает что - почитать. Смысл: для подсчета площади/периметра любой из фигур должен использоваться один интерфейс (метод в данном контексте).

3. Естественно, дополнительно нужен код демонструрующий их применение.

Входные данные (читать из файла):
одна или более строк в следующем формате
<название фигуры> <параметры> \n

Выходные:
список фигур и их периметр и площадь.

Это сообщение отредактировал glock18 - 20.11.2009 - 01:37
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Joker  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Программист маньяк
******

Профиль
Журнал
Группа: Форумчанин
Завсегдатай форума
Сообщений: 1718
Пользователь №: 17079
На форуме: 7 лет, 10 месяцев, 8 дней
Карма: 6

Трезвый :
8 лет, 14 дней


А какие входные данные то? будет картинка с фигурами (круг, квадрат и треугольник.) или параметры этих фигур?
PMПисьмо на e-mail пользователюСайт пользователя
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
glock18  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Be prepared
******

Профиль
Группа: Эксперт
Группа переписки
Сообщений: 5199
Пользователь №: 17723
На форуме: 7 лет, 8 месяцев, 5 дней
Карма: 57




Joker
Спасибо, дописал.
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Joker  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Программист маньяк
******

Профиль
Журнал
Группа: Форумчанин
Завсегдатай форума
Сообщений: 1718
Пользователь №: 17079
На форуме: 7 лет, 10 месяцев, 8 дней
Карма: 6

Трезвый :
8 лет, 14 дней


Ну вот примеры записи так?) я правильно понел?)

пример записи для круга

Цитата

circle 40

Где circle это название фигуры а 40 это диаметр круга.

пример записи для квадрата

Цитата

square 40

Где square это название фигуры а 40 это сторона квадрата.

Цитата

triangle 5 10 75

Где triangle это название фигуры а 5 это сторона треугольника 10 это вторая сторона треугольника и 75 это угол между эти двумя сторонами.

PMПисьмо на e-mail пользователюСайт пользователя
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
glock18  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Be prepared
******

Профиль
Группа: Эксперт
Группа переписки
Сообщений: 5199
Пользователь №: 17723
На форуме: 7 лет, 8 месяцев, 5 дней
Карма: 57




Вполне)))
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Michael  
[x] Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Эксперт
Группа переписки
Сообщений: 6073
Пользователь №: 18498
На форуме: 7 лет, 5 месяцев, 21 день
Карма: 256




Ну наконец то полиморфизм программирую на php rolleyes.gif
Описание классов:

class Figure
{
protected $type = '';
public function getArea() {}
public function getPerimeter() {}
public function getType()
{
if ($this->type == '') return 'Неопределен';
else return $this->type;
}
}


class Square extends Figure
{
private $side;
function __construct($a = 0)
{
$this->type = '';
$a = floatval($a);
if ($a > 0)
{
$this->type = 'Square';
$this->side = $a;
}
}

public function getArea()
{
if (!$this->type) return '';
return $this->side * $this->side;
}
public function getPerimeter()
{
if (!$this->type) return '';
return $this->side * 4;
}
}


class Circle extends Figure
{
private $radius;
function __construct($r = 0)
{
$this->type = '';
$r = floatval($r);
if ($r > 0)
{
$this->type = 'Circle';
$this->radius = $r;
}

}

public function getArea()
{
if (!$this->type) return '';
return M_PI * $this->radius * $this->radius;
}

public function getPerimeter()
{
if (!$this->type) return '';
return 2 * M_PI * $this->radius;
}
}


class Triangle extends Figure
{
private $a, $b, $c;
function __construct($a = 0, $b = 0, $c = 0)
{
$this->type = '';
$a = floatval($a); $b = floatval($b); $c = floatval($c);
if (($a > 0 ) && ($b > 0) && ($c > 0))
{
$p = ($a + $b + $c) / 2; // полупериметр
if (($p > $a ) && ($p > $b) && ($p > $c))
{
$this->type = 'Triangle';
$this->a = $a;
$this->b = $b;
$this->c = $c;
}
}
}


public function getArea()
{
if (!$this->type) return '';
$p = ($this->a + $this->b + $this->c) / 2; // полупериметр
return sqrt($p * ($p - $this->a) * ($p - $this->b) * ($p - $this->c)); // формула Герона
}

public function getPerimeter()
{
if (!$this->type) return '';
return $this->a + $this->b + $this->c;
}
}


Вызов:

$x = ''; // будет массивом объектов разного типа
$f = file('file.txt');
foreach ($f as $val)
{
$who = explode(',', trim($val));
$who[] = 0; $who[] = 0; $who[] = 0; // если не корректный ввод (особо не проверяю)
switch ($who[0])
{
case 'circle':
$x[] = new Circle($who[1]);
break;
case 'square':
$x[] = new Square($who[1]);
break;
case 'triangle':
$x[] = new Triangle($who[1], $who[2], $who[3]);
break;
}
}

if ($x)
{
foreach ($x as $v)
{
echo $v->getType(), ' , Площадь=', $v->getArea(), ' , Периметр=', $v->getPerimeter(), '<br>';
}
}



Входные данные file.txt:
circle,10
square,20
triangle,5,6,7
circle,4
circle,6
square,7
triangle,13,12,7

Результат:
Circle , Площадь=314.15926535898 , Периметр=62.831853071796
Square , Площадь=400 , Периметр=80
Triangle , Площадь=14.696938456699 , Периметр=18
Circle , Площадь=50.265482457437 , Периметр=25.132741228718
Circle , Площадь=113.09733552923 , Периметр=37.699111843078
Square , Площадь=49 , Периметр=28
Triangle , Площадь=41.569219381653 , Периметр=32

P.S. Треугольник задаю сторонами smile.gif


--------------------
There never was a struggle in the soul of a good man that was not hard
PM
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
glock18  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Be prepared
******

Профиль
Группа: Эксперт
Группа переписки
Сообщений: 5199
Пользователь №: 17723
На форуме: 7 лет, 8 месяцев, 5 дней
Карма: 57




Цитата
P.S. Треугольник задаю сторонами

имхо формула Герона наиболее удобна здесь smile.gif +1

В целом неплохо. Но:
1. проперти $type совсем ни к чему. только лишние проблемы приносит. для определения типа можно было использовать не захардкоженные строки, а константу __CLASS__ или функцию get_class

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

2. $x объявлен не массивом. а строка в свою очередь тоже массив. в этом свете строки
$x = '';
$x[] = new Circle();

выглядяет не очень

3. Figure не помешало бы сделать абстрактным. А так же его методы для подсчет периметра и площади.

в остальном задача решена так, как я и ожидал smile.gif
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Krevedko  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Тупая креведко
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 1905
Пользователь №: 18200
На форуме: 7 лет, 6 месяцев, 20 дней
Карма: 37




полный трындец...я вот уже подумываю не сдавать конкурсную работу, а то с моим ооп (с маленькой буквы) стыдно будет совсем blink.gif unsure.gif
копчиком чувствую, что там все неправильно, но пока не могу понять.
попытаюсь код босса уровня понять...если честно что-то брезжит... biggrin.gif

...гм.. а вообщем-то все более понятно, чем я ожидал.
PMПисьмо на e-mail пользователюСайт пользователя
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
linker  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Эксперт
Группа переписки
Сообщений: 5790
Пользователь №: 22814
На форуме: 6 лет, 6 месяцев, 20 дней
Карма: 264




Ну что можно сказать на первый взгляд:

1. Figure в абстракцию, а значит и все его методы тоже сделать абстрактными.
2. Выкинуть абсолютно бесполезную конструкцию
if (!$this->type) return '';
в методах getArea, getPerimeter
3. Выкинуть все выражения в конструкторах аля $a = floatval($a); $b = floatval($b); $c = floatval($c);, вместо них делать, как делают нормальные люди:
new Circle((float)$who[1]);
new Square((float)$who[1]);
new Triangle((float)$who[1], (float)$who[2], (float)$who[3]);

4. Вместо этого куска
$who[] = 0; $who[] = 0; $who[] = 0;
лучше
if (empty($val)) { continue; }

5. Создание экземпляров классов лучше вынести в фабрику.

Это только на первый взгляд.

Это сообщение отредактировал linker - 28.06.2010 - 16:55


--------------------
PMПисьмо на e-mail пользователюСайт пользователяICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Shuriken  
[x] Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 257
Пользователь №: 17632
На форуме: 7 лет, 8 месяцев, 17 дней
Карма: 7




Привет всем! Решаю данную задачу, но программа выдаёт ошибку

Fatal error: Cannot redeclare func_area() (previously declared in K:\home\localhost\www\1.php:12) in K:\home\localhost\www\1.php on line 27

Вот код:

header("Content-Type: text/html; charset=utf-8"); 
class Figure {
var $area;
var $perimetr;
}

class Circle extends Figure {
var $radius;
function Circle($r) {
function func_area() {
$this->area=M_PI*pow($r,2);
echo "Круг: Площадь = $this->area ";
}
function func_perim() {
$this->perimetr=2*M_PI*$r;
echo "Периметр = $this->perimetr.<br>";
}
}
}




class Square extends Figure {
var $a;
function Square($x) {
function func_area() {
$this->area=pow($x,2);
echo "Квадрат: Площадь = $this->area ";
}
function func_perim() {
$this->perimetr=4*$x;
echo "Периметр = $this->perimetr.<br>";
}
}
}



class Triangle extends Figure {
var $a;
var $b;
var $angle;
function Triangle($x,$y,$z) {
function func_area() {
$this->area=0.5*$x*$y*sin(deg2rad($z));
echo "Треугольник: Площадь = $this->area ";
}
function func_perim() {
$this->perimetr=$x+$y+sqrt(pow($x,2)+pow($y,2)-2*$x*$y*cos($z));
echo "Периметр = $this->perimetr.<br>";
}
}
}



$f=fopen("input.txt","r+");

while (!feof($f)) {
$in=explode (",",fgets($f));
switch ($in[0]) {
case circle: {
$out=new Circle ($in[1]);
}
break;
case square: {
$out=new Square($in[1]);
}
break;
case triangle: {
$out=new Triangle($in[1],$in[2],$in[3]);
}
break;
}
}


Что не так?

До введения конструктора программа работала нормально, а вот с добавлением конструктора выдаёт ошибку.

Это сообщение отредактировал Shuriken - 16.08.2012 - 10:40
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Winston  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме




******

Профиль
Группа: Эксперт
Группа переписки
Сообщений: 9509
Пользователь №: 18161
На форуме: 7 лет, 6 месяцев, 24 дня
Карма: 552




Вообще то уже давно есть версия PHP5, зачем ты пишешь под PHP4 не понятно.
И еще, где ты видел, чтобы методы были реализованы в конструкторе? blink.gif



Спустя 9 минут, 42 секунды Winston написал(а):
Цитата (Winston @ 16.08.2012 - 11:12)
И еще, где ты видел, чтобы методы были реализованы в конструкторе?

Или ты анонимные функции заделал? biggrin.gif
PMСайт пользователя
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Shuriken  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 257
Пользователь №: 17632
На форуме: 7 лет, 8 месяцев, 17 дней
Карма: 7




Цитата (Winston @ 16.08.2012 - 08:12)
Вообще то уже давно есть версия PHP5, зачем ты пишешь под PHP4 не понятно.
И еще, где ты видел, чтобы методы были реализованы в конструкторе?  blink.gif

Я только учусь. В теорию по ООП не совсем въехал, разбираюсь на практике.

Для PHP5 конструктор пишется function __construct?

В конструкторе можно делать только присвоение и расчёты?
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Winston  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме




******

Профиль
Группа: Эксперт
Группа переписки
Сообщений: 9509
Пользователь №: 18161
На форуме: 7 лет, 6 месяцев, 24 дня
Карма: 552




Цитата (Shuriken @ 16.08.2012 - 11:23)
Для PHP5 конструктор пишется function __construct?

Да, а еще расставляются модификаторы доступа.
Цитата (Shuriken @ 16.08.2012 - 11:23)
В конструкторе можно делать только присвоение и расчёты?

Можно делать все, что можно в обычных функциях/методах
PMСайт пользователя
    1   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Shuriken  
[x] Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 257
Пользователь №: 17632
На форуме: 7 лет, 8 месяцев, 17 дней
Карма: 7




Переделал код вот таким образом:


header("Content-Type: text/html; charset=utf-8");
class Figure {
var $area;
var $perimetr;
}

class Circle extends Figure {
var $radius;
function __construct($r) {
$this->radius=$r;
}
function func() {
$this->area=M_PI*pow($this->radius,2);
echo "Круг: Площадь = $this->area ";
$this->perimetr=2*M_PI*$this->radius;
echo "Периметр = $this->perimetr.<br>";
}
}




class Square extends Figure {
var $a;
function __construct($x) {
$this->a=$x;
}
function func() {
$this->area=pow($x,2);
echo "Квадрат: Площадь = $this->area ";
$this->perimetr=4*$x;
echo "Периметр = $this->perimetr.<br>";
}
}



class Triangle extends Figure {
var $b;
var $c;
var $angle_bc;
function __construct($x,$y,$z) {
$this->b=$x;
$this->c=$y;
$this->angle_bc=$z;
}
function func() {
$this->area=0.5*$this->c*$this->b*sin(deg2rad($this->angle_bc));
echo "Треугольник: Площадь = $this->area ";
$this->perimetr=$this->c+$this->b+sqrt(pow($this->c,2)+pow($this->b,2)-2*$this->c*$this->b*cos($this->angle_bc));
echo "Периметр = $this->perimetr.<br>";
}

}



$f=fopen("input.txt","r+");

while (!feof($f)) {
$in=explode (",",fgets($f));
switch ($in[0]) {
case circle: {
$out=new Circle ($in[1]);
$out->func();
}
break;
case square: {
$out=new Square($in[1]);
$out->func();
}
break;
case triangle: {
$out=new Triangle($in[1],$in[2],$in[3]);
$out->func();
}
break;
}
}




Исходные данные:
circle,3
square,2
triangle,2,3,30

Результат:
Круг: Площадь = 28.2743338823 Периметр = 18.8495559215.
Квадрат: Площадь = 0 Периметр = 0.
Треугольник: Площадь = 1.5 Периметр = 8.33900922451.

Всё правильно исходя из условия задачи?

Это сообщение отредактировал Shuriken - 16.08.2012 - 12:06
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Игорь_Vasinsky  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Лысый и злой
******

Профиль
Журнал
Группа: ★ЛжеЭксперт★
Завсегдатай форума
Сообщений: 26041
Пользователь №: 21350
На форуме: 6 лет, 10 месяцев, 3 дня
Карма: 726

Не курю:
1 год, 3 месяца, 20 дней


Цитата
square,2

Цитата
Квадрат: Площадь = 0 Периметр = 0.


--------------------
Халявные ответы кончились.
Если нужен готовый код - готовьтесь заплатить.
Райкин тоже был артист

Возле дома был сарай
А когда всё хорошо
Можно просто покурить

user posted image
http://ufa102.xyz/
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
  Быстрый ответ
Информация о Госте
Введите Ваше имя
Кнопки кодов
Для вставки цитаты, выделите нужный текст и
НАЖМИТЕ СЮДА
Введите сообщение
Смайлики
:huh:  :o  ;) 
:P  :D  :lol: 
B)  :rolleyes:  <_< 
:)  :angry:  :( 
:unsure:  :blink:  :ph34r: 
     
Показать всё

Опции сообщения  Включить смайлики?
 Включить подпись?
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:

Опции темыСтраницы: (2) [1] 2  Ответ в темуСоздание новой темыСоздание опроса