С# Множественное наследование
В настоящее время я изучаю С# с ASP.NET MVC 4 с Code First Approach. Im Visual Basic Developer, и теперь я хочу запустить С#. И теперь я столкнулся с ситуацией, когда мне нужно управлять множественным наследованием. Но это невозможно в классе I. Итак, как мне управлять этими классами, у меня есть:
//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; }
}
То, что я хочу сделать, одобрено, ApprovedDate и ApprovedUserId также распространено. Я хочу указать эти свойства, например:
public class Approve {
public bool Approved { get; set; }
public DateTime ApprovedDate { get; set; }
public int ApprovedUserId { get; set; }
}
И, хотите использовать как:
public class Student:Person,Approve
{
public DateTime DateOfBirth { get; set; }
public DateTime EnrollmentDate { get; set; }
public string Remarks { get; set; }
}
И я не могу поместить эти вещи внутри PERSON. Потому что я должен использовать это для других классов, но это не Person.
Затем, как мне достичь этого...
Пожалуйста, дайте мне пример для вышеуказанной ситуации.
Пожалуйста, помогите. И, Большое спасибо вам в Advance.
Ответы
Ответ 1
Одним из возможных решений могло бы стать изменение вашей иерархии:
public class PersonWithApprove : Person { // TODO: replace with non disgusting name
public bool Approved { get; set; }
// etc...
}
public class Student : PersonWithApprove {
}
public class Faculty : PersonWithApprove {
}
Или вы можете создать интерфейс:
public interface IApprove {
bool Approved { get; set; }
// etc
}
public class Student : Person, IApprove {
}
Вы также можете оставить класс Approve
как таковой и иметь классы с свойством этого типа:
public class Student : Person {
Approve _approve = new Approve();
public Approve Approve {
get { return _approve; }
}
}
Ответ 2
Это хороший случай, ИМХО, чтобы использовать интерфейсы здесь, что-то вроде этого:
// 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
}
Ответ 3
Короткий ответ
Рассмотрим вместо этого использование интерфейсов, которые допускают множественное наследование и могут быть объявлены с помощью ключевого слова interface
.
Длинный ответ
Наследование из нескольких базовых классов в С# является незаконным. Классы могут иметь только 1 базовый класс, тогда как они могут реализовать любое количество интерфейсов. Есть несколько причин для этого, но в основном это сводится к тому, что множественное наследование вводит гораздо большую сложность в иерархию классов.
Интерфейсы используются для объявления группы общих функций (методов и свойств), которые должны быть реализованы классом.
Чтобы изменить существующий код на использование интерфейсов (вместо множественного наследования), вы можете сделать следующее:
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
}
Этот подход абстрагирует реализацию интерфейса IApprove и, подобно множественному наследованию, позволяет пользователю работать с объектами, которые реализуют IApprove, но их конкретный тип неизвестен (или не имеет значения).
Для получения дополнительной информации об использовании интерфейсов в С# обратитесь к:
http://msdn.microsoft.com/en-us/library/87d83y5b.aspx
Ответ 4
Вы можете использовать композитный шаблон
public class Student:Person
{
public Approve App { get; set; }
public DateTime DateOfBirth { get; set; }
public DateTime EnrollmentDate { get; set; }
public string Remarks { get; set; }
}
Ответ 5
Рассмотрим следующий пример: он использует два интерфейса:
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();
}
}
Ответ 6
В базовом примере с использованием шаблона 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;
}
}
}
Демо:
MultipleClass multipleClass = new MultipleClass();
multipleClass.Method1(); //OUTPUT: Class1: Method1, MyInt: 1
multipleClass.Method2(); //OUTPUT: Class2: Method2, MyInt: 1
multipleClass.MyInt = 1;