Sdílet prostřednictvím


Dědičnost (Příručka programování C#)

Dědičnost spolu s zapouzdření a polymorfismus, je jedním z tři hlavní charakteristiky (nebo sloupky) objektově orientované programování.Dědičnost umožňuje vytvořit nové třídy, které znovu použít, rozšířit a upravit chování, které je definováno v jiných třídách.Třídy, jejíž členové jsou zděděny, nazývá základní třídy, se nazývá třída, která tyto členy odvozené třídy.Odvozená třída může mít pouze jeden Přímá základní třída.Dědičnost je však přenositelné.ClassC je odvozen z ClassB a ClassB je odvozen od ClassA, ClassC zdědí členy deklarované v ClassB a ClassA.

[!POZNÁMKA]

Struktur nepodporují dědičnosti, ale implementují rozhraní.Další informace naleznete v tématu Rozhraní (Příručka programování C#).

Odvozené třídy je koncepčně specializace základní třídy.Například pokud máte základní třídy Animal, může mít jeden odvozené třídy s názvem Mammal a jiné odvozené třídy s názvem Reptile.A Mammal je Animala Reptile je Animal, ale každý odvozené třídy představuje různé specializace základní třídy.

Při definování třídy odvodit z jiné třídy odvozené třídy implicitně získá všechny členy základní třídou, s výjimkou jeho konstruktory a destruktory.Odvozené třídy můžete tím znovu použít kód v základní třídě bez nutnosti jej re-implement.V odvozené třídě můžete přidat další členy.Tímto způsobem odvozená třída rozšiřuje funkce základní třídy.

Následující obrázek znázorňuje třídu WorkItem , představuje položku práce v některé obchodní proces.Stejně jako všechny třídy odvozuje z System.Object a dědí všechny metody.WorkItemPřidá vlastní pět členů.Patří konstruktoru, protože nejsou děděna konstruktory.Třída ChangeRequest od WorkItem a představuje určitý druh pracovní položku.ChangeRequestPřidá další dva členy na členy, které dědí z WorkItem a z Object.Přidat vlastní konstruktor a také přidá originalItemID.Vlastnost originalItemID umožňuje ChangeRequest instance je spojena s původní WorkItem na který se vztahuje požadavek na změnu.

Dědičnost třídy

Dědičnost tříd

Následující příklad ukazuje, jak jsou vyjádřeny prokázána v předchozí ukázce vztahy třídy v jazyce C#.Příklad také ukazuje jak WorkItem potlačí metodu virtuální Object.ToStringa jak se ChangeRequest třída dědí WorkItem implementace metody.

// WorkItem implicitly inherits from the Object class.
public class WorkItem
{
    // Static field currentID stores the job ID of the last WorkItem that
    // has been created.
    private static int currentID;

    //Properties.
    protected int ID { get; set; }
    protected string Title { get; set; }
    protected string Description { get; set; }
    protected TimeSpan jobLength { get; set; }

    // Default constructor. If a derived class does not invoke a base-
    // class constructor explicitly, the default constructor is called
    // implicitly. 
    public WorkItem()
    {
        ID = 0;
        Title = "Default title";
        Description = "Default description.";
        jobLength = new TimeSpan();
    }

    // Instance constructor that has three parameters.
    public WorkItem(string title, string desc, TimeSpan joblen)
    {
        this.ID = GetNextID();
        this.Title = title;
        this.Description = desc;
        this.jobLength = joblen;
    }

    // Static constructor to initialize the static member, currentID. This
    // constructor is called one time, automatically, before any instance
    // of WorkItem or ChangeRequest is created, or currentID is referenced.
    static WorkItem()
    {
        currentID = 0;
    }


    protected int GetNextID()
    {
        // currentID is a static field. It is incremented each time a new
        // instance of WorkItem is created.
        return ++currentID;
    }

    // Method Update enables you to update the title and job length of an
    // existing WorkItem object.
    public void Update(string title, TimeSpan joblen)
    {
        this.Title = title;
        this.jobLength = joblen;
    }

    // Virtual method override of the ToString method that is inherited
    // from System.Object.
    public override string ToString()
    {
        return String.Format("{0} - {1}", this.ID, this.Title);
    }
}

// ChangeRequest derives from WorkItem and adds a property (originalItemID) 
// and two constructors.
public class ChangeRequest : WorkItem
{
    protected int originalItemID { get; set; }

    // Constructors. Because neither constructor calls a base-class 
    // constructor explicitly, the default constructor in the base class
    // is called implicitly. The base class must contain a default 
    // constructor.

    // Default constructor for the derived class.
    public ChangeRequest() { }

    // Instance constructor that has four parameters.
    public ChangeRequest(string title, string desc, TimeSpan jobLen,
                         int originalID)
    {
        // The following properties and the GetNexID method are inherited 
        // from WorkItem.
        this.ID = GetNextID();
        this.Title = title;
        this.Description = desc;
        this.jobLength = jobLen;

        // Property originalItemId is a member of ChangeRequest, but not 
        // of WorkItem.
        this.originalItemID = originalID;
    }
}

class Program
{
    static void Main()
    {
        // Create an instance of WorkItem by using the constructor in the 
        // base class that takes three arguments.
        WorkItem item = new WorkItem("Fix Bugs",
                                     "Fix all bugs in my code branch",
                                     new TimeSpan(3, 4, 0, 0));

        // Create an instance of ChangeRequest by using the constructor in
        // the derived class that takes four arguments.
        ChangeRequest change = new ChangeRequest("Change Base Class Design",
                                                 "Add members to the class",
                                                 new TimeSpan(4, 0, 0),
                                                 1);

        // Use the ToString method defined in WorkItem.
        Console.WriteLine(item.ToString());

        // Use the inherited Update method to change the title of the 
        // ChangeRequest object.
        change.Update("Change the Design of the Base Class",
            new TimeSpan(4, 0, 0));

        // ChangeRequest inherits WorkItem's override of ToString.
        Console.WriteLine(change.ToString());

        // Keep the console open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* Output:
    1 - Fix Bugs
    2 - Change the Design of the Base Class
*/

Abstraktní a virtuální metody.

Při základní třídy deklaruje metodu jako virtuální, odvozené třídy lze potlačit s vlastní implementací metody.Pokud je základní třída deklaruje člena jako abstraktní, že metoda musí být přepsána do jiné abstraktní třídy, která přímo dědí z třídy.Pokud je odvozené třídy sám abstraktní, zdědí abstraktní členy bez jejich provádění.Abstraktní a virtuální členové jsou základem pro polymorfismus, což je druhý hlavní charakteristika objektově orientované programování.Další informace naleznete v tématu Polymorfismus (Příručka programování C#).

Abstraktní základní třídy

Můžete deklarovat třídu jako abstraktní Chcete-li zabránit přímé vytvoření instance pomocí nové klíčové slovo.Je-li to provést, pouze pokud nová třída je odvozena z ní lze použít třídy.Abstraktní třída obsahovat jednu nebo více podpisů metodu, že samy jsou deklarován jako abstraktní.Tyto podpisy určit parametry a vrací hodnotu, ale žádné implementaci (tělo metody).Abstraktní třída nemusí obsahovat abstraktní členy; Pokud třída obsahuje abstraktní člena, samotné třídy musí deklarovat jako abstraktní.Odvozené třídy, které nejsou abstraktní samotné musí obsahovat implementaci pro jakékoli abstraktní metody základní třídy.Další informace naleznete v tématu Abstraktní a uzavřených tříd a členů tříd (Příručka programování C#).

Rozhraní

Rozhraní je typ odkazu, který je poněkud podobná abstraktní základní třídy, která je tvořena pouze abstraktní členy.Pokud třída implementuje rozhraní, musí implementace stanovit všechny členy rozhraní.Třídu lze implementovat více rozhraní, přestože lze odvodit z pouze jediné přímé základní třídy.

Rozhraní slouží k definování tříd, které nemusí mít určité možnosti "je" vztah.Například System.IEquatable<T> každé třídy nebo struct, který má umožnit určit, zda dva objekty typu jsou rovnocenné (typ však definuje ekvivalence) kódu klienta lze implementovat rozhraní.IEquatable<T>neznamená stejný druh "je" vztah, který existuje mezi základní třídy a odvozené třídy (například Mammal je Animal).Další informace naleznete v tématu Rozhraní (Příručka programování C#).

Odvozené třídy přístup členům základní třídy.

Odvozené třídy má přístup k veřejné, chráněné, vnitřní a chráněné vnitřní členy základní třídy.Přestože odvozená třída dědí členové soukromé základní třídy, nelze získat přístup k těm členům.Tyto členy soukromého však jsou stále ještě v odvozené třídě a provést stejnou práci udělat v základní třídě sám.Předpokládejme například, že metoda chráněné základní třídy přistupuje pole private.Toto pole musí být přítomny v odvozené třídě zděděné třídě základní metody pracovat správně.

Zabránění dalšímu odvození

Třídy můžete zabránit další třídy dědí z něj nebo některého z jejích členů prohlášením samotný nebo jako člen uzavřených.Další informace naleznete v tématu Abstraktní a uzavřených tříd a členů tříd (Příručka programování C#).

Odvozené třídy skrytí členů základní třídy.

Skrýt členy základní třídy odvozené třídy deklarování členů se stejným názvem a podpisem.Nové modifikátor lze výslovně uvede člen neurčené být lokálními základní člen.Použití nové není vyžadováno, ale je generována upozornění kompilátoru, pokud nové není použita.Další informace naleznete v tématu Správa verzí s přepsat a nová klíčová slova (Příručka programování C#) a Víte, kdy použít přepsat a nová klíčová slova (C# Příručka programování).

Viz také

Referenční dokumentace

Třídy a struktur (Příručka programování C#)

třídy (C#-Reference)

Struktura (C#-Reference)

Koncepty

Příručka programování C#