Laden...

Gleichzeitig von Interface und abstrakter Klasse erben, ok?

Erstellt von moon-safari vor 12 Jahren Letzter Beitrag vor 12 Jahren 1.519 Views
M
moon-safari Themenstarter:in
1 Beiträge seit 2012
vor 12 Jahren
Gleichzeitig von Interface und abstrakter Klasse erben, ok?

Hallo zusammen!

Ich versuche mich gerade mit interfaces und abstrakten Klassen auseinanderzusetzen und hab zum Üben hierfür ne kleine Basis Geometrie Bibliothek geschrieben.
Also ich hoffe man versteht anhand des Codes schon, was ich versucht hab zu erreichen. Es gibt also ein Interface IXYZ und eine davon abgeleitete abstrakte Klasse XYZ, die nur Werte für die drei Raumkoordinaten beinhalten (und zwei unterschiedliche Konstruktorfunktionen). Außerdem werden die Interfaces IPoint und IVector ebenfalls von IXYZ abgeleitet und um einige spezifische Methoden erweitert. Die Klasse Point wird nun sowohl von XYZ (um die Konstruktorfunktionien zu erhalten) als auch von IPoint abgeleitet. Dasselbe gilt für die Klasse Vector. Jetzt funktionier das ja so alles recht gut, aber ich befürchte, dass das nicht gerade allerbeste Programmierpraxis ist. Ich leite Point ja letztendlich von einem Interface und einer abstrakten Klasse ab, die beide wiederum vom selben Interface abgeleitet wurden.
Also gibt es irgendeinen besseren Weg, um die gleiche Funktionalität zu erreichen?

    interface IXYZ
    {
        double x
        {
            get;
            set;
        }

        double y
        {
            get;
            set;
        }

        double z
        {
            get;
            set;
        }
    }

    abstract class XYZ : IXYZ
    {
        private double _x;
        private double _y;
        private double _z;

        public double x
        {
            get { return _x; }
            set { _x = value; }
        }

        public double y
        {
            get { return _y; }
            set { _y = value; }
        }

        public double z
        {
            get { return _z; }
            set { _z = value; }
        }

        public XYZ()
        {
            this.x = 0;
            this.y = 0;
            this.z = 0;
        }

        public XYZ(double x, double y, double z)
        {
            this.x = x;
            this.y = y;
            this.z = z;
        }
    }

    interface IPoint : IXYZ
    {
        double distanceTo(IPoint c);
        IPoint matrixTransform(Matrix4x4 m);
    }

    interface IVector : IXYZ
    {
        double length
        {
            get;
            set;
        }

        IVector matrixTransform(Matrix4x4 m);
        double dotMultiply(IVector v);
        IVector crossMultiply(IVector v);
        IVector normalize();
    }

    class Point : XYZ, IPoint
    {
        public Point() : base()
        {
        }

        public Point(double x, double y, double z) : base(x, y, z)
        {
        }

        public double distanceTo(IPoint p)
        {
            double dx = p.x - this.x;
            double dy = p.y - this.y;
            double dz = p.z - this.z;
            return Math.Sqrt(dx * dx + dy * dy + dz * dz);
        }

        public IPoint matrixTransform(Matrix4x4 m)
        {
            return matrixMultiply(m, this);
        }

        public static Point operator *(Matrix4x4 m, Point a)
        {
            return matrixMultiply(m, a);
        }

        private static Point matrixMultiply(Matrix4x4 m, IPoint a)
        {
           //....
        }

    }

    class Vector : XYZ, IVector
    {
        public double length
        {
            get { return Math.Sqrt(this.x * this.x + this.y * this.y + this.z * this.z); }
            set { }
        }

        public Vector(double x, double y, double z) : base(x, y, z)
        {
        }

        public IVector matrixTransform(Matrix4x4 m)
        {
            return matrixMultiply(m, this);
        }

        public double dotMultiply(IVector v)
        {
            return dotProduct(this, v);
        }

        public IVector crossMultiply(IVector v)
        {
            return crossProduct(this, v);
        }

        public IVector normalize()
        {
            return normalization(this);
        }

        private static Vector matrixMultiply(Matrix4x4 m, IVector a)
        {
           //....
        }

        private static Vector normalization(IVector a)
        {
           //....
        }

        private static Vector vectorAddition(IVector a, IVector b)
        {
            //....
        }

        private static double dotProduct(IVector a, IVector b)
        {
           //...
        }

        private static Vector crossProduct(IVector a, IVector b)
        {
           //....
        }
    }
C
1.214 Beiträge seit 2006
vor 12 Jahren

Ich leite Point ja letztendlich von einem Interface und einer abstrakten Klasse ab, die beide wiederum vom selben Interface abgeleitet wurden

Das macht nichts.

F
10.010 Beiträge seit 2004
vor 12 Jahren

@moon-safari :

Ich leite Point ja letztendlich von einem Interface und einer abstrakten Klasse ab,

Nein, Du leitest von einer Klasse ab, Implementierst ein Interface, das ist ein unterschied.

L
11 Beiträge seit 2012
vor 12 Jahren
Hinweis von herbivore vor 12 Jahren

Vorne weg: Echte Mehrfachvererbung, also das Erben von mehreren Klassen, ist in C# allerdings nicht möglich und kann daher nicht genutzt werden.

Also generell: wenn Mehrfachvererbung möglich ist darf man sie auch nutzen. Sonst gäbe es sie ja nicht. 😉

In diesem Fall ist es aber so wie FZelle schon schrieb: du leitest von einer abstrakten Klasse ab und implementierst ein Interface. Das ist, soweit ich die Literatur verstanden habe, gängige Praxis.

Ich verstehe nur den Sinn hinter deinen Interfaces (aktuell) nicht.
Das IXYZ Interface verstehe ich, da ja sowohl XYZ als auch Point und Vector dieses Interface implementieren.

Warum du dir aber IVector und IPoint Interfaces angelegt hast verstehe ich nicht.
Du benutzt sie ja nur in Vector und Point, und da kannst du es auch eigentlich ohne Interface einfach runtertippen.

Es gibt 10 Arten von Menschen. Die einen verstehen das binäre Zahlensystem, die anderen nicht.