web-dev-qa-db-fra.com

Héritage multiple C #

Actuellement, j'étudie le C # avec ASP.NET MVC 4 avec Code First Approach. Im Visual Basic Developer, et maintenant je veux démarrer C #. Et maintenant, je suis tombé sur la situation où je dois gérer l'héritage multiple. Mais ce n'est pas possible avec la pensée de classe i. Alors, comment dois-je gérer ces classes que j'ai:

//I have the Following Person Class which Hold Common Properties 
//and a Type of Person e.g : Student, Faculty, Administrative
public class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Type { get; set; }
}


//This is my Student Class, which is Derived from Person
public class Student:Person
{
    public DateTime DateOfBirth { get; set; }
    public DateTime EnrollmentDate { get; set; }
    public string Remarks { get; set; }


    public bool Approved { get; set; }
    public DateTime ApprovedDate { get; set; }
    public int ApprovedUserId { get; set; }
}


//This is my Faculty Class, which is also Derived from Person
public class Faculty : Person
{
    public DateTime HiredDate { get; set; }


    public bool Approved { get; set; }
    public DateTime ApprovedDate { get; set; }
    public int ApprovedUserId { get; set; }
}

Ce que je veux faire est Approved, ApprovedDate et ApprovedUserId également courants. Je veux spécifier ces propriétés comme:

 public class Approve {
    public bool Approved { get; set; }
    public DateTime ApprovedDate { get; set; }
    public int ApprovedUserId { get; set; }
}

Et, souhaitez utiliser comme:

public class Student:Person,Approve
{
    public DateTime DateOfBirth { get; set; }
    public DateTime EnrollmentDate { get; set; }
    public string Remarks { get; set; }
}

Et, je ne peux pas mettre ces choses à l'intérieur PERSONNE . Parce que je dois l'utiliser pour une autre classe, mais ce ne sont pas des personnes.

Alors, comment puis-je y parvenir ...

Veuillez me donner un exemple de la situation ci-dessus.

Veuillez aider. Et merci beaucoup d'avance.

12
Nirmal Subedi

Une solution possible serait de modifier votre hiérarchie:

public class PersonWithApprove : Person { // TODO: replace with non disgusting name
    public bool Approved { get; set; }
    // etc...
}

public class Student : PersonWithApprove {
}

public class Faculty : PersonWithApprove {
}

Ou vous pouvez créer une interface:

public interface IApprove {
    bool Approved { get; set; }
    // etc
}

public class Student : Person, IApprove {
}

Vous pouvez également laisser la classe Approve en tant que telle et avoir des classes avec une propriété de ce type:

public class Student : Person {
    Approve _approve = new Approve();
    public Approve Approve {
        get { return _approve; }
    }
}
22
Paolo Tedesco

C'est un bon cas, à mon humble avis, d'utiliser des interfaces ici, quelque chose comme ça:

  // Interfaces:

  // General person
  public interface IPerson {
    int Id { get; set; }
    string FirstName { get; set; }
    string LastName { get; set; }
    string Type { get; set; }
  }

  // Approvable person
  public interface IApprovable {
    bool Approved { get; set; }
    DateTime ApprovedDate { get; set; }
    int ApprovedUserId { get; set; }
  } 

  // Student is a IPerson + IApprovable
  public interface IStudent: IPerson, IApprovable {
    DateTime DateOfBirth { get; set; }
    DateTime EnrollmentDate { get; set; }
  }

  // So classes will be

  public class Approve: IApprovable {
    ... //TODO: Implement IApprovable interface here
  } 

  public class Faculty: IPerson, IApprovable {
    public DateTime HiredDate { get; set; }

    ... //TODO: Implement IPerson interface here
    ... //TODO: Implement IApprovable interface here
  }

  public class Student: IStudent {
    public string Remarks { get; set; }

    ... //TODO: Implement IStudent interface here
  }
6
Dmitry Bychenko

Réponse courte

Envisagez plutôt d'utiliser des interfaces, qui permettent un héritage multiple et peuvent être déclarées à l'aide du mot clé interface.

Réponse longue

L'héritage de plusieurs classes de base en C # est illégal. Les classes ne peuvent avoir qu'une seule classe de base alors qu'elles peuvent implémenter n'importe quel nombre d'interfaces. Il y a plusieurs raisons à cela mais cela revient principalement au fait que l'héritage multiple introduit beaucoup plus de complexité dans une hiérarchie de classes.

Les interfaces sont utilisées pour déclarer un groupe de fonctionnalités communes (méthodes et propriétés) qui doivent être implémentées par classe.

Pour modifier votre code existant pour utiliser des interfaces (au lieu de l'héritage multiple), vous pouvez effectuer les opérations suivantes:

public interface IApprove // Defines a set of functionality that a class must implement.
{
    // All these properties must be inherited as public when implemented.
    bool Approved { get; set; } // Property declaration.
    DateTime ApprovedDate { get; set; }
    int ApprovedUserId { get; set; }
}

public class Student : Person, IApprove
{
    public DateTime DateOfBirth { get; set; }
    public DateTime EnrollmentDate { get; set; }
    public string Remarks { get; set; }

    #region IApprove Implementation

    private bool _approved; // Private variable that is accessed through the 'Approved' property of the 'IApprove' interface.
    public bool Approved // Defines 'Approved' inherited from IApprove
    {
        get { return _approved; }
        set { _approved = value; }
    }

    private DateTime _approvedDate;
    public DateTime ApprovedDate // Defines 'ApprovedDate' inherited from IApprove.
    {
        get { return _approvedDate; }
        set { _approvedDate = value; }
    }

    private int _approvedUserId;
    public int IApprove.ApprovedUserId // Alternative syntax to define an interfaces property.
    {
        get { return _approvedUserId; }
        set { _approvedUserId = value; }
    }

    #endregion
}

Cette approche résume l'implémentation d'une interface IApprove et, comme l'héritage multiple, permet à l'utilisateur d'opérer sur des objets qui implémentent IApprove mais leur type concret est inconnu ( ou non pertinent).

Pour plus d'informations sur l'utilisation des interfaces en C #, reportez-vous à:

http://msdn.Microsoft.com/en-us/library/87d83y5b.aspx

5
matthewrdev

Vous pouvez utiliser un motif composite

    public class Student:Person
    {
        public Approve App { get; set; }
        public DateTime DateOfBirth { get; set; }
        public DateTime EnrollmentDate { get; set; }
        public string Remarks { get; set; }
    }
2
Daniel Rapaport

Prenons l'exemple suivant, il utilise deux interfaces:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


////////
////////
/// Multiple Inheritance With Interfaces

public interface Interface1
{
    void func1();
    void fun();
}

public interface Interface2
{
    void func2();
    void fun();
}

public class MyTestBaseClass : Interface1, Interface2
{
    void Interface1.func1()
    {
        Console.WriteLine("From MyInterface1 Function()");
        return;
    }


    void Interface2.func2()
    {
        Console.WriteLine("From MyInterface2 Function()");
        return;
    }

    void Interface1.fun()
    {
        Console.WriteLine("fun1()");
    }

    void Interface2.fun()
    {
        Console.WriteLine("fun2()");
    }


    public static void Main()
    {
        MyTestBaseClass myclass = new MyTestBaseClass();
        ((Interface1)myclass).func1();
        ((Interface2)myclass).func2();
    }

}
2
JAN

Quelques exemples de base utilisant le modèle de conception Decorator:

public class Class1
{
    public void Method1()
    {
        Console.write($"Class1: Method1, MyInt: {MyInt}");
    }

    public int MyInt { get; set; }
}

public class Class2
{
    public void Method2()
    {   
        Console.write($"Class2: Method2, MyInt: {MyInt}");      
    }

    public int MyInt { get; set; }
 }

public class MultipleClass
{
    private Class1 class1 = new Class1();
    private Class2 class2 = new Class2();

    public void Method1()
    {
        class1.Method1();
    }
    public void Method2()
    {
        class2.Method2();
    }

    private int _myInt;
    public int MyInt
    {
        get { return this._myInt; }
        set
        {
            this._myInt = value;
            class1.MyInt = value;
            class2.MyInt = value;
        }
    }
}

Démo:

 MultipleClass multipleClass = new MultipleClass();
 multipleClass.Method1(); //OUTPUT: Class1: Method1, MyInt: 1 
 multipleClass.Method2(); //OUTPUT: Class2: Method2, MyInt: 1
 multipleClass.MyInt = 1;
1
Shahar Shokrani