2015-05-12 4 views
1

У меня есть абстрактный класс и класс ребенкаПодкласса абстрактного класса, всегда называют абстрактный конструктор

abstract class abstractClass 
{ 
    public int x; 

    protected abstractClass(int x) 
    { 
     this.x = x; 
    } 
} 

class childClass : abstractClass 
{ 
    childClass(int x) 
     : base(x) 
    { 
    } 
} 

У меня есть много дочерних классов, как эта, где все эти классы всегда просто называют общий конструктор abstractClass1(int x) путем вызова base(x) в своих конструкторах.

Когда я хочу добавить новое свойство в конструктор, например, еще один int y, я должен отредактировать все эти классы и добавить y в качестве параметра в конструкторе каждого потомка, а также конструктор абстрактного класса.

Есть ли другой способ сделать это, учитывая, что я заранее знаю, что каждый дочерний класс будет использовать абстрактный конструктор классов и не будет добавлять ничего другого?

+0

Зависит от того, что такое 'y'. Должны ли дочерние классы предоставлять значение для 'y'? Будет ли конструктор, который принимает только 'x', по-прежнему действителен? –

+0

@BJMyers ya, конечно, 'y' получит свое значение, установленное из конструктора, иначе я просто добавлю' y' в абстрактный класс a, который бы это был – dimitris93

+0

Вы могли бы добавить еще один конструктор с дополнительным параметром или установить параметр в значение по умолчанию в сигнатуре метода. –

ответ

3

Вот одна идея: сделать AbstractClassParameters класс:

class AbstractClassParameters { 
    public int x { get; private set; } 
    // add more parameters here 
    public AbstractClassParameters(int x) { 
     this.x = x; 
     // add more initializers here 
    } 
} 

Теперь вы можете передать экземпляр AbstractClassParameters в конструктор абстрактного класса, и каждый подкласс может сделать то же самое, просто передавая его.

abstract class abstractClass 
{ 
    public int x; 

    protected abstractClass(AbstractClassParameters p) 
    { 
     this.x = p.x;    
    } 
} 

class childClass : abstractClass 
{ 
    childClass(AbstractClassParameters p) : base(p) { } 
} 

При добавлении параметра, нужно только отредактировать AbstractClassParameters класс и abstractClass, не каждый подкласс.

+0

отличная идея, спасибо – dimitris93

+0

Итак, каждый раз, когда новое поле/свойство добавляется в абстрактный базовый класс, конструкторы для AbstractClass ** и ** AbstractClassParameters должны быть расширены; и каждый вызов конструктора для AbstractClassParameters должен быть изменен вместо равного количества вызовов конструктору для AbstractClass. Я не вижу, как на самом деле это не небольшое увеличение работы для поддержки расширения. –

+1

@PieterGeerkens В любом случае необходимо будет изменить все вызовы (вызовы подкласса ctors), поэтому базовый класс должен быть изменен.Существует один новый класс для изменения, но никакие подклассы не должны быть изменены, поэтому это должно уменьшать работу, пропорциональную количеству подклассов. – Blorgbeard

0

К сожалению, я не думаю, что вы можете сделать это любым другим способом. Вы должны изменить абстрактный класс, потому что вам нужно добавить новый элемент y. Вы либо модифицируете конструктор абстрактного класса, чтобы инициализировать элемент y, либо можете создать свойство вокруг y и позволить потомкам инициализировать его внутри конструктора.

+0

Я изменю конструктор абзацев, чтобы инициализировать значение 'y'. Но это все равно потребует от меня изменения 'childClass (int x, int y): base (x, y)' для каждого дочернего элемента – dimitris93

0

Мне кажется, что большинство уже существующих подклассов могут легко принять значение по умолчанию для нового свойства y. В этом случае добавьте новый конструктор для базового класса с новым инициализатором свойств и добавьте старый конструктор значение нового свойства в стандартное значение по умолчанию. Теперь только подклассы, для которых требуется значение, отличное от значения по умолчанию для нового свойства, нужно вызвать расширенный конструктор базового класса.

Ваш пример будет выглядеть так:

abstract class abstractClass 
{ 
    public int x { get; private set; } 
    public int y { get; private set; } 

    protected abstractClass(int x) : this(x, defaultY) {} 
    protected abstractClass(int x, int y) 
    { 
     this.x = x; 
     this.y = y; 
    } 
} 

class childClass : abstractClass 
{ 
    childClass(int x) 
     : base(x) 
    { 
    } 
} 

class childClass2 : abstractClass 
{ 
    childClass(int x, int y) 
     : base(x,y) 
    { 
    } 
} 
+0

Все подклассы должны будут установить значение 'y'. Там нет значения по умолчанию. – dimitris93

Смежные вопросы