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

Neregistrovaný

Zobrazeno 29 zpráv z 29.
//= 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.
Proč zase dědí třída Account z formu?
Aby sdílela proměnnou:
protected bool logged = false;
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!");
}
}
}
Projdi si tutoriály tady na Devbooku, tohle by bylo na dlouho...
Odpoledne v prográmku ti sepišu co je natom blbě
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
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ží
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:
Nechápu, co se vám na mém kódu nelíbí. Nebo teď je to OK?
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.
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.
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)
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!");
}
}
}
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.
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
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.