Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Изменить public на private в унаследованном классе


Автор: Elfet 29.5.2007, 10:23
Как изменить public на private в унаследованном классе?  smile 

Автор: tol05 29.5.2007, 10:32
никак. Потомки могут только расширять возможности базовых классов, а не ограничивать их.
Вместо наследования агрегируй класс в свой и сделай доступ к чему нужно. Или наследуйся от еще более раннего класса.

Автор: HalkaR 29.5.2007, 10:32
Изменить сигнатуру методов в унаследованном классе нельзя.
Тем более если они private ты их даже не увидишь.
Если методы protected можно сокрыть их и написать обертки для них.

Автор: Elfet 29.5.2007, 10:58
Цитата(HalkaR @  29.5.2007,  11:32 Найти цитируемый пост)
Если методы protected можно сокрыть их и написать обертки для них. 

Вот это вот мне нужно smile Как? smile

Автор: adLucem 29.5.2007, 11:17
Код


// отделяем интерфейс, который будет поддерживаться наследником
public interface ISuper {
    void Foo ( );
}

public class Super : ISuper {
    public void HideMe ( );
    public void Foo ( );
}

// делаем wrapper.
public class Derived : ISuper {
    private Super super;
    public Derived ( ) {
        super = new Super ( );
    }
    public void Foo ( ) {
        super.Foo ( );
    }
    private void HideMe ( ) {
        super.HideMe ( );
    }
}


Цитата(Elfet @  29.5.2007,  08:23 Найти цитируемый пост)
Как изменить public на private в унаследованном классе?


Вопрос поставлен некорректно - наследник не должен давать меньше или обещать больше чем базовый класс - это явная ошибка проектирования.

Автор: Elfet 30.5.2007, 10:52
Цитата(adLucem @  29.5.2007,  12:17 Найти цитируемый пост)
это явная ошибка проектирования.

У меня есть класс матриц MxN со свойствами M, N. От него я наследую класс векторов, где M - всегда равняется 1, и этот параметр нигде не нужен, вот я его и хочу скрыть smile

Автор: HalkaR 30.5.2007, 11:09
Код

        class A
        {
            private int m, n;
            private int[,] arr;

            public A(int m, int n)
            {
                this.m = m;
                this.n = n;
                arr = new int[m,n];
            }
        }

        private class B : A
        {
            public B(int m) : base(m, 1)
            {
            }
        }

Автор: marcusmae 30.5.2007, 11:26
Цитата(adLucem @  29.5.2007,  11:17 Найти цитируемый пост)
Вопрос поставлен некорректно - наследник не должен давать меньше или обещать больше чем базовый класс - это явная ошибка проектирования.

По-моему, перебор с категоричностью. Хотя

Цитата(Elfet @  30.5.2007,  10:52 Найти цитируемый пост)
 меня есть класс матриц MxN со свойствами M, N. От него я наследую класс векторов, где M - всегда равняется 1, и этот параметр нигде не нужен, вот я его и хочу скрыть

это действительно выглядит странновато. Сколько я видел и сам писал линейной алгебры, всюду матрица - это составной объект, использующий вектора, а не наоборот, . Обычно, они даже https://svn.sourceforge.net/svnroot/dnanalytics/numerical/trunk/LinearAlgebra/Matrix.cs (если только матрица не хранится, как вектор), так что "скрывать" придётся очень многое. Впрочем, Вам виднее.

Абстрагируемся от этого примера   smile Конечно, наследующийся класс сигнатуру изменить не может. Некоторую гибкость способен предоставить базовый класс. Может, Вам подойдёт модификатор internal? = Работает он так : если проставить internal какому-нибудь члену класса, то он будет виден только классам внутри данной сборки, а из других сборок будет, как private. Таким образом, проектирование будет заключаться в объединении базовых классов в отдельную сборку с internal где надо, а наследники - в отдельной сборке. http://msdn2.microsoft.com/en-us/library/7c5ka91b(VS.80).aspx
 

Автор: Elfet 30.5.2007, 13:11
HalkaR, угу, так и у меня smile

Цитата(marcusmae @  30.5.2007,  12:26 Найти цитируемый пост)
это действительно выглядит странновато. Сколько я видел и сам писал линейной алгебры, всюду матрица - это составной объект, использующий вектора, а не наоборот, . Обычно, они даже не связаны наследованием (если только матрица не хранится, как вектор), так что "скрывать" придётся очень многое. Впрочем, Вам виднее.

Я дулул так как нас учил препод по алгебре - вектора - это всего лишь подвид матриц smile 

Цитата(marcusmae @  30.5.2007,  12:26 Найти цитируемый пост)
Абстрагируемся от этого примера   smile Конечно, наследующийся класс сигнатуру изменить не может. Некоторую гибкость способен предоставить базовый класс. Может, Вам подойдёт модификатор internal? = Работает он так : если проставить internal какому-нибудь члену класса, то он будет виден только классам внутри данной сборки, а из других сборок будет, как private. Таким образом, проектирование будет заключаться в объединении базовых классов в отдельную сборку с internal где надо, а наследники - в отдельной сборке. Подробнее...

Пожалуй я не буду с этим возится smile

Код

    public class MyMatrix : ICloneable
    {
        private float[,] array;

        public MyMatrix(float[,] matrix)
        {
            array = matrix;
        }

        public MyMatrix(int m, int n)
        {
            array = new float[m, n];
        }

        public float this[int i, int j]
        {
            set
            {
                array[i, j] = value;
            }
            get
            {
                return array[i, j];
            }
        }

        public int Rows
        {
            get
            {
                return array.GetLength(0);
            }
        }

        public int Columns
        {
            get
            {
                return array.GetLength(1);
            }
        }

        public override int GetHashCode()
        {
            int hash = 0;
            for (int i = 0; i < Rows; i++)
                for (int j = 0; j < Columns; j++)
                    hash ^= this[i, j].GetHashCode();
            return hash;
        }

        public override bool Equals(object obj)
        {
            if (obj is MyMatrix)
            {
                MyMatrix v = (MyMatrix)obj;
                if (v.Rows == Rows && v.Columns == Columns)
                {
                    bool equal = true;
                    for(int i = 0; i < Rows; i++)
                        for (int j = 0; j < Columns; j++)
                        {
                            if (v[i, j] != this[i, j])
                                equal = false;
                        }
                    return equal;
                }
                else
                {
                    return false;
                }
            }
            return false;
        }

        public static bool operator ==(MyMatrix u, MyMatrix v)
        {
            if (Object.Equals(u, null))
            {
                return Object.Equals(v, null);
            }

            if (Object.Equals(v, null))
            {
                return Object.Equals(u, null);
            }

            return u.Equals(v);
        }

        public static bool operator !=(MyMatrix u, MyMatrix v)
        {
            if (Object.Equals(u, null))
            {
                return !Object.Equals(v, null);
            }

            if (Object.Equals(v, null))
            {
                return !Object.Equals(u, null);
            }

            return !u.Equals(v);
        }


        public static MyMatrix operator -(MyMatrix v)
        {
            float[,] array = new float[v.Rows, v.Columns];
            for (int i = 0; i < v.Rows; i++)
                for (int j = 0; j < v.Columns; j++)
                    array[i, j] = v[i, j];
            return new MyMatrix(array);
        }

        public static MyMatrix operator +(MyMatrix u, MyMatrix v)
        {
            if (u.Rows == v.Rows && u.Columns == v.Columns)
            {
                float[,] array = new float[v.Rows, v.Columns];
                for (int i = 0; i < v.Rows; i++)
                    for (int j = 0; j < v.Columns; j++)
                        array[i, j] = u[i, j] + v[i, j];
                return new MyMatrix(array);
            }
            else
            {
                throw new Exception("Матрицы имеют не одинаковый размер!");
            }
        }

        public static MyMatrix operator +(MyMatrix v, float s)
        {
            float[,] array = new float[v.Rows, v.Columns];
            for (int i = 0; i < v.Rows; i++)
                for (int j = 0; j < v.Columns; j++)
                    array[i, j] = v[i, j] + s;
            return new MyMatrix(array);
        }

        public static MyMatrix operator +(float s, MyMatrix v)
        {
            float[,] array = new float[v.Rows, v.Columns];
            for (int i = 0; i < v.Rows; i++)
                for (int j = 0; j < v.Columns; j++)
                    array[i, j] = v[i, j] + s;
            return new MyMatrix(array);
        }

        public static MyMatrix operator -(MyMatrix u, MyMatrix v)
        {
            if (u.Rows == v.Rows && u.Columns == v.Columns)
            {
                float[,] array = new float[v.Rows, v.Columns];
                for (int i = 0; i < v.Rows; i++)
                    for (int j = 0; j < v.Columns; j++)
                        array[i, j] = u[i, j] - v[i, j];
                return new MyMatrix(array);
            }
            else
            {
                throw new Exception("Матрицы имеют не одинаковый размер!");
            }
        }

        public static MyMatrix operator -(MyMatrix v, float s)
        {
            float[,] array = new float[v.Rows, v.Columns];
            for (int i = 0; i < v.Rows; i++)
                for (int j = 0; j < v.Columns; j++)
                    array[i, j] = v[i, j] - s;
            return new MyMatrix(array);
        }

        public static MyMatrix operator -(float s, MyMatrix v)
        {
            float[,] array = new float[v.Rows, v.Columns];
            for (int i = 0; i < v.Rows; i++)
                for (int j = 0; j < v.Columns; j++)
                    array[i, j] = s - v[i, j];
            return new MyMatrix(array);
        }


        public static MyMatrix operator *(MyMatrix v, float s)
        {
            float[,] array = new float[v.Rows, v.Columns];
            for (int i = 0; i < v.Rows; i++)
                for (int j = 0; j < v.Columns; j++)
                    array[i, j] = s * v[i, j];
            return new MyMatrix(array);
        }

        public static MyMatrix operator *(float s, MyMatrix v)
        {
            float[,] array = new float[v.Rows, v.Columns];
            for (int i = 0; i < v.Rows; i++)
                for (int j = 0; j < v.Columns; j++)
                    array[i, j] = s * v[i, j];
            return new MyMatrix(array);
        }

        public static MyMatrix operator /(MyMatrix v, float s)
        {
            float[,] array = new float[v.Rows, v.Columns];
            for (int i = 0; i < v.Rows; i++)
                for (int j = 0; j < v.Columns; j++)
                    array[i, j] = v[i, j] / s;
            return new MyMatrix(array);
        }

        public static MyMatrix operator /(float s, MyMatrix v)
        {
            float[,] array = new float[v.Rows, v.Columns];
            for (int i = 0; i < v.Rows; i++)
                for (int j = 0; j < v.Columns; j++)
                    array[i, j] = s / v[i, j];
            return new MyMatrix(array);
        }


        public static explicit operator float[,](MyMatrix v)
        {
            float[,] array = new float[v.Rows, v.Columns];
            for (int i = 0; i < v.Rows; i++)
                for (int j = 0; j < v.Columns; j++)
                    array[i, j] = v[i, j];
            return array;
        }

        public static MyMatrix MatrixMultiplication(MyMatrix u, MyMatrix v)
        {
            if (u.Columns == v.Rows)
            {
                MyMatrix matrix = new MyMatrix(u.Rows, v.Columns);
                for (int i = 0; i < u.Rows; i++)
                    for (int j = 0; j < v.Columns; j++)
                    {
                        matrix[i,j] = 0;
                        for (int k = 0; k < u.Columns; k++)
                            matrix[i,j] += u[i,k] * v[k,j];
                    }
                return matrix;
            }
            else
            {
                throw new Exception("Такие матрицы не возможно перемножить!");
            }
        }

        public static MyMatrix operator *(MyMatrix u, MyMatrix v)
        {
            return MyMatrix.MatrixMultiplication(u, v);
        }

        public static MyMatrix Transposition(MyMatrix v)
        {
            MyMatrix matrix = new MyMatrix(v.Columns, v.Rows);
            for (int i = 0; i < v.Rows; i++)
                for (int j = 0; j < v.Columns; j++)
                    matrix[j,i] = v[i,j];
            return matrix;
        }

        public object Clone()
        {
            MyMatrix matrix = new MyMatrix(Rows, Columns);
            for (int i = 0; i < Rows; i++)
                for (int j = 0; j < Columns; j++)
                    matrix[i, j] = this[i, j];
            return matrix;
        }

        public override string ToString()
        {
            string str = "";
            for (int i = 0; i < Rows; i++)
            {
                str += "{";
                for (int j = 0; j < Columns; j++)
                {
                    if (j != 0)
                        str += ",";
                    str += this[i,j];
                }
                str += "}";
            }
            return str;
        }
    }

Код

    public class Vector : MyMatrix
    {
        public Vector(float x, float y, float z)
            : base(new float[1, 3] { { x, y, z } })
        {
        }

        public float this[int i]
        {
            get
            {
                return this[0, i];
            }
            set
            {
                this[0, i] = value;
            }
        }

        public float X
        {
            get
            {
                return this[0];
            }
            set
            {
                this[0] = value;
            }
        }

        public float Y
        {
            get
            {
                return this[1];
            }
            set
            {
                this[1] = value;
            }
        }

        public float Z
        {
            get
            {
                return this[2];
            }
            set
            {
                this[2] = value;
            }
        }

        public float GetLength()
        {
            return (float)Math.Sqrt(X * X + Y * Y + Z * Z);
        }

        public float GetLengthSquared()
        {
            return (X * X + Y * Y + Z * Z);
        }

        public void Normalize()
        {
            float length = GetLength();
            if (length == 0)
            {
                throw new DivideByZeroException("Невожможно нормализовать нулевой вектор.");
            }

            X /= length;
            Y /= length;
            Z /= length;
        }

        public static float Angle(Vector u, Vector v)
        {
            return (float)Math.Acos(Vector.ScalarProduct(u, v) / (u.GetLength() * v.GetLength()));
        }

        public static float ScalarProduct(Vector u, Vector v)
        {
            return u.X * v.X + u.Y * v.Y + u.Z * v.Z;
        }

        public static Vector CrossProduct(Vector u, Vector v)
        {
            return new Vector(u.Y * v.Z - u.Z * v.Y, u.Z * v.X - u.X * v.Z, u.X * v.Y - u.Y * v.X);
        }

        public static Vector operator *(Vector u, Vector v)
        {
            return Vector.CrossProduct(u, v);
        }

        public static explicit operator float[](Vector v)
        {
            float[] array = new float[v.Columns];
            for (int i = 0; i < v.Columns; i++)
                    array[i] = v[i];
            return array;
        }
    }

Автор: marcusmae 30.5.2007, 14:49
Цитата(Elfet @  30.5.2007,  13:11 Найти цитируемый пост)
Я дулул так как нас учил препод по алгебре - вектора - это всего лишь подвид матриц  

С некоторых позиций, ступенька - это, конечно, подвид лестниц. Больше того, в программировании (особенно, коммерческом) разведение сколь-угодно летающих крокодилов по соображениям целесообразности не принято считать большИм злом. Другое дело, что утверждение Вашего преподавателя пользы-то никакой не приносит. Потверждением тому служит Ваш же код : от наследования ровным счётом ничего нового не приобрели - всё это и так уже было в http://msdn2.microsoft.com/en-us/library/system.array_members.aspx. С точки зрения фундаментальной теории, одномерные векторные пространства мало похожи на многомерные. В них могут вводиться различные метрики (например, норма, как корень из скалярного произведения вектора на себя Vs. спектральная норма матрицы, Сh- или L2- и тд.), рассмотрение многих свойств и характеристик бессмысленно. В конечном итоге, эти самые свойства служат цели создания на их основе некоторых хороших алгоритмов, например, для решения систем линейных алгебраических уравнений или поиска спектра матрицы (оператора). А хорошие (эффективные) алгоритмы, как правило, работают только с объектами достаточно специального вида. Так что, не сочтите за занудство и разрешите посоветовать делать разумные обобщения. smile 

Автор: Elfet 30.5.2007, 16:16
Цитата(marcusmae @  30.5.2007,  15:49 Найти цитируемый пост)
С некоторых позиций, ступенька - это, конечно, подвид лестниц

Да, забавно  smile Ну рас уж сделано, то переделывать не буду smile

Автор: Elfet 2.6.2007, 10:43
Что-то мне не нравился что у меня получилось:
Код

Vector v = new Vector(1,1,1);
Vector n = -v; //не проходит, так как получается после "-" MyMatrix нужно писать new Vector(-v)   :-|

Как избавиться можно от этого?

Автор: lam0x7C4 3.6.2007, 15:49
Цитата(Elfet @ 2.6.2007,  10:43)
Код

Vector n = -v; 



Думаю, можна только так:
Код

Vector n = new Vector(-v);

Автор: Retro 3.6.2007, 16:42
Цитата(lam0x7C4 @  3.6.2007,  14:49 Найти цитируемый пост)
Думаю, можна только так:

А если проверить? smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)