Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Vererbte Klassen zu Interface vereinigen
exaveal
myCSharp.de - Member



Dabei seit:
Beiträge: 100

Themenstarter:

Vererbte Klassen zu Interface vereinigen

beantworten | zitieren | melden

Moin Leute.

Ich habe zwei Klassen:


class ControlA : UserControl
class ControlB : UserControl

Diese beiden Klasse haben viele gleiche Methoden, wie getLaenge(); und getWeite();
Ich möchte in einer gemeinsamen Liste List<T> diese Klassen verwalten. Dazu erstelle ich ein Interface:


public interface IInterface

und ändere die Klassen ab:


class ControlA : UserControl, IInterface
class ControlB : UserControl, IInterface


Nun erstelle ich meine Liste:


private List<IInterface> Liste = new List<IInterface>();


Nun kann ich aber über die Liste nur Methoden des Interface aufrufen:


Liste.ElementAt(0)).getLaenge();

aber leider keine Methoden der BasisKlasse UserForm. Mache ich die Liste vom Objekttyp UserForm dreht sich das Problem nur um.


Gibt es da eine Lösung? Ahhhh
private Nachricht | Beiträge des Benutzers
exaveal
myCSharp.de - Member



Dabei seit:
Beiträge: 100

Themenstarter:

beantworten | zitieren | melden

Okay, ich könnte das Interface einfach durch eine Klasse ersetzen. Diese erbt dann von UserForm und die ControlA und ControlB erben dann von der Klasse 'Interface'.

Gibt es vielleicht eine schönere Variante?
Ich arbeite mich grad in C# ein und wollte eigentlich den Sinn von Interfaces verstehen :D Jetzt macht mir das Interface natürlich ziemliche Probleme weil es ja nicht die Methoden von UserControl erben kann. Knifflig knifflig ...
private Nachricht | Beiträge des Benutzers
m0rius
myCSharp.de - Member

Avatar #avatar-3125.png


Dabei seit:
Beiträge: 1043

beantworten | zitieren | melden

Hallo exaveal,

warum erstellst du nicht eine Klasse MyControl, die von UserControl erbt und die gemeinsamen Methoden (bzw. Properties) von ControlA und ControlB enthält? ControlA und ControlB erben ihrerseits von MyControl.

Ein kleiner Hinweis zu Namenskonventionen und Verwendung von Methoden am Rande: getLaenge() und getWeite() sollten besser als Properties Width und Length angelegt werden. Sollen diese aus irgendeinem Grund trotzdem als Methode implementiert werden, würden sie GetWeite() und GetLaenge() bzw. besser GetWidth() und GetLength() genannt werden.

m0rius
Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg
private Nachricht | Beiträge des Benutzers
reloop
myCSharp.de - Member

Avatar #avatar-3256.jpg


Dabei seit:
Beiträge: 142

beantworten | zitieren | melden

Wenn deine Klasse das Interface IInterface zugewiesen hat, welches wiefolgt aufgebaut wäre:

public interface IInterface
{
   void myMethod();
}
Dann müsstest du zwingend in der Klasse diese Funktion auch anlegen, mittels:

public void myMethod()
{

}

Und somit ist sie auch im

private List<myClass> _liste = new List<myClass>();
_liste.ElementAt(0)).myMethod();

vorhanden. Ausschlagebender Punkt ist, dass die Methode public ist.

Gruss,
reloop


Zusammengefasst:

    public class myClass : UserControl , IInterface
    {
        public void myMethod()
        {

        }
    }

    public interface IInterface
    {
        void myMethod();
    }

    public class myTestClass
    {
        private List<myClass> _liste= new List<myClass>();

        public myTestClass()
        {
            _liste.ElementAt(0).myMethod();
        }
    }
Dieser Beitrag wurde 5 mal editiert, zum letzten Mal von reloop am .
private Nachricht | Beiträge des Benutzers
exaveal
myCSharp.de - Member



Dabei seit:
Beiträge: 100

Themenstarter:

beantworten | zitieren | melden

Zitat von m0rius
warum erstellst du nicht eine Klasse MyControl, die von UserControl erbt und die gemeinsamen Methoden (bzw. Properties) von ControlA und ControlB enthält? ControlA und ControlB erben ihrerseits von MyControl.

Okay, ich habe das jetzt so realisiert:


    public class MyUserControl: UserControl  //ehemals IInterface
    {
        public virtual void createMenu()
        {}
        public virtual void createStatus()
        {}
    }


    public partial class ControlA: MyUserControl
    {
        public new void createMenu()
        {}
        public new void createStatus()
        {}
        public void moreMethods()
        {}
    }

Jetzt motzt aber der Compiler:
Inkonsistenter Zugriff: Basisklasse "MyUserControl" ist weniger zugreifbar als Klasse "ControlA"

urgs, wie bekomm ich denn das jetzt weg? bzw was heißt weniger zugreifbar?


//EDIT:
da war ich mal wieder zu voreilig :) Habe die Klasse MyUserControl inkl. Methoden als abstract deklariert und die Methoden in den Klassen ControlA/B mit override implementiert.


Danke für die schnelle Hilfe!
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von exaveal am .
private Nachricht | Beiträge des Benutzers
xxMUROxx
myCSharp.de - Member

Avatar #avatar-3236.jpg


Dabei seit:
Beiträge: 1626
Herkunft: Südtirol/Italien

beantworten | zitieren | melden

Hallo exaveal,

weniger zugreifbar heißt in dem Moment dass eine Klasse Internal ist und die abgeleitete Public, in deinem geposteten Beispiel ist dies jedoch nicht der Fall. Bist du dir sicher dass das Gepostete Beispiel mit dem realen in deinem Programm der Fall ist, denn dein Beispiel kompiliert erwartungsgemäß bei mir.

Jedoch habe ich an dich eine Frage:
Haben deine Methoden in deiner Basisklasse einen Body? Oder sind diese nur der Zusammenfassung herausgeschnitten worden?

Gruß
Michael
Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp
private Nachricht | Beiträge des Benutzers
m0rius
myCSharp.de - Member

Avatar #avatar-3125.png


Dabei seit:
Beiträge: 1043

beantworten | zitieren | melden

Hallo exaveal,

schön, dass es jetzt geklappt hat – nur frage ich mich, ob deine hier gepostete Lösung deiner existierenden entspricht? Die Fehlermeldung des Compilers rührt daher, dass MyControl einen restriktiveren Zugriffsmodifizierer hat als ControlA.
Kann es sein, dass deine Klasse MyControl folgendermaßen implizit den Modifizierer internal verwendet? Wenn ja, setze diesen explizit auf public.

class MyControl
{
    /* ... */
}

Ohne dich nötigen zu wollen, möchte ich dir nochmal die Microsoft-Namenskonventionen, speziell die Konventionen für Methoden, ans Herz legen. Diese sind weit verbreitet und sollten IMHO befolgt werden.


m0rius
Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg
private Nachricht | Beiträge des Benutzers
exaveal
myCSharp.de - Member



Dabei seit:
Beiträge: 100

Themenstarter:

beantworten | zitieren | melden

Hallo Leute.
Erstmal: Ich finds echt super, dass Ihr so hilfsbereit seid :)

Also ich habe die Klassen im Startthread nur übersichtshalber gekürzt. Und das Beispiel was ich hier gepostet habe, entspricht nicht genau dem, welches ich verwende. Das hat den einfachen Grund, dass ich (so doof wies auch klingt) in meiner Bachelorarbeit für eine Firma programmiere. Ich will nur einfach nicht, dass sie durch googeln ihre Klassen in Foren wieder finden und ich am Ende wegen sowas abgemahnt werde.

Es war natürlich die internal/public Geschichte xxMUROxx. Ich habe den Code im Thread zwar richtig angepasst, allerdings das public in meiner abstrakten Klasse im Programmcode vergessen :)

Die Namenskonventionen werde ich mir auch nochmal anschauen. Ich erschlage mich nur gerade mit ~10 Büchern und lese viel parallel.



Das Programm ist jetzt lauffähig mit der neuen abstrakten Kasse als Interface. Dafür kann ich jetzt nicht mehr den Designer in VisualStudio 2010 für die UserControls ControlA & ControlB aufrufen. Herrlich ...
Die Fehlermeldung lautet
Der Designer kann keine Instanz des Typs TGV.TabContent erstellen, da dieser als abstrakt deklariert ist.

Naja, dann muss ich wohl zum bearbeiten der Klasse die Ableitung entfernen und zum kompilieren wieder einfügen. Etwas umständlich, aber wenigstens gehts erstmal.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von exaveal am .
private Nachricht | Beiträge des Benutzers