Diskuze: C# "Vytvoření instance sama sebe" - Předání hodnoty jinému objektu.
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 13 zpráv z 13.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Abych pravdu řekl, dost dobře nechápu, čeho chceš dosáhnout, ale nemohl bys nějakou třídu od jiné třeba podědit?
Jestli metoda potřebuje pracovat s nějakým objektem, tak jí prostě předáš ten objekt:
class First
{
//spousty vlastností a metod
}
class Second
{
public void Metoda(First instance)
{
//nyní pracuj s instancí 1. třídy
}
}
Jestli to dobře chápu, tak se navázájem třídy mohou požívat takto:
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello C#");
Trida1 trida1 = new Trida1();
Trida2 trida2 = new Trida2();
trida1.Trida2 = trida2;
trida2.Trida1 = trida1;
}
}
public class Trida1
{
public Trida2 Trida2 { get; set; }
public void NejakaMetoda()
{
Trida2.PrvniMetoda();
}
public void DalsiMetoda()
{}
}
public class Trida2
{
public Trida1 Trida1 { get; set; }
public void PrvniMetoda()
{
}
public void DruhaMetoda()
{
Trida1.DalsiMetoda();
}
}
(online: http://volatileread.com/…ppetcompiler?…)
Není to ale uplně dobré.
Spíš by chtělo vědět k čemu to potřebuješ a možná zvolit lepší
návrh...
Pardon, asi jsem to špatně vyjádřil...
using System;
class Program
{
static void Main()
{
Game game = new Game();
game.MainLoop();
}
}
class Game
{
public int zivot { get; private set; }
public int skore { get; private set; }
public void MainLoop()
{
GameFrame gameframe = new GameFrame();
for(;;)
{
// Prubeh hry
gameframe.vykresli();
}
}
}
class GameFrame
{
public void vykresli()
{
// Zde nejaky "graficky" prvek
Console.Write("Zde potrebuji vypsat skore"); // Zde potrebuji vlastnost, ktera se ale nachazi ve tride Game
// Je zde moznost vyuzit parametru, ale co kdyz tech vlastnosti bude vic a budou vice sofistikovane
}
}
Děkuji všem za rady.
Zkoušel jsem tu dědičnost, ale ta dědí pouze dané metody ale ne hodnoty,
nebo se mýlím?
Určitě i hodnoty když v ní jsou v definici třídy, nicméně ty za běhu samozřejmě ne, dědí se třída, ne její instance.
Každopádně dělá se to parametrem přesně jak říkáš v komentu když jich máš 50 těch parametrů, můžeš jako parametr předat rovnou celou instanci v které je těch 50 proměnných které potřebuješ.
Tak jsem to s tou dědičností myslel
A jak v tomto případě mám předat tu instanci, když už jsem uvnitř té třídy "Game"?
Takhle:
class Game
{
public int zivot { get; private set; }
public int skore { get; private set; }
public void MainLoop()
{
GameFrame gameframe = new GameFrame(this);
for (;;)
{
// Prubeh hry
gameframe.vykresli();
}
}
}
class GameFrame
{
private Game game;
public GameFrame(Game g)
{
this.game = g;
}
public void vykresli()
{
// Zde nejaky "graficky" prvek
Console.Write("Score: " + game.skore); // Zde potrebuji vlastnost, ktera se ale nachazi ve tride Game
// Je zde moznost vyuzit parametru, ale co kdyz tech vlastnosti bude vic a budou vice sofistikovane
}
}
Martine perfektní
Než ti to odkliknu, mohl by jsi mi lehce objasnit, jak to funguje
GameFrame gameframe = new GameFrame(this);
Spis, jak to, že parametr this bere tu instanci. Díky
A to, že se nedá tato instance vytvořit v rámci celé dané třídy, ale jen v nějaké metodě je asi zapříčiněné tím, že v té době nějak neexistuje nebo proč?
Ptám se proto, že bych se rád poučil z chyb a věděl proč to tak funguje
Díky
Pod klíčovým slovem this se skrývá instance dané třídy. Takže do konstruktoru třídy GameFrame předáme parametrem instanci třídy Game. Mohl bys předávat instanci té třídy i přímo do metody vykresli(), ale to bys ji předával při každém vykreslení, což je zbytečné.
Jinak druhému dotazu moc nerozumím. Ale v zásadě v Mainu jsi vytvořil instanci třídy Game a zavolal metodu MainLoop(). V této chvíli instance třídy Game existuje a je uložená někde v paměti. Dá se k ní přistupovat přes veřejné metody a proměnné.
GameFrame gameframe = new GameFrame(this);
Tímhle řádkem jsi řekl, že se má vytvořit nová instance třídy GameFrame a zavolal jsi její konstruktor. V konstruktoru jsi jí pomocí this předal instanci třídy Game (protože jsi ji vytvořil v třídě Game), takže teď k ní můžeš přes veřejné metody a proměnné přistupovat.
Kdyžtak doporučuju projít zdejší tutoriály o OOP, jsou dost kvalitní a
zodpoví to mnoho otázek.
Užitečný odkaz o klíčovém slovu this : https://msdn.microsoft.com/…k1507sz.aspx?…
Klidně se na cokoli dalšího ptej.
Díval jsem se zrovna co všechno this umí a jsem překvapen . Jinak zdejší tutoriály na OOP jsem projížděl, ale měl bych si je zopakovat . Ono to člověku je vše jasné, než nezačne sám něco programovat.
Ještě zkusím upřesnit ten poslední dotaz.
class Game
{
public int zivot { get; private set; }
public int skore { get; private set; }
GameFrame gameframe = new GameFrame(this); // Zde je chyba, proc?
public void MainLoop()
{
GameFrame gameframe = new GameFrame(this); // Zde je vse v poradku.
for (;;)
{
// Prubeh hry
gameframe.vykresli();
}
}
}
Chyba tam vyskočí proto, že instance se vytvoří poté, co proběhne konstruktor. V tomhle případě instance ještě neexistuje, proto to hlásí chybu. Dobré je to napsat například takhle:
class Game
{
public int zivot { get; private set; }
public int skore { get; private set; }
private GameFrame gameframe;
public Game()
{
gameframe = new GameFrame(this); // v momentě, kdy se vykoná tento kód je jasné, o jakou instanci se jedná
}
public void MainLoop()
{
while (true) // je zvyk psát nekonečný cyklus takhle, ale samozřejmě to už je otázka vkusu :)
{
// Prubeh hry
gameframe.vykresli();
}
}
}
Funguje to. Moc díky za tvůj čas a vysvětlení. Pomohl jsi mi .
Zobrazeno 13 zpráv z 13.