Во-первых, не пишите код транслитом. Названия должны быть на англицком и только на нём. Мне вот неясно, что делает otric. Ещё в C# не рекомендуется использовать snake-style названия, то есть те, где слова подчёркиванием разделены. Лучше писать, например, negativeRowIndex. Представьте, что Ваш код будет читать какой-то индиец, который ни разу русский не видел и не слышал. Он должен его понять. Вообще, главный признак хорошего кода - понятность.
Во-вторых, при наследовании желательно у базового класса как-то определять интерфейс. У Вашего же интерфейс определён окончательно только у класса-наследника. Вообще, этому ваш препод учить, а не мы.
В-третьих, все поля и методы классов определяйте как можно более закрыто. Желательно private, если никак невозможно - protected. public могут быть только методы. Это, вроде бы, называется "сокрытие данных". Например, поля m, n и mas у Вас стоит сделать хотя бы защищёнными.
Мне было не лень, и я написал тебе кучу кода. Внимательно прочти комментарии и следуй советам оттуда.
Код:
using System;
using System.Text;
namespace _1234
{
class Parent
{
protected int rowCount;
protected int columnCount;
protected int[,] internalArray;
public Parent(int rows, int columns)
{
rowCount = rows;
columnCount = columns;
internalArray = new int[rowCount, columnCount];
}
// Убрал параметры - у тебя это в полях есть
public void Input()
{
/* Console.WriteLine("Введите кол-во строк n");
int n = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Введите кол-во столбцов m");
int m = Convert.ToInt32(Console.ReadLine());*/
// Убрал это. Зачем ты объявяешь локальную переменную, если у тебя есть поле?
//int[,] mas = new int[n, m];
Console.WriteLine("Введите элементы массива");
for (int i = 0; i < internalArray.GetLength(0); i++)
{
Console.WriteLine("Введите элементы " + i + "-й строки ПО ОДНОМУ!!!:");
for (int j = 0; j < internalArray.GetLength(1); j++)
{
Console.WriteLine();
internalArray[i, j] = Convert.ToInt32(Console.ReadLine());
}
}
}
// currently nothing to do
public virtual void ProcessArray() { }
// Убрал параметры. Зачем они тебе, если ты их в полях хранишь?
public void Output()
{
//int[,] mas = new int[n, m];
Console.WriteLine("Now we output changed matrix");
for (int i = 0; i < internalArray.GetLength(0); ++i)
{
for (int j = 0; j < internalArray.GetLength(1); ++j)
{
Console.Write("{0,3} ", internalArray[i, j]);
}
Console.WriteLine();
}
}
}
class Child : Parent
{
public Child(int rows, int columns) : base(rows, columns) { }
// не знаю, зачем тебе свой swap, но оставил
private static void Swap<T>(ref T aa, ref T bb)
{
T temp;
temp = aa;
aa = bb;
bb = temp;
}
// Изменяем поведение
public override void ProcessArray()
{
MoveNegativeNumbersDown();
PrintNonNegativeRows();
}
// Каждое действие выносим в отдельный метод с понятным названием
// Это упрощает понимание
private void MoveNegativeNumbersDown()
{
// Я не делаю swap, потому это портит порядок чисел
// Отдельные массивы для хранения отрицательных и положительных чисел в исходном порядке
// Сначала разделить, а потом объединить быстрее, чем постоянно сдвигать столбики
// Почему это так, должны объяснить на курсе алгоритмов.
// Если интересно, почитай про асимптотический анализ сложности алгоритмов
// И главное: этот код понятнее
// Вынес я это из цикла, так как это уменьшит количество выделений памяти
int[] negatives = new int[rowCount];
int[] positives = new int[rowCount];
for (int j = 0; j < columnCount; j++)
{
// начали делить столбец
int positiveCount = 0;
int negativeCount = 0;
for (int i = 0; i < rowCount; i++)
{
if (internalArray[i, j] < 0)
{
negatives[negativeCount++] = internalArray[i, j];
}
else
{
positives[positiveCount++] = internalArray[i, j];
}
}
// разделили, теперь заполняем его
for(int i = 0; i< positiveCount; i++)
{
internalArray[i, j] = positives[i];
}
for(int i = positiveCount; i < rowCount; i++)
{
internalArray[i, j] = negatives[i-positiveCount];
}
}
}
// Каждое действие выносим в отдельный метод с понятным названием
// Это упрощает понимание
private void PrintNonNegativeRows()
{
int highestNegativeRow = GetHighesPositionOfNegative();
Console.WriteLine("We print our nonnegative rows:");
for (int i = 0; i< highestNegativeRow; i++)
{
for (int j = 0; j<columnCount; j++)
{
Console.Write(internalArray[i, j]);
if(j<columnCount-1)
Console.Write(" ");
}
Console.WriteLine();
}
}
// Каждое действие выносим в отдельный метод с понятным названием
// Это упрощает понимание
private int GetHighesPositionOfNegative()
{
int highestPosition = rowCount;
for (int j = 0; j< columnCount; j++)
{
// Так как мы ищем самую высокую позицию, нет смысла проверять всё до конца
for (int i = 0; i< highestPosition; i++)
{
if (internalArray[i, j] < 0)
{
highestPosition = i;
}
}
}
return highestPosition;
}
}
class Program
{
static void Main(string[] args)
{
// Мы назначаем переменной типа Parent значение типа Child
// Это называется dependency injection
Parent c = new Child(4, 3);
c.Input();
c.ProcessArray();
c.Output();
Console.ReadKey();
}
}
}