Avatar billede websam Nybegynder
20. marts 2007 - 11:55 Der er 13 kommentarer og
2 løsninger

At arve ?

Hejsa,

Jeg har et spørgsmål til det med at arve. Hvis jeg har en klasse som nedenfor :

Interface myInterface
{
    bool myMethod
}

class myClass : myInterface
{
    public bool myMethod
    {
        // noget kode her
    }
}

altså har jeg her benyttet mig af et interface som myClass inplemntere.

Hvordan arver jeg fra denne klasse ?

/Websam
Avatar billede thomas_yde Nybegynder
20. marts 2007 - 12:44 #1
class MyNewClass : myClass
{
public MyNewClass(){}
//code away...
}
Avatar billede websam Nybegynder
20. marts 2007 - 13:25 #2
Det ser som oxo fint ud men hvis jeg så vælger at vil bruge et interface i den nye klasse hvordan skal det så se ud ?

interface MyNewInterface
{
    bool myNewMethod
}

class MyNewClass : ???
{
    public MyNewClass(){}
    //code away...
}

Og sidst men ikke mindst har jeg så forstået det rigtigt at jeg så igennem den nye klasse kan trække alle metoder fra base klassen, noget i stil med dette :

MyNewClass obj = new MyNewClass

obj.myMethod(); //fra base klassen

/Websam
Avatar billede thomas_yde Nybegynder
20. marts 2007 - 13:42 #3
Fx.
using System;
using System.Collections.Generic;
using System.Text;

namespace Playground
{
    public enum AnimalType
    {
        Horse,
        Duck,
        Dog
    }
    interface AnimalInterface
    {
        AnimalType getAnimalType();
    }

    class Animal : AnimalInterface
    {
        public AnimalType type;

        public AnimalType getAnimalType()
        {
            return type;
        }
    }

    interface DuckInterface
    {
        void Quak();
    }

    class Duck : Animal, DuckInterface
    {
        public Duck()
        {
            base.type = AnimalType.Duck;
        }

        public void Quak()
        {
            Console.WriteLine("Duck goes Quak quak!");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Duck d = new Duck();
            d.Quak();
            Console.ReadLine();
        }
    }
}


Ved ikke om det er det bedste eksempel. det gik lidt hurtigt.
Avatar billede thomas_yde Nybegynder
20. marts 2007 - 13:47 #4
tilføjelse til main:
Console.WriteLine("Created object " + d.getAnimalType().ToString());

Du kan tilgå metoderne.
Avatar billede crazysnap Seniormester
20. marts 2007 - 14:50 #5
Hej websam,

For at svare mere specifikt på dine spørgsmål:


1) Hvordan nedarver man både fra en klasse og et interface på samme tid:


class MyNewClass : BaseClass, IClass
{
    //Alle metoderne i IClass SKAL implementeres
}


2) Kan man så kalde alle metoderne i BaseClass fra et MyNewClass objekt?

Du kan kalde alle metoderne i BaseClass som er 'public' (de er som default 'private'). Så alle metoder defineret som:


public void metode() {}


i BaseClass Kan kaldes fra et MyNewClass objekt.



3) Hvad kan man så se af metoder og varaible fra BaseClass i sin nedarvede MyNewClass?

Der kan man se og tilgå alle 'protected' og 'public' metoder og variable.



Mvh.

- Snap :)
Avatar billede websam Nybegynder
21. marts 2007 - 06:13 #6
crazysnap >>

1. Som jeg husker det kan jeg da ikke andet end at implementere alle metoder uden at den kommer med fejl men det er da muligt jeg tager fejl.

2. Jeg er med på at private metoder ikke kan tilgåes fra en anden klasse jeg gad bare ikke skrive public på mine metoder (dovenskab)

3. Det med public, protected osv. skulle der oxo være styr på ;o)

Men ellers tak for indput.
Avatar billede crazysnap Seniormester
21. marts 2007 - 09:32 #7
Hej websam,

Det er fuldstændig korrekt at du skal implementere alle metoder fra dit interface i din klasse eller kommer compileren med en fejl (derfor jeg skrev):    :)


class MyNewClass : BaseClass, IClass
{
    //Alle metoderne i IClass SKAL implementeres
}


Men du behøver selvfølgelig ikke overskrive nogen af metoderne i BaseClass. :)


Mvh.

- Snap
Avatar billede websam Nybegynder
22. marts 2007 - 18:09 #8
Ok jeg har leget lidt med det, så kome venligst med lidt kritik ;o)

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace myNamespace1
{
    public interface iClass
    {
        string GetUser();
    }

    public class Class1
    {
        private int _UserId;
        public int UserId
        {
            get { return _UserId; }
            set { _UserId = value; }
        }

        private string _Firstname;
        public string Firstname
        {
            get { return _Firstname; }
            set { _Firstname = value; }
        }

        private string _Lastname;
        public string Lastname
        {
            get { return _Lastname; }
            set { _Lastname = value; }
        }

        private void PopulateDefault()
        {
            _Id = 0;
            _Firstname = "";
            _Lastname = "";
        }

        public Class1()
        {
            PopulateDefault();
        }

        public Class1(int Id)
        {
            PopulateDefault();
        }

        public string GetUser()
        {
            return "Brugeren med Id : " + _UserId + " ved navn : " + _Firstname + " " + _Lastname + ".";
        }
    }
}

###################################################################################

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace myNamespace2
{
    public class Class2 : myNamespace1.Class1, myNamespace1.iClass
    {
        // En masse ny kode her . . .
    }
}

####################################################################################

Her kalder jeg så fra min code-behind :

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using myNamespace2;

public partial class Test_Test1 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Class2 obj = new Class2();
        obj.UserId = 12;
        obj.Firstname = "John";
        obj.Lastname = "Doe";
        Response.Write(obj.GetUser().ToString());
    }
}

####################################################################################

hvilket jo så som forventet udskriver "Brugeren med Id : 12 ved navn : John Doe." til skærmen.

Men hvis nu jeg så vil overskrive en eller flere metoder fra min Class1 hvordan bære jeg mig så ad ?

/Websam
Avatar billede snepnet Nybegynder
22. marts 2007 - 18:36 #9
Du gør metoden virtual i class1, og laver et override i class2
F.eks.:

// i class1
public virtual string GetUser()
{
  return "...";
}

// i class2
public override string GetUser()
{
  // din implementering
}

Mvh
Avatar billede websam Nybegynder
22. marts 2007 - 19:02 #10
Hej snepnet...

Det vil sige at man faktisk skal gøre sig til vane at lave dem virtual for på sigt at kunne arve fra klasserne man med tiden har lavet ?
Avatar billede crazysnap Seniormester
22. marts 2007 - 22:11 #11
Hej websam,


Du behøver ikke lave dem virtual, at lave dem virtual er dog en vigtig egenskab af polymorphismen og gør at hvis du kalder en metode i base-klassen er det den overskrevede metode i den nedarvede klasse der bliver kaldt, eksempel:


class BaseClass
{
    public virtual string GetUser();
    {
        return "Base";
    }
}

class Class1 : BaseClass
{
    public override string GetUser()
    {
        return "Class1";
    }
}


BaseClass bs = new Class1();
Response.Write(bs.GetUser());  //Udskriver "Class1"


Dvs, hvis du kalder metoden fra BaseClass'en kalder den metoden fra Class1.
Hvis du derimod ikke bruger 'virtual' kan du bruge 'new' til at overskrive en metode i base-klassen, forskellen er bare at hvis du kalder bs.GetUser() kalder den ikke metoden i Class1 men metoden i BaseClass, eksempel:


class BaseClass
{
    public string GetUser();
    {
        return "Base";
    }
}

class Class1 : BaseClass
{
    public new string GetUser()
    {
        return "Class1";
    }
}


BaseClass bs = new Class1();
Response.Write(bs.GetUser());  //Udskriver "Base"

Class1 c1 = (Class1)bs;
Response.Write(c1.GetUser());  //Udskriver "Class1"



Håber det klargjorde det lidt! :)


Mvh.

- Snap
Avatar billede snepnet Nybegynder
22. marts 2007 - 23:31 #12
Du skal ikke gøre det til en vane at lave metoderne virtuelle... Det er en beslutning du tager fra metode til metode, og hvis du flager dem som override'able - skal du jo så også helst have sikret dig at det rent faktisk kan lade sig gøre, uden at funktionaliteten knækker.

Som snap skriver kan du godt redifinere en metode i en nedarvet klasse, men det er vanligvis lidt mere risikabelt, da du ikke nødvendigvis ved hvad du ender op med. Som du kan se af snaps eksempel - vil du kunne risikere at få kørt baseklassens metode i nogle tilfælde, og din egen implementering i andre.
En fortsættelse af snaps eksempel:

Du har hentet et livssimulerings framework på nettet, og i det findes følgende klasse:

public class Human
{
  public void Run()
  {
    // implementering af noget med at sætte den ene fod foran den anden..
    // og tælle en distance op
  }
}

I din egen applikatikation har du særlige behov, og har været nødt til at specialisere

public class HumanWithoutLegs : Human
{
  public new void Run()
  {
    // lad være med at tælle en distance op
    // eller smid måske en exception.
  }
}

Og frameworket giver dig mulighed for at sætte liv i dine personer:

// dit program
Human h = new Human();
LifeEngine.StartModernLife(h);

Så starter personen et simuleret liv....

Metoden StartModernLife tager naturligvis et objekt af typen Human som parameter.

Det vil du så også gerne gøre med din egen person:

HumanWithoutLegs hh = new HumanWithoutLegs();
LifeEngine.StartModernLife(hh);

Hvilket går godt, fordi din egen type - HumanWithoutLegs - er en specialisering af Human.

Nu er det så sådan, at noget af det bemeldte simalator gør er følgende:

if(CurrentDay == Day.Sunday)
{
  Gym gym = new Gym();
  gym.ActivateHuman(h); // hvor h skal være af typen Human
}

Gymnastiksalen gør så følgende

public class Gym
{
  public void ActivateHuman(Human human)
  {
    human.Run();
  }
}

Hvilket vil have et temmelig uheldigt impact på din application - i og med at din person uden ben vil begynde at løbe...?!?

Hvis vi tager dit program igen (og forestiller os at du har redefineret Run med new:
HumanWithoutLegs hh = new HumanWithoutLegs();
LifeEngine.StartModernLife(hh);

Og ændrer det sådan her:
HumanWithoutLegs hh = new HumanWithoutLegs();
hh.Run();
LifeEngine.StartModernLife(hh);

Så vil dit eget kald til hh.Run() gøre som den skal, men det kald frameworket udfører efterfølgende vil gøre noget aldeles ulogisk - nemlig at lade personen gå.
Det samme objekt vil altså opføre sig forskelligt rundt omkring i din applikation.

Den slags applikationer er ikke rare at have med at gøre.

Havde du gjort som følger:
public class Human
{
  public virtual void Run()
  {
    // implementering af noget med at sætte den ene fod foran den anden..
  }
}

public class HumanWithoutLegs : Human
{
  public override void Run()
  {
    // lad være med at tælle en distance op
    // eller smid måske en exception.
  }
}

Ville du have fået din egen implementering.

Ganske kort kan det siges, at den virtuelle metode medfører at den faktiske metode først bliver slået op på kørselstidspunktet, hvorimod den ikke-virtuelle slås op på kompileringstidspunktet.

I det tilfælde hvor Run() ikke er vituel vil det her:
public class Gym
{
  public void ActivateHuman(Human human)
  {
    human.Run();
  }
}

Medføre at kompileren kan slå Human-klassens implementering af Run op (og måske endda inline den, hvis den finder det mest optimalt), og på den måde får du aldrig kørt din egen implementering.

Det er et tænkt eksempel, men er du med på risikoen?

Mvh
Avatar billede websam Nybegynder
17. juni 2007 - 09:02 #13
smid et svar begge ;o)
Avatar billede crazysnap Seniormester
17. juni 2007 - 18:12 #14
Der kommer et herfra! :)


Mvh.

- Snap
Avatar billede snepnet Nybegynder
21. juni 2007 - 15:06 #15
Og et her :o)
Mvh
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