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
Форумы портала PHP.SU :: Версия для печати :: Абстрактные классы
Форумы портала PHP.SU » » Объектно-ориентированное программирование » Абстрактные классы

Страниц (1): [1]
 

1. In1ernal Error - 04 Мая, 2012 - 17:34:57 - перейти к сообщению
Доброго времени суток!

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

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

Выскажите свое мнение по поводу сабжа. Используете например вы их в своих проектах или нет? И т.д. и т.п.
2. caballero - 04 Мая, 2012 - 17:45:24 - перейти к сообщению
Цитата:
Какой смысл их использовать, если с тем же успехом можно наследоваться от обычных классов?

кроме тех случаев когда создание объекта базового класса - бессмысленно.

Цитата:
Декларация функций? Но ведь для этого есть интерфейсы, которые отлично справляются со своей задачей.

а когда нужно и тело функции а не только декларация.

Цитата:
Вот и получается, что абстрактные классы не нужны,

это у тебя так получаетсмя

Цитата:
Используете например вы их в своих проектах или нет? И т.д. и т.п.

разумеется
3. In1ernal Error - 04 Мая, 2012 - 17:47:29 - перейти к сообщению
caballero пишет:
а когда нужно и тело функции а не только декларация.


Но тогда зачем придумали трейты?
Что в итоге использовать-то я не пойму? Абстрактные классы или трейты с интерфейсами?
4. caballero - 04 Мая, 2012 - 17:52:02 - перейти к сообщению
Цитата:
Но тогда зачем придумали трейты?

при чем тут трейты?

Цитата:
Что в итоге использовать-то я не пойму?

значить тебе пока ничего не надо использовать. Когда понадобится (на практике) - ответ будет очевиден.
5. OrmaJever - 04 Мая, 2012 - 17:59:09 - перейти к сообщению
есть один класс(абстрактный), от него будут унаследованы 5 классов. В этом одном классе описываются несколько методов которые одинаковые для всех пяти наследников, но есть 3(например) метода которые разные для каждого, и без них работа класса не возможна. Вот и нужно указать что именно эти функции нужно описать + из обстрактного класса нельзя создать обьект. В некоторых cms видел один абстрактный класс core, который затем наследуют все кому не лень, но создавать обьект класса core нельзя, можно использовать абстрактность имено для запрета создания обьекта.
6. In1ernal Error - 04 Мая, 2012 - 18:26:27 - перейти к сообщению
OrmaJever пишет:
можно использовать абстрактность имено для запрета создания обьекта


Вот это уже интереснее
7. armancho7777777 - 04 Мая, 2012 - 18:49:27 - перейти к сообщению
caballero пишет:
значить тебе пока ничего не надо использовать. Когда понадобится (на практике) - ответ будет очевиден.
Согласен.
8. Мелкий - 04 Мая, 2012 - 19:45:09 - перейти к сообщению
In1ernal Error пишет:
Но тогда зачем придумали трейты?

Как костыль для множественного наследования. И интерфейсы - тоже.
Интерфейс - это и есть абстрактный класс, не имеющий реализации.
9. tato - 05 Мая, 2012 - 08:50:47 - перейти к сообщению
Цитата:
Какой смысл их использовать, если с тем же успехом можно наследоваться от обычных классов

В принципе можно наследоватся от обычного класса и не реализовывать( оставлять пустыми ) методы, которые будут перекрыты в классах потомках, НО! тогда они станут необязательными для реализации. ВАЖНО! если Мы расширяем абстрактный класс и не реализуем его абстрактные методы, то получаем ошибки т.к. реализация обязательна.
Как уже писали выше, "соль" абстракции это возможность реализовать часть методов и запретить создание экземпляров абстракции.

Цитата:
Декларация функций? Но ведь для этого есть интерфейсы

Интерфейсы существуют не только для декларации, они как и классы, по сути, являются типом данных. Так же в интерфейсе можно задать область видимости только public, в абстракции можно public, protected, что бывает весьма полезно.

Вобщем в этом коде попытался отразить все выше сказанное:
PHP:
скопировать код в буфер обмена
  1.  
  2. [spoiler]
  3. <?PHP
  4. //Абстракция Test
  5. abstract class Test {
  6.        
  7.     //Константа
  8.     const SOME_CONST = "some const";
  9.    
  10.     // защищенный метод
  11.     protected function fooProtected()
  12.     {
  13.         return "fooProtected";
  14.     }
  15.    
  16.     //Абстрактный метод, реализация обязательна
  17.     abstract public function barAbstract();        
  18. }
  19.  
  20. //Интерфейс TypeOneIface
  21. interface TypeOneIface {
  22.     function echoFoo();
  23. }
  24.  
  25. // Два класа расширяющие абстракцию
  26. // ключевое слово final говорит о том, что класс финальный и его нельзя расщирять
  27. final class TestTwo extends Test implements TypeOneIface {
  28.  
  29.     // реализация обязательного метода ( дектует интерфейс )    
  30.     public function echoFoo()
  31.     {
  32.         return self::fooProtected() . " in TestTwo<br>";
  33.     }
  34.     // реализация обязательного метода ( дектует абстракция )
  35.     public function barAbstract()
  36.     {
  37.         echo "bar in TestTwo<br>";
  38.     }    
  39. } // END_CLASS TestTwo
  40.  
  41. final class TestThree extends Test implements TypeOneIface {
  42.  
  43.     // реализация обязательного метода ( дектует интерфейс )
  44.     public function echoFoo()
  45.     {
  46.         return self::fooProtected() . " in TestThree<br>";
  47.     }
  48.     // реализация обязательного метода
  49.     public function barAbstract()
  50.     {
  51.         echo "bar in TestThree<br>";
  52.     }
  53. } // END_CLASS TestThree
  54.  
  55. // еще один тестовый класс
  56. final class LetsRock {
  57.    
  58.     // Принимаем типизированную переменную, тип есть интерфейс TypeOneIface
  59.     public function echoFoo( TypeOneIface $object )
  60.     {
  61.         echo $object->echoFoo();
  62.     }
  63.    
  64.     // Принимаем типизированную переменную, тип есть абстракция Test
  65.     public function echoBar( Test $object )
  66.     {
  67.         echo $object->barAbstract();
  68.     }
  69. }
  70.  
  71. // Let's Rock!
  72.  
  73. // наши экземпляры
  74. $test_two   = new TestTwo();
  75. $test_three = new TestThree();
  76. $lets_rock  = new LetsRock();
  77.  
  78. // Константа
  79. echo sprintf( "test two const  -> %s <br> test three const -> %s<br>", TestTwo::SOME_CONST, TestThree::SOME_CONST );
  80.  
  81. // Рвботаем с объектами
  82. $lets_rock->echoFoo( $test_two );
  83. $lets_rock->echoFoo( $test_three );
  84.  
  85. // Вариант 1
  86. echo "I<br>";
  87. $lets_rock->echoBar( $test_two );
  88. $lets_rock->echoBar( $test_three );
  89. // Вариант 2
  90. echo "II<br>";
  91. echo $test_two->barAbstract();
  92. echo $test_three->barAbstract();
  93. ?>
  94. test two const -> some const
  95. test three const -> some const
  96. fooProtected in TestTwo
  97. fooProtected in TestThree
  98. I
  99. bar in TestTwo
  100. bar in TestThree
  101. II
  102. bar in TestTwo
  103. bar in TestThree
  104. [/spoiler]
  105.  

 

Powered by ExBB FM 1.0 RC1