Diskuze: Loggin
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.


Proč zase dědí třída Account z formu?


noName:2.10.2013 10:03
Aby sdílela proměnnou:
protected bool logged = false;
David Hartinger:2.10.2013 10:07
Odkdy je logged vlastností formuláře? To snad patří uživateli. Zkus to napsat objektově.


Tak jsem to přepsal, ale nikdo mi stejně nezodpověděl moji otázku. Proč, když chci proměnnou name z Form1 zobrazit na Form2, tak to nejde. Já bych to udělal tak, že bych si vytvořil novou instanci třídy Admin a z ni pak čerpal, jenže
Account acc = new Account();
nelze vytvořit.


public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// Nový Form2
/// </summary>
protected void NewForm2()
{
this.Hide();
Form2 newForm2 = new Form2();
newForm2.Show();
}
private void loggin_Click(object sender, EventArgs e)
{
if(user.Checked)
{
Account newUser = new User(accountName.Text, accountPassword.Text);
newUser.Loggin();
newUser.logged = true;
if (newUser.logged == true)
NewForm2();
}
else if(admin.Checked)
{
Account newAdmin = new Admin(accountName.Text, accountPassword.Text);
newAdmin.Loggin();
if (newAdmin.logged == true)
NewForm2();
}
}
private void exit_Click(object sender, EventArgs e)
{
Close();
}
}
// ACCOUNT:
public abstract class Account
{
/// <summary>
/// Jméno účtu
/// </summary>
public string name { get; private set; }
/// <summary>
/// Heslo účtu
/// </summary>
public string password { get; private set; }
/// <summary>
/// Je uživatel přihlášen?
/// </summary>
public bool logged { get; set; }
/// <summary>
/// Nová instance ÚČTU
/// </summary>
public Account(string name, string password)
{
this.name = name.ToUpper();
this.password = password.ToUpper();
}
/// <summary>
/// Využití polymorfismu
/// VIRTUAL - zástupce (přepisovaná metoda)
/// </summary>
public virtual void Loggin()
{}
}
// USER:
public class User : Account
{
/// <summary>
/// Nová instance UŽIVATELE
/// </summary>
public User(string name, string password): base(name, password)
{}
/// <summary>
/// Přepsání metody Loggin pro UŽIVATELE:
/// </summary>
public override void Loggin()
{
logged = true;
MessageBox.Show(String.Format("Ahoj uživateli {0}. Tvé heslo je: {1}.", name, password));
}
}
// ADMIN:
public class Admin : Account
{
/// <summary>
/// Nová instance ADMINA
/// </summary>
public Admin(string name, string password): base(name, password)
{}
/// <summary>
/// Přepsání metody Loggin pro ADMINA
/// </summary>
public override void Loggin()
{
if ((name == "ADMIN") && (password == "HESLO"))
{
logged = true;
MessageBox.Show(String.Format("Ahoj admine {0}. Tvé heslo je: {1}.", name, password));
}
else
{
logged = false;
MessageBox.Show("Zadal jste špatné přihlašovací údaje nebo nejste admin!");
}
}
}
Luboš Běhounek Satik:2.10.2013 10:40
Projdi si tutoriály tady na Devbooku, tohle by bylo na dlouho...
Odpoledne v prográmku ti sepišu co je natom blbě
Petr Nymsa:2.10.2013 10:51
Bohužel tam je mnoho chyb. Předpokládám že nevíš co dělá klíčové slovo abstract ??
Celý návrh je špatně. Do začátku poradím. Snaž se to udělat co nejjednodušeji a postupně přijdeš na to jak to vylepšit. Uděláš si třídu Uživatel, kteýr bude mít jméno, heslo a bool přihlášen. Tuto třídu udělej podle návrhu správně -> použij vlastnosti apod.
Až budeš mít tohle, postni nám to sem a poradíme dál
Jan Vargovský:2.10.2013 14:43
protected bool logged = false;
To, že od té třídy dědíš, neznamená že je ta proměnná globální a bude všude stejná. Pro každou instanci se tvoří nová paměť, takže ty proměnné nejsou nijak sdílené atd. ty klidně můžeš mít 10 instancí, kde je nějaká bool logged a každá bude mít jinačí hodnotu.
Account acc = new Account();
Když je něco abstraktní, tak je to pouze nějaký vzor. Takže buď ho použiješ jako interface a nebo jako předka v nějaké další implementaci třídy.
public virtual void Loggin(){}
Tohle by mělo být abstraktní, protože to nemá žádnou implementaci => v děděné třídě jí pak musíš implementovat (overridnout)
Potom nějaké blbosti co vidím v kódu např.:
newUser.logged = true;
if (newUser.logged == true)
NewForm2();
ta podmínka tam ani být nemusí a jen to stačí zavolat.
Zkus to znovu, popřípadě si opravdu pročti co které klíčové slova znamenají, takhle chaoticky používáš věci a nevíš jak fungují a je to (dle mě) na tebe příliš složité. Navíc jde vidět, že jsi ani nečetl žádný tutorial a nevíš ani co je to instance atd.


1)
newUser.logged = true;
if (newUser.logged == true)
NewForm2();
Toto tam vůbec nemělo být, to byl překlep:
newUser.logged = true;
2)
public virtual void Loggin(){}
Máš pravdu, má to být takto:
public abstract void Loggin()
A nesmí obsahovat
{}
, protože překladač to nepřeloží
- Vím co je to instance... Jen jsem se asi špatně vyjádřil


public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// Nový Form2
/// </summary>
protected void NewForm2()
{
this.Hide();
Form2 newForm2 = new Form2();
newForm2.Show();
}
private void loggin_Click(object sender, EventArgs e)
{
if(user.Checked)
{
Account newUser = new User(accountName.Text, accountPassword.Text);
newUser.Loggin();
if (newUser.logged == true)
NewForm2();
}
else if(admin.Checked)
{
Account newAdmin = new Admin(accountName.Text, accountPassword.Text);
newAdmin.Loggin();
if (newAdmin.logged == true)
NewForm2();
}
}
private void exit_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
// ACCOUNT:
public abstract class Account
{
/// <summary>
/// Jméno účtu
/// </summary>
public string name { get; private set; }
/// <summary>
/// Heslo účtu
/// </summary>
public string password { get; private set; }
/// <summary>
/// Je uživatel přihlášen?
/// </summary>
public bool logged;
/// <summary>
/// Nová instance ÚČTU
/// </summary>
public Account(string name, string password)
{
this.name = name.ToUpper();
this.password = password.ToUpper();
}
/// <summary>
/// ABSTRACT - vzor (nemé tělo => žádná implementace )
/// Využití polymorfismu (přepisovaná metoda)
/// </summary>
public abstract void Loggin();
}
// USER:
public class User : Account
{
/// <summary>
/// Nová instance UŽIVATELE
/// </summary>
public User(string name, string password): base(name, password)
{}
/// <summary>
/// Přepsání metody Loggin pro UŽIVATELE:
/// </summary>
public override void Loggin()
{
logged = true;
MessageBox.Show(String.Format("Ahoj uživateli {0}. Tvé heslo je: {1}.", name, password));
}
}
// ADMIN:
public class Admin : Account
{
/// <summary>
/// Nová instance ADMINA
/// </summary>
public Admin(string name, string password): base(name, password)
{}
/// <summary>
/// Přepsání metody Loggin pro ADMINA
/// </summary>
public override void Loggin()
{
if ((name == "ADMIN") && (password == "HESLO"))
{
logged = true;
MessageBox.Show(String.Format("Ahoj admine {0}. Tvé heslo je: {1}.", name, password));
}
else
{
logged = false;
MessageBox.Show("Zadal jste špatné přihlašovací údaje nebo nejste admin!");
}
}
}
POPIS:
- Klik na tlačítko Loggin
- Podle chackBoxu vybere typ účtu
- Vytvoří se instance
- Zavolá se metoda Loggin() dle typu účtu
- Pokud bylo zadáno správné heslo nastaví proměnnou logged na true
- Pokud je logged == true zavolá se metoda NewForm2
Nechápu, co se vám na mém kódu nelíbí. Nebo teď je to OK?
Kit:2.10.2013 21:04
Můžeš pro mne něco udělat? Zlikviduj prosím ty nesmyslné komentáře. Snižují přehlednost tvého programu. Až se ty komentáře naučíš psát, tak je tam klidně zase dávej.
Jan Vargovský:2.10.2013 21:22
To, že nevíš co je instance sem vydedukoval z toho nesmyslného dědění formu.
Proč jednou používáš na zveřejnění proměnných vlastnosti a pak to prostě hodíš jen tak public?
protected modifikator na tu metodu NewForm2() trošku nechápu proč je protected ?
Proč první nastavuješ bool logged mimo třídu a pak když voláš metodu Loggin() tak jí nastavuješ znova ? Když už, tak bych tam dal podmínku, jestli náhodou není přihlášený. (oznamování o tom, že jsem se přihlasil pomocí message boxu, ten sw by byl pryč během pár minut)
if(!logged)
{
logged = true;
TODO: ...
}
Celkově ten objektový návrh je celkem zbytečně rozsáhlý. Stačilo by udělat třídu User, dát tam jednotlivé vlastnosti, virtualní metodu na log in a pak udělat třídu admin, která dědí z třídy User, přepsat metodu a máš kód o 90% kratší.
Nevím, jestli ti chybí implementovat nějaký rozdíl mezi adminem a klasickým uživatelem, ale ať se přihlásím tak nebo tak, tak se mi otevře pořád stejný form.
EDIT: S tím co napsal kit ofc souhlasím.


- U proměnné logged potřebuji z venku čtení i zápis a je jedno jestli napíši:
public bool logged;
nebo
public bool logged { get; set }
U proměnných name a password potřebuji z venku pouze čtení proto jsem použil vlastnosti, kde jsem si nastavil, že z venku mohu jen číst.
public string password { get; private set; }
3)
public string name { get; private set; }
2)
protected void NewForm2()
Místo protected stačí private, protože tuto metodu volám pouze ve Form1 (metoda NewForm2 je ve třídě Form1)
- MessageBox tam být vůbec nemusí...
- A co se týče rozsáhlosti programu, tak je to schválně... Tento program jsem začal psát z jediného důvodu - abych si procvičil své (zatím velice omezené) zkušenosti.
- Mě ty komentáře pomáhají. Když používám více proměnných se stejným jménem, stačí když si na něj najedu myší a podle komentáře hned vím, o kterou proměnnou jde.
David Hartinger:3.10.2013 10:19
Je to už trochu lepší, ale pořád nic moc. Administrátor rozšiřuje uživatele, proto by z něj měl dědit, jelikož může to co user a něco navíc. Abstraktní třída se používá v případě, když by uživatel mohl něco, co nemůže administrátor a to se nestává.
Jsem rád, že už účet nedědí z formu, dávalo to asi takový smysl jako by kolibřík dědil z hrocha.
Celkově mám dojem, že jsi se nazpaměť naučil co je abstract nebo virtual, ale vůbec nechápeš proč se objekty vlastně používají. Udělal bys lépe, kdybys nepoužíval tyto pokročilé věci a raději pochopil princip OOP. Doufám, že jsi na tohle nepřišel z mých tutoriálů.


Myslím, že jsem konečně pochopil to, co se mi tu snažíte vysvětlit
již od začátku... Zbytečně jsem si komplikoval život. Před chvílí jsem
došel ze školy a za 5 minut jsem napsal nový kód. Teď se mlátím do hlavy,
jak jsem mohl být tak slepý :[ Mrkněte na to:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// Nový Form2
/// </summary>
private void NewForm2()
{
this.Hide();
Form2 newForm2 = new Form2();
newForm2.Show();
}
private void loggin_Click(object sender, EventArgs e)
{
if (user.Checked)
{
User newUser = new User(accountName.Text, accountPassword.Text);
newUser.Loggin();
if (newUser.logged)
NewForm2();
}
else if (admin.Checked)
{
User newAdmin = new Admin(accountName.Text, accountPassword.Text);
newAdmin.Loggin();
if (newAdmin.logged)
NewForm2();
}
}
private void exit_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
// USER
public class User
{
/// <summary>
/// Jméno účtu
/// </summary>
public string name { get; private set; }
/// <summary>
/// Heslo účtu
/// </summary>
public string password { get; private set; }
/// <summary>
/// Je uživatel přihlášen?
/// </summary>
public bool logged;
public User(string name, string password)
{
this.name = name.ToUpper();
this.password = password.ToUpper();
}
public virtual void Loggin()
{
logged = true;
MessageBox.Show(String.Format("Ahoj uživateli {0}. Tvé heslo je: {1}.", name, password));
}
}
// ADMIN
public class Admin : User
{
public Admin(string name, string password):base(name, password)
{
}
public override void Loggin()
{
if ((name == "ADMIN") && (password == "HESLO"))
{
logged = true;
MessageBox.Show(String.Format("Ahoj admine {0}. Tvé heslo je: {1}.", name, password));
}
else
{
logged = false;
MessageBox.Show("Zadal jste špatné přihlašovací údaje nebo nejste admin!");
}
}
}
Jan Vargovský:3.10.2013 17:09
Nenapsal jsem to předtím, ale nevadí - pokrok. Každopádně psát uživateli jméno a heslo po tom co se přihlásil mi přijde trošku nahlavu. To přihlašování, že se 5x přihlásíš pod stejným jménem je trošku fail programátora, přečti si co jsem psal nahoře a zkus to doimplementovat.
Teď ještě abys dodržoval konvence C# a bude to fajn.
Petr Nymsa:3.10.2013 17:18
Ono už je to lepší , ale zároveň to je stále špatně. Třída Admin by měla být něčím odlišná od běžného uživatele. měla by poskytovat více práv tomu, kdo je Admin. Ověření přihlášení / odhlášení může být uvnitř třídy, ALE je tu jeden nesmysl.
To budeš zakládat vždy novou instanci třídy Admin, při každém pokusu o přihlášení ?
V konstruktoru předáš heslo a jméno, které správně patří uživateli. Metodě Login dej ještě dva parametry -> pass a username. A tyhle parametry předávej jako přihlášení. Zbytek už si snad domyslíš proč ti to takhle píšu a co s tím
Jakub Lásko[Saarix]:3.10.2013 17:54
Zirko má pravdu eště bych si tam poupravil to, že když je newUser
prázdný, tak se vytvoří instance Uživatele/Admina, ale opakovat to vždy je
zbytečné. Ale eště radši bych to dal někam k registraci a zde ověřoval z
listu registrovaných


Opravdu jsem si teď ověřil, že každé vytvoření nové instance
zbytečně plní operační paměť. Tak snad jsem to vyřešil
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void NewForm2()
{
this.Hide();
Form2 newForm2 = new Form2();
newForm2.Show();
}
private void loggin_Click(object sender, EventArgs e)
{
if ((user.Checked) && (accountName.Text.ToUpper() == "USER") && (accountPassword.Text.ToUpper() == "HESLO"))
{
User newUser = new User(accountName.Text, accountPassword.Text);
newUser.Loggin();
if (newUser.logged)
NewForm2();
}
/////////////////////
else if ((admin.Checked) && (accountName.Text.ToUpper() == "ADMIN") && (accountPassword.Text.ToUpper() == "HESLO"))
{
User newAdmin = new Admin(accountName.Text, accountPassword.Text);
newAdmin.Loggin();
if (newAdmin.logged)
NewForm2();
}
else
MessageBox.Show("Zadal jste špatné přihlašovací údaje!");
}
private void exit_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
// USER
public class User
{
public string name { get; private set; }
public string password { get; private set; }
public string account;
public bool logged;
public User(string name, string password)
{
this.name = name.ToUpper();
this.password = password.ToUpper();
}
public virtual void Loggin()
{
account = "USER";
logged = true;
}
}
// ADMIN
public class Admin : User
{
public Admin(string name, string password):base(name, password)
{
}
public override void Loggin()
{
account = "ADMIN";
logged = true;
}
}
Zobrazeno 29 zpráv z 29.