2009-03-26 4 views
2

몇 가지 추가 기능을 사용하여 C#의 기본 클래스를 확장하고자합니다. 확장 된 버전으로 변환해야하는 기본 클래스 개체 (계정)의 배열을 반환하는 기존 코드가 있습니다.상속 문제에 대한 내 머리를 얻으십시오.

class AccountXtra : Account 
{ 
    public int Period { get; set; } 
    public int Visitors { get; set; } 
    public string ContactName { get; set; } 
} 

모든 좋은 :

은 그래서 확장 버전이있다.

계정의 인스턴스가있을 때 어떻게 AccountXtra의 새 인스턴스를 만들 수 있습니까?

//This doesn't work 
AccountXtra newInstance = (AccountXtra)accountInstance; 
//This also doesn't work 
AccountXtra newInstance = new AccountXtra(); 
newInstance = accountInstance; 

답변

1

당신은 기본을 지금 파생 클래스의 새로운 객체를 생성하지 될 필요가있다. 이전 전화를 new Account으로 바꾸고 new AccountXtra으로 바꿉니다. 또는, 당신은 Account 오브젝트를 그것의 새로운 파생 클래스 버전을 만드는 AccountXtra의 생성자가 필요합니다

public AccountXtra(Account baseInstance) : this() 
{ 
    this.Field1 = baseInstance.Field1; 
    this.Field2 = baseInstance.Field2; 
    ... 
} 

설명 : 당신은 그것을하지 않는 파생 클래스에 기본 클래스를 캐스팅 할 수 없습니다 파생 클래스 유형입니다.

AccountXtra accountXtra = new AccountXtra(); 
Account xtraAsBase = (Account)accountXtra; 
AccountXtra xtraCastBack = (AccountXtra)xtraCastAsBase; 

을하지만이되지 않습니다 :이 작동합니다

Account Base = new Account(); 
AccountXtra baseAsDerived = (AccountXtra)Base; //Cast base to derived class 
+0

"this.Field1 = baseInstance.Field1"이것은 내가 피하려고했던 것입니다. 대체 방법은 기본 클래스를 래핑하여 속성으로 표시하는 것입니다. 이것은 덜 악한 것처럼 보입니다 –

+0

이 경우 나는 상속을 전혀 사용하지 않을 것입니다, 나는 기본 클래스의 인스턴스를 포함하는 새로운 클래스를 만들 것입니다. 그러나 Account 객체를 만드는 코드에 액세스 할 수있는 경우 AccountXtra 객체를 만드는 대신 해당 객체를 변경하면됩니다. 그렇다면 원하는대로 자유롭게 할 수 있습니다. –

1

을하지만 계정의 인스턴스가있을 때 어떻게 내가 AccountXtra의 새 인스턴스를 만들려면 어떻게해야합니까 :

나는 시도?

잘못된 방식으로 진행됩니다. 계정 개체로 도처에서 처리 할 수있는 AccountXtra 개체를 만들어야합니다.

그런데 목록 작성 코드에서 만들려는 개체의 유형을 모르는 경우 약 factory patterns을 읽어보십시오.

귀하가 갖고있는 특정 문제로 자유롭게 질문을 업데이트하십시오.

1

기본 클래스를 하위 클래스로 변환 할 수 없습니다. 즉, 개체의 유형이 '계정'인 경우 'AccountXtra'로 캐스팅 할 수 없습니다. 그러나 "AccountXtra"클래스가있는 경우 "Account"를 상속하므로 Account에 캐스팅 할 수 있습니다.

기존 코드의 소스가있는 경우 "new Account()"생성자를 호출하는 위치를 변경하고이를 "new AccountXtra()"로 변경해야합니다. 또한 "Account"클래스의 인스턴스를 "AccountXtra"로 바꿔야합니다.

"Account"유형의 인수를 취하는 AccountXtra()에서 생성자를 생성하고 모든 정보를 새로운 인스턴스. 정확하지는 않지만 원하는 효과를 얻을 수 있습니다.

public class AccountXtra : Account 
{ 
    public AccountXtra(Account existingAccount) : base() 
    { 
     this.accountName = existingAccount.accountName; 
     this.accountNumber = existingAccount.accountNumber; 
     ... 
    } 
} 
+0

답변 해 주셔서 감사합니다. 나는 분명히 틀린 클래스 상속에 대한 가정을 가졌습니다. (어쨌든 현실이 아니라는 의미에서 잘못된 것입니다!) –

+0

"슈퍼 클래스"가 아니라 "서브 클래스"라고 생각합니다. 그리고 그것의 경우도. – recursive

+0

문제 없습니다. 이러한 계정 객체를 생성하는 코드에 액세스 할 수없는 경우 시도해 볼 또 다른 옵션을 추가했습니다. –

0

당신은 추상화 할 수 있습니다 그것을 밖으로 모든 공통 속성을 가진 일반적인 추상 클래스로 :

public abstract class Account 
{ 
    //all common members make them abstract 
    public abstract int AccountId { get; set; } 
} 

그 다음이 귀하의 추가 및 새로운 "기본"계정은 일반 계정 클래스에서 파생됩니까?

public class AccountBasic : Account 
{ 
    public override int AccountId { get; set; } 
    //implement the rest 
} 

public class AccountExtra : Account 
{ 
    public override int AccountId { get; set; } 
    //your extra details 
    public int Period { get; set; } 
    public int Visitors { get; set; } 
    public string ContactName { get; set; } 
} 

이렇게하면 다음과 같이 컬렉션을 만들 수 있습니다. List allAccounts; 여기서 공통 속성을 조작 할 수 있습니다. 특수 클래스의 인스턴스를 유지 관리하는 중입니다.

+0

그것은 데코레이터 패턴입니다. 이 상황에서 죽이는 것 같이 보입니다. –

0

이것은 이전 답변에 대한 의견으로 의도되었지만 시간이 너무 오래 걸렸을 것으로 생각됩니다.

부모 클래스의 인스턴스를 가져와 그 클래스의 데이터를 복사하는 생성자가있는 하위 클래스를 갖는 것이 널리 보급 된 표준입니다. 여러 수준의 상속 및 다른 클래스로 인해 발생할 수있는 두통을 최소화하는 한 가지 방법은이 작업을 수행하는 보호 된 함수를 만드는 것입니다.이 경우에는 Assign이라고 부릅니다. Person, EmployeeManager이라는 세 가지 클래스가 있다고 가정합니다. 그들은 각각 순서대로 다른 것을 상속 받는다. 그래서 우리는을 변경할 수

public class Manager : Person 
{ 
    private string department; 

    public Manager() { } 
    public Manager(Employee newManager) : this() 
    { 
     base.Assign(newManager); 
    } 

    public string Department 
    { 
     get { return department; } 
     set { department = value; } 
    } 

    protected new void Assign(Manager otherManager) 
    { 
     base.Assign(otherManager); 

     Department = otherManager.Department; 
    } 
} 

그래서 각 클래스에서 Assign() 방법은 new을 선언

public class Employee : Person 
{ 
    private int employeeID; 

    public Employee() { } 
    public Employee(Person newEmployee) : this() 
    { 
     base.Assign(newEmployee); 
    } 

    public int EmployeeID 
    { 
     get { return employeeID; } 
     set { employeeID = value; } 
    } 

    protected new void Assign(Employee otherEmployee) 
    { 
     base.Assign(otherEmployee); 

     EmployeeID = otherEmployee.EmployeeID; 
    } 
} 

그럼 우리가 관리자에 대해 동일한 예제를 따르

public class Person 
{ 
    private string name; 

    public string Name 
    { 
     get { return name; } 
     set { name = value; } 
    } 

    protected void Assign(Person otherPerson) 
    { 
     Name = otherPerson.Name; 
    } 
} 

이제 우리는 직원을 정의 서명을 사용하고 상속 된 클래스에 대한 얕은 복사 기능을 제공합니다.

이 패턴은 이전 개체와 동일한 데이터를 가진 NEW 개체를 만듭니다. 이전 개체는 여전히 존재하며 기존 참조는 새 개체를 가리 키지 않습니다. 사실 개체의 TYPE을 변경하는 것은 허용되지 않습니다.

+0

아 예 단순한 패턴 –

관련 문제