2016-03-14 4 views
2

У меня есть эти 5 классов. Один базовый класс называется Фигура, который является абстрактным классом и 4 конкретными производными классами.вызов не унаследованного метода производного класса

Classes

Я должен создать массив фигурас размера 8 (два Cuadrado, два Rectangulo, два Triangulo и два Серкуло), так что я сделал это:

Figuras[] figuras = new Figuras[8]; 
figuras[0] = new Cuadrado(1); 
figuras[1] = new Cuadrado(2); 
figuras[2] = new Rectangulo(2, 1); 
figuras[3] = new Rectangulo(6, 2); 
figuras[4] = new Triangulo(1, 2, 2); 
figuras[5] = new Triangulo(3, 3, 4); 
figuras[6] = new Circulo(1); 
figuras[7] = new Circulo(4); 

Тогда я перебирать массив для вычисления площади и периметра каждой фигуры. Проблема возникает, когда я пытаюсь вызвать метод calcularDiametro(), который принадлежит только фигуре Circulo. Как я могу это сделать?

Я пробовал следующее, но он не работает.

foreach (Figuras f in figuras) 
    if (f is Circulo) 
     f.calcularDiametro(); 

Любая помощь будет оценена по достоинству.

+1

Просто рекомендация - используйте английский язык при именовании переменных, классов, методов и т. Д. То же самое касается комментариев. Хотя понятно, что вы здесь делаете, это не будет хорошо принято в международной команде. – Filkolev

+0

Благодарим вас за предложение @Filkolev, я на самом деле это делаю. Это было просто упражнение для практического литья между классами. – IvnBam

ответ

4

Вы должны бросить его в Circulo, чтобы вызвать Circulo Определённые методы:

foreach (Figuras f in figuras) 
{ 
    if (f is Circulo) 
     (Circulo)f.calcularDiametro(); 
} 

Обратите внимание, что это немного расточительно, потому что он делает тип проверки дважды (что является дорогостоящей операцией). Один из способов сделать это без этих отходов является использование as:

foreach (Figuras f in figuras) 
{ 
    Circulo circ = f as Circulo; 
    if (circ != null) 
    { 
     circ.calcularDiametro(); 
    } 
} 
4

Вы можете использовать as opertor и предотвратить дополнительный бросок и повысить производительность

foreach (Figuras f in figuras) 
{ 
    var c = f as Circulo; 
    if (c != null) 
     c.calcularDiametro(); 
} 

Вы также можете использовать OfType, чтобы получить объекты определенного типа от вашего Enumerable

foreach (var c in figuras.OfType<Circulo>()) 
{ 
    c.calcularDiametro(); 
} 
1

Другие ответы технически правильные, но неправильные. Ваша проблема заключается в том, что вы не должны инициировать эти вычисления извне классов в первую очередь. Сами классы должны выполнять вычисления по мере необходимости либо в конструкторе, либо когда внешний компонент запрашивает значение perimetro или diametro. Это инкапсуляция.

+0

Инкапсуляция - это скрытие внутренних выработок вычислений. Классы делают это просто отлично. Мне кажется, что метод 'calcularDiametro' не применяется к другим формам, поэтому он отлично подходит только для определенного подкласса, чтобы иметь этот метод. – Enigmativity

+0

Я считаю, что Мартин совершенно прав, дизайн нарушает некоторые принципы. – Glenner003

+0

Спасибо, Гленнер. Чтобы уточнить: скрытие кода расчета, но требующего от клиента инициирования расчета, бессмысленно с точки зрения ООП. Вы не интересуетесь расчетами, вас интересуют только периметро и только диаметры (свойства фигур). Все, что нужно сделать для создания этих ценностей, должно быть скрыто. Это как идти в пекарню и не просить хлеба, а вместо этого рассказывать человеку, чтобы положить тесто в форму, положить его в духовку, подождать пару часов, вынуть его, положить в мешок и передать его тебе. Кто сейчас делает хлеб? –

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