1

Тема: Де використовувати абстрактні класи, а де інтерфейси?

Привіт. Сьогодні йду додому з однокурсником, і почав пояснювати йому за класи, інтерфейси, та наслідування. Хтів привести два приклада, де треба використати наслідування класу, і де треба використовувати наслідування інтерфейсу, в результаті сам заплутався.
Я так розумію, всі ці наслідування треба використовувати як для виключення дублювання кода, так і для створення абстракції. В мене приклад був такий: є два види м'ячів, перший - дерев'яний, а другий - гумовий. Нам не зручно використовувати два контейнера для обох видів м'ячів і необхідно абстрагувати їх до одної сутності - мяч. Для цього я б використав абстрактний класс, і вийшло б щось типу цього

class Program
    {
        static void Main(string[] args)
        {
            ball[] i = new[] {(ball)new WoodenBall(),new RubberBall()};
            foreach (var b in i)
            {
                Console.WriteLine(b.GetBall());
            }
            Console.Read();
        }
    }

    abstract class ball
    {
        public abstract string GetBall();
    }

    class WoodenBall:ball
    {
        public override string GetBall()
        {
            return "WoodenBall";
        }
    }

    class RubberBall : ball
    {
        public override string GetBall()
        {
            return "RubberBall";
        }
    }

А потім я хтів придумати приклад з використанням інтерфейсу, але чомусь не зміг. Звичайно, я можу замінити абстрактний клас на інтерфейс з сигнатурою одного метода, потім по різному реалізувати цей метод в відповідних класах, що наслідують той інтерфейс і в мене вийде те ж саме, що й з абстрактним класом. Навіщо ж тоді мені той інтерфейс взагалі потрібен? Я знаю, що можна наслідуватись від декількох інтерфейсів, але не зовсім розумію, де це може знадобитись?

All you want is a dingle,
What you envy's a schwang,
A thing through which you can tinkle,
Or play with, or simply let hang...

2

Re: Де використовувати абстрактні класи, а де інтерфейси?

Абстрактний клас може містити неабстрактні методи, інтерфейси - ні.
Клас може наслідувати кільком інтерфейсам, але тільки одному класу.

3

Re: Де використовувати абстрактні класи, а де інтерфейси?

koala написав:

Абстрактний клас може містити неабстрактні методи, інтерфейси - ні.
Клас може наслідувати кільком інтерфейсам, але тільки одному класу.

а можна наслідуватись від інтерфейса і від класу одночасно?

All you want is a dingle,
What you envy's a schwang,
A thing through which you can tinkle,
Or play with, or simply let hang...

4

Re: Де використовувати абстрактні класи, а де інтерфейси?

Так, цілком. В цьому і ідея. Головне - не тягнути дві реалізації в один клас, там починаються проблеми зі спільними предками (ну... не зовсім проблеми, але плутанини багато).

5

Re: Де використовувати абстрактні класи, а де інтерфейси?

koala написав:

Так, цілком. В цьому і ідея. Головне - не тягнути дві реалізації в один клас, там починаються проблеми зі спільними предками (ну... не зовсім проблеми, але плутанини багато).

а можете зробити маленький приклад, де доцільно використовувати саме інтерфейси?

All you want is a dingle,
What you envy's a schwang,
A thing through which you can tinkle,
Or play with, or simply let hang...

6 Востаннє редагувалося koala (04.11.2013 22:07:38)

Re: Де використовувати абстрактні класи, а де інтерфейси?

Вашій ілюстрації не вистачає ланок. Припустимо, у нас є ще "твердий м'яч", "кам'яний м'яч", "твердий предмет",  і "залізний куб". Тупий твердий предмет - інтерфейс, який реалізовують дерев'яні, залізні і кам'яні предмети. Абстрактний клас твердий м'яч, зокрема, наслідує одночасно м'ячу і твердому предмету. Дерев'яний і кам'яний м'ячі наслідують твердому предмету. Класи "м'яч" і "твердий м'яч" можуть мати методи з реалізацією (наприклад, обчислити об'єм чи поверхню), але мають і абстрактні члени. Твердий предмет містить тільки абстрактні методи. Залізний куб - твердий предмет, але з повною реалізацією.

7

Re: Де використовувати абстрактні класи, а де інтерфейси?

koala написав:

Вашій ілюстрації не вистачає ланок. Припустимо, у нас є ще "твердий м'яч", "кам'яний м'яч", "твердий предмет",  і "залізний куб". Тупий твердий предмет - інтерфейс, який реалізовують дерев'яні, залізні і кам'яні предмети. Абстрактний клас твердий м'яч, зокрема, наслідує одночасно м'ячу і твердому предмету. Дерев'яний і кам'яний м'ячі наслідують твердому предмету. Класи "м'яч" і "твердий м'яч" можуть мати методи з реалізацією (наприклад, обчислити об'єм чи поверхню), але мають і абстрактні члени. Твердий предмет містить тільки абстрактні методи. Залізний куб - твердий предмет, але з повною реалізацією.

Щиро дякую, зара важко це все зрозуміти, як висплюсь, то перечитаю знову.

All you want is a dingle,
What you envy's a schwang,
A thing through which you can tinkle,
Or play with, or simply let hang...

8

Re: Де використовувати абстрактні класи, а де інтерфейси?

спробуємо так:

abstract class Ball;
interface HardObject;
abstract class HardBall:Ball, HardObject;
class RubberBall:Ball;
class WoodenBall:HardBall;
class StoneBall:HardBall;
class IronCube:HardObject;

Домашнє завдання: придумати абстрактні методи для всіх абстрактних класів і інтерфейсів. Придумати неабстрактні методи для всіх класів (абстрактних и неабстрактних).

9 Востаннє редагувалося FakiNyan (05.11.2013 01:31:17)

Re: Де використовувати абстрактні класи, а де інтерфейси?

koala написав:

спробуємо так:

abstract class Ball;
interface HardObject;
abstract class HardBall:Ball, HardObject;
class RubberBall:Ball;
class WoodenBall:HardBall;
class StoneBall:HardBall;
class IronCube:HardObject;

Домашнє завдання: придумати абстрактні методи для всіх абстрактних класів і інтерфейсів. Придумати неабстрактні методи для всіх класів (абстрактних и неабстрактних).

не розумію, навіщо мені це -_-

using System;


namespace polymorph
{
    class Program
    {
        static void Main(string[] args)
        {           
            Ball[] balls=new Ball[3];
            balls[0]=new WoodenBall();
            balls[1]=new StoneBall();
            balls[2]=new RubberBall();
            foreach (var ball in balls)
            {
                ball.AbstractBallSay();
            }
            HardObject hardObject=new IronCube();
            hardObject.HardObjectSay();
            Console.Read();
        }
    }

    abstract class Ball
    {
        public void BallSay()
        {
            Console.Write("hello i'm ball");
        }

        public abstract void AbstractBallSay();
    }

    interface HardObject
    {
        void HardObjectSay();
    }

    abstract class HardBall : Ball, HardObject
    {
        public void HardObjectSay()
        {
            Console.Write(" and i'm hard");
        }

        public override void AbstractBallSay()
        {
            BallSay();
            HardObjectSay(); 
        }

        public abstract void HardBallSay();
    }

    class RubberBall : Ball
    {
        public void RubberBallSay()
        {
            Console.WriteLine(", also i'm Rubber ball"); 
        }
        public override void AbstractBallSay()
        {
            BallSay();
            RubberBallSay();
        }
    }

    class WoodenBall : HardBall
    {
        public void WoodenBallSay()
        {
            Console.Write(", also i'm Wooden ball ");
        }

        public override void HardBallSay()
        {
            Console.WriteLine("so i'm hard ball");
        }

        public override void AbstractBallSay()
        {
            BallSay();     
            HardObjectSay();
            WoodenBallSay();
            HardBallSay();
        }
    }

    class StoneBall : HardBall
    {
        public void StoneBallSay()
        {
            Console.Write(", also i'm Stone ball ");
        }

        public override void HardBallSay()
        {
            Console.WriteLine("so i'm hard ball");
        }

        public override void AbstractBallSay()
        {
            BallSay();
            HardObjectSay();
            StoneBallSay();
            HardBallSay();
        }
    }

    class IronCube : HardObject
    {
        public void HardObjectSay()
        {
            Console.WriteLine("i'm not ball, i'm cube, hard cube");
        }
    }

}
Post's attachments

ss (2013-11-05 at 12.30.03).png 29.31 kb, 53 downloads since 2013-11-05 

All you want is a dingle,
What you envy's a schwang,
A thing through which you can tinkle,
Or play with, or simply let hang...

10

Re: Де використовувати абстрактні класи, а де інтерфейси?

Ви формально поставилися до завдання. Я не казав писати реалізації, до речі. А треба було задати методи, притаманні кожному об'єкту. Наприклад, у всіх м'ячів можна обчислити об'єм за відомою формулою одразу. Тверді тіла можуть, наприклад, ламати одне одного. А дерев'яний м'яч може, до того, ще й згоріти.

11

Re: Де використовувати абстрактні класи, а де інтерфейси?

koala написав:

Ви формально поставилися до завдання. Я не казав писати реалізації, до речі. А треба було задати методи, притаманні кожному об'єкту. Наприклад, у всіх м'ячів можна обчислити об'єм за відомою формулою одразу. Тверді тіла можуть, наприклад, ламати одне одного. А дерев'яний м'яч може, до того, ще й згоріти.

ну так це ж вже фізика якась

All you want is a dingle,
What you envy's a schwang,
A thing through which you can tinkle,
Or play with, or simply let hang...

12

Re: Де використовувати абстрактні класи, а де інтерфейси?

А у вас лінгвістика, кулі говорять і все :)

13

Re: Де використовувати абстрактні класи, а де інтерфейси?

FakiNyan написав:
koala написав:

Ви формально поставилися до завдання. Я не казав писати реалізації, до речі. А треба було задати методи, притаманні кожному об'єкту. Наприклад, у всіх м'ячів можна обчислити об'єм за відомою формулою одразу. Тверді тіла можуть, наприклад, ламати одне одного. А дерев'яний м'яч може, до того, ще й згоріти.

ну так це ж вже фізика якась

дерев'яний м'яч - це взагалі упоротість

Психологічні бесіди з додатковою послугою промивання мізків. Недорого.
Не дизайню. Взагалі ні разу. У назві розділу "Дизайн та графіка" є слово "графіка" - ось тут трохи шарю. І не більше. Так, часто питають.
Продам гараж

14

Re: Де використовувати абстрактні класи, а де інтерфейси?

Cyan написала:

дерев'яний м'яч - це взагалі упоротість

Ви не повірите, які варіанти були до поширення гуми...

15

Re: Де використовувати абстрактні класи, а де інтерфейси?

ну то просто знаєте шо. в грі ж мають бути там різні персонажи з різними можливостями, то я через то  й питаю про ті наслідування. Мають же бути різні там раси, класи персонажів, і вони ще можуть бути жінкою або мужіком. і то треба так зробити, щоб був один такий клас з назвою Персонаж, а від нього там вже наслідуются три різні класи, ну чи скільки там рас буде, я взагалі раси не люблю в іграх, краще зробити більше класів, але щоб всі персонажи людьми були. Так от значить Персонажи діляться на декілька класів, і кожний з класів може бути або дівкою або хлопцем. То це ж можна зробити два інтерфейси, наприклад, або один абстрактний клас - Персонаж, і два інтерфейси - Чоловік і Жінка, а потім, наприклад, класу Нідзя! буде наслідуватись два класа - НіндзяЧоловік і НіндзяЖінка, ну то буде типу так виглядати

abstract class Character{}
interface Male{}
interface Female{}
class Ninja:Character{}
class NinjaMale:Ninja,Male
class NinjaFemale:Ninja,Female

ну і там якісь методи наробити. Ех, скоріше б я здав там один пратівний екзамен і почав би робити оце все, ліл.

All you want is a dingle,
What you envy's a schwang,
A thing through which you can tinkle,
Or play with, or simply let hang...

16

Re: Де використовувати абстрактні класи, а де інтерфейси?

Якщо вам треба робити повний мікс властивостей, то це не наслідуванням краще, а агрегацією:

abstract class Sex
class Male:Sex
class Female:Sex
abstract class Speciality
class Ninja:Speciality
class Character
{
  Sex sex;
  Speciality speciality;
}
...
myCharacter.sex=new Male();
myCharacter.speciality=new Ninja();
myCharacter.sex.fallInLove(...);
Подякували: FakiNyan1

17

Re: Де використовувати абстрактні класи, а де інтерфейси?

koala написав:

Якщо вам треба робити повний мікс властивостей, то це не наслідуванням краще, а агрегацією:

abstract class Sex
class Male:Sex
class Female:Sex
abstract class Speciality
class Ninja:Speciality
class Character
{
  Sex sex;
  Speciality speciality;
}
...
myCharacter.sex=new Male();
myCharacter.speciality=new Ninja();
myCharacter.sex.fallInLove(...);

а  я чомусь от як почав розбиратися з тими інтерфейсами і наслідуваннями, подумав, що теперь будь-яку задачу мона робити з їх допомогою, але бачу, що це не так, треба думати і робити так, як вийде краще, а не тулити купу інтерфейсів і т.д. Але знаєте в чому моя проблема? В тому що я не можу знайти оту золоту середину, ну, вірніше, я так ніколи не робив. Просто раніше я будь-яку задачу робив якимось функціональним способом без використання принципів та можливостей ООП, вигадував купу костилів, де можна було б написати гарний код. А тепер мені хочется понапихувати купу інтерфейсів, де вони не треба, буду тепер намагатися робити то все з розумом карочі. От скоро сяду за диплом, буде мені такий невеличкий челендж типу.

All you want is a dingle,
What you envy's a schwang,
A thing through which you can tinkle,
Or play with, or simply let hang...

18

Re: Де використовувати абстрактні класи, а де інтерфейси?

Мудрість торкнулася розуму твого, падаване юний.

Подякували: Cyan1

19

Re: Де використовувати абстрактні класи, а де інтерфейси?

koala написав:

Мудрість торкнулася розуму твого, падаване юний.

чуйте, ви ж мені просто розповіли про паттерн - "Команда"... Я от якраз дивився відюшку про це

All you want is a dingle,
What you envy's a schwang,
A thing through which you can tinkle,
Or play with, or simply let hang...

20

Re: Де використовувати абстрактні класи, а де інтерфейси?

Так, тільки ви гілкою помилилися :)