Avatar billede dinirex Nybegynder
01. oktober 2009 - 13:54 Der er 12 kommentarer og
1 løsning

Superclass gør brug af ukendt subclass object

Hej.

Jeg har et lille problem, jeg gerne vil høre om der er nogen af jer, der kan løse.

Jeg har en general funktion i min super class, som skal modtage et object fra en af sub classerne.

Funktionen skal være så general, at ligemeget hvilken en af subclasserne der kalder den, skal den kunne udføres.

Eks:

class A
{
  setData(int type, object e)
  {
      e.doSomeThing();
  }
}

class B : A
{

  BrugSetData()
  {
    setData(0, this);
  }

}

Dette skulle gerne gøre, at jeg får en kopi af mit B objekt, og i setData, skulle jeg gerne have adgang til attributterne i B objektet.

Dette kan jeg ikke få til at fungere, ved ikke hvad parameteren skal være istedet for object for, at få det til at virke.

Nogen forslag? Meget gerne med eksempler.

På forhånd tak.
Avatar billede coreclr Nybegynder
01. oktober 2009 - 14:08 #1
Benyt et interface:

  public abstract class BaseClass
  {
      protected void Run(ILogic logic)
      {
        logic.DoLogic();
      }
  }

  public class A : ILogic
  {
      public void DoLogic()
      {
      }
  }

  public class B : ILogic
  {
      public void DoLogic()
      {
      }
  }

  public interface ILogic
  {
      void DoLogic();
  }
Avatar billede softspot Forsker
01. oktober 2009 - 14:12 #2
Umiddelbart vil jeg jo mene at en superklasse IKKE må vide noget om hvad der er defineret af egenskaber eller metoder på en subklasse. Derfor skal superklassen benytte sig af det interface som den selv (eller dens egen superklasse) definerer - ellers hører den funktionalitet, efter min mening, ikke til på den aktuelle klasse...

Mht. det du efterspørger, så vil jeg mene det kan klares med en virtual metode. Noget i stil med dette:

class A
{
  setData(int type)
  {
      doSomething();
  }

  protected virtual void doSomething() { }
}

class B : A
{

  BrugSetData()
  {
    setData(0);
  }

  protected override void doSomething() { }
}
Avatar billede sirius Nybegynder
01. oktober 2009 - 14:11 #3
er ikke helt sikker på hvad du mener, men kan det være noget ala det her:

abstract class A
{
    abstract protected string Test { get; set; }
    protected void setData(int type)
    {
        Test = "ABC";
    }
}

class B : A
{
    protected override string Test { get; set; }

    void BrugSetData()
    {
        setData(0);
    }
}
Avatar billede softspot Forsker
01. oktober 2009 - 14:17 #4
"Dette skulle gerne gøre, at jeg får en kopi af mit B objekt, og i setData, skulle jeg gerne have adgang til attributterne i B objektet" >> Hvad er det egentlig helt præcis du vil opnå?
Avatar billede bitmatic Nybegynder
01. oktober 2009 - 14:37 #5
En superclass må sgu ikke kende til dens subclasses....

Kan du ikke prøve at beskrive lidt mere i fritekst hvad det er du vil opnå, og så er der sikkert nogen herinde der kan anbefale dig en  måde at gøre det på, der ikke får binder unødige knuder på OOP.
Avatar billede dinirex Nybegynder
01. oktober 2009 - 15:41 #6
Tror ikke rigtig i har forstået mit spørgsmål helt korrekt.

Har fået fortalt at BaseClass ikke må kende til SubClass.

Det jeg ønsker er, at tilgå attributter på et objekt, men jeg ikke ikke typen på objekt.

void testafobjekt( object e)
{
    //Whatever needs to happen
}

testafobjekt skal kunne kaldes ved at give en kopi af et objekt.

A objA;
B objB;

objA og ojbB har hver sin setData verison, og inde i deres version kalder de så testafobject. Det vil sige at objA vil sende en kopi af et objekt fra class A og objB vil sende en kopi af et objekt fra class B.
Avatar billede coreclr Nybegynder
01. oktober 2009 - 15:51 #7
Mener du sådan her:

public class WorkerClass
  {
      public void DoStuff(ILogic logic)
      {
        logic.DoLogic();
      }
  }

  public class A : ILogic
  {
      public void SetData()
      {
        WorkerClass worker = new WorkerClass();
        worker.DoStuff(this);
      }

      public void DoLogic()
      {
      }
  }

  public class B : ILogic
  {
      public void SetData()
      {
        WorkerClass worker = new WorkerClass();
        worker.DoStuff(this);
      }

      public void DoLogic()
      {
      }
  }

  public interface ILogic
  {
      void DoLogic();
  }


Men jeg ville nu løse det sådan her i stedet:
  public class Tester
  {
      public void Run()
      {
        WorkerClass worker = new WorkerClass();
        A a = new A();
        worker.DoStuff(a);
      }
  }

  public class WorkerClass
  {
      public void DoStuff(ILogic logic)
      {
        logic.DoLogic();
      }
  }

  public class A : ILogic
  {
      public void DoLogic()
      {
      }
  }

  public class B : ILogic
  {
      public void DoLogic()
      {
      }
  }

  public interface ILogic
  {
      void DoLogic();
  }
Avatar billede dinirex Nybegynder
01. oktober 2009 - 20:31 #8
Næsten, eftersom A er en subclass af ILogic, vil den kunne tilgå DoLogic( parameter ), hvor parameter er en template (i c++) for et ukendt klasse objekt.

Altså


  //SuperClass
  public class ILogic
  {
      void DoLogic( parameter e, int type )
      {
          switch( type )
          {
                    case 0:
                    {
                        // Hvis objekt af type A gør hvad der
                        // skal gøres
                        break;
                    }

                    case 1:
                    {
                        // Hvis objekt af type B gør hvad der
                        // skal gøres
                        break;
                    }

          }


      }

  }

  //SubClass
  public class A : ILogic
  {
      public void SetData()
      {
        DoLogic( this );
      }
  }

  //SubClass
  public class B : ILogic
  {
      public void SetData()
      {
        DoLogic( this );
      }
  }

  Main()
  {
    A a = new A();
    B b = new B();

    a.SetData();
    b.SetData();
  }
Avatar billede coreclr Nybegynder
01. oktober 2009 - 20:50 #9
Jeg mener at det er den forkerte måde at løse det på. Drop switch/case og brug istedet polymorphism, ligesom i #1.

Du burde ligge logikken fra case 0 ind i klasse A og logikken fra case 1 ind i klasse b.
Avatar billede coreclr Nybegynder
01. oktober 2009 - 21:02 #10
Jeg kan ikke anbefalse det, men du kan naturligvis benytte if/else/switch og så lave metoden generic.

ala:

public class WorkerClass
    {
        public void DoLogic<T>(T type)
        {
            if (type is A)
            {

            }
            else if (type is B)
            {

            }
        }
    }


  public class A
  {
      public void SetData()
      {
          WorkerClass obj = new WorkerClass();
          obj.DoLogic<A>(this);
      }
  }

 
  public class B
  {
      public void SetData()
      {
          WorkerClass obj = new WorkerClass();
          obj.DoLogic<B>(this);
      }
  }
Avatar billede coreclr Nybegynder
01. oktober 2009 - 21:07 #11
Du skal nok bruge en constraint, where T : ILogic

public class WorkerClass
    {
        public void DoLogic<T>(T type) where T : ILogic
        {
            if (type is A)
            {
               
            }
            else if (type is B)
            {

            }
        }
    }


    public class A : ILogic
  {
      public void SetData()
      {
          WorkerClass obj = new WorkerClass();
          obj.DoLogic<A>(this);
      }

      public string Name { get; set; }
  }


  public class B : ILogic
  {
      public void SetData()
      {
          WorkerClass obj = new WorkerClass();
          obj.DoLogic<B>(this);
      }

      public string Name { get; set; }
  }


  public interface ILogic
  {
      string Name { get; set; }
  }
Avatar billede dinirex Nybegynder
01. oktober 2009 - 22:06 #12
Okay. Jeg har fået det til at virke, men det passer ikke designmæssigt ind i programmet, og jeg har derfor valgt at droppe idéen.

Men jeg siger tak for hjælpen, og coreclr hvis du smider et svar, kan du få pointene.
Avatar billede coreclr Nybegynder
01. oktober 2009 - 22:12 #13
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester