Dědičnost – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Dědičnost – .NET – Fórum – Programujte.comDědičnost – .NET – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
paul270
Návštěvník
17. 5. 2008   #1
-
0
-

Zdravím. Na jedněch stránkách jsem našel tento kód:

using System;

using System.Collections.Generic;
using System.Text;

namespace RuzneOsoby
{
public class Osoba
{
private string Jmeno;
private string Prijmeni;

public string jmeno
{
get
{
return this.Jmeno;
}
set
{
this.Jmeno = value;
}
}

public string prijmeni
{
get
{
return this.Prijmeni;
}
set
{
this.Prijmeni = value;
}
}
}

public class Klient : Osoba
{
private int CisloUctu;

public int cislouctu
{
get
{
return this.CisloUctu;
}
set
{
if (value < 0)
{
this.CisloUctu = -1;
}
else { this.CisloUctu = value; }
}
}
}

class Program
{
static void Main(string[] args)
{
Klient klient = new Klient();
klient.jmeno = "Petr";
klient.prijmeni = "Novák";
klient.cislouctu = 120558;

Console.WriteLine("Jméno: {0}", klient.jmeno);
Console.WriteLine("Příjmení: {0}", klient.prijmeni);
Console.WriteLine("Číslo účtu: {0}", klient.cislouctu);

Console.ReadLine();
}
}
}


A chci se zeptat:

1.- Proč se tady vlastně dědičnost využívá, není to zbytečné?
2.- Jaktože lze dědit private (datové složky Jmeno, Prijmeni)?

Nahlásit jako SPAM
IP: 88.103.71.–
Reklama
Reklama
17. 5. 2008   #2
-
0
-
Nahlásit jako SPAM
IP: 81.92.146.–
Dušan Janošík | web: djanosik.cz, @djanosik
paul270
Návštěvník
17. 5. 2008   #3
-
0
-

Vždyť přece mohu napsat tohle - a je to kratší a jediné co se změnilo je to, že jsem vše ze třídy Osoba vymazal a nakopíroval do Klienta. Pak ovšem nechápu, kde je ta výhoda.

using System;

using System.Collections.Generic;
using System.Text;

namespace RuzneOsoby
{
public class Klient
{
private int CisloUctu;
private string Jmeno;
private string Prijmeni;

public string jmeno
{
get
{
return this.Jmeno;
}
set
{
this.Jmeno = value;
}
}
public string prijmeni
{
get
{
return this.Prijmeni;
}
set
{
this.Prijmeni = value;
}
}
public int cislouctu
{
get
{
return this.CisloUctu;
}
set
{
if (value < 0)
{
this.CisloUctu = -1;

}
else { this.CisloUctu = value; }
}
}
}

class Program
{

static void Main(string[] args)
{
Klient klient = new Klient();
klient.jmeno = "Petr";
klient.prijmeni = "Novák";
klient.cislouctu = 120558;

Console.WriteLine("Jméno: {0}", klient.jmeno);
Console.WriteLine("Příjmení: {0}", klient.prijmeni);
Console.WriteLine("Číslo účtu: {0}", klient.cislouctu);

Console.ReadLine();

}
}
}

Nahlásit jako SPAM
IP: 88.103.71.–
17. 5. 2008   #4
-
0
-

To samozřejmě můžeš (ten tvůj kód je pouze příklad a ne nic, kde je dědičnost nezbytná), ale co když pak budeš potřebovat třeba něco takovýho.

public void NazevMetody(Osoba clovek)

{
string text = clovek.Metoda(); // společný kód, obsah proměnné je pro každého jiný

if(clovek is Klient)
{
// kod specificky pro kleinta
}
else if(clovek is Partner)
{
// kod specificky pro obchodního partnera
}
}


Partner i Klient má stejná základní vlastnosti, ale v mnohých ohledech se lišej.

Nahlásit jako SPAM
IP: 81.92.146.–
Dušan Janošík | web: djanosik.cz, @djanosik
Chrasty
~ Redaktor
+4
Posthunter
17. 5. 2008   #5
-
0
-

V tomhle případě, když máš jenom jednoho člověka, tak by to šlo jak jsi to napsal... ale co kdybys chtěl udělat víc typů lidí než jen jeden? Neříkej, že bys ten kód zkopíroval a jenom přepsal "Klient" na "Popelář" třeba... Nejen, že dědičnost zlepšuje čitelnost kódu, ale změna, kterou uděláš na bázové třídy se logicky promítne i na dceřiné třídě. A navíc, i ten popelář se nějak jmenuje, takhle bys musel tu vlastnost "jmeno" psát znova, když ji jednoduše zdědíš, o nic se nestaráš..

Mně problematika dědičnosti nepřijde nějak složitá, nechápu, co na to pořád vidíš :smile1:

EDIT: tak djanosik předvedl další využití:)

Nahlásit jako SPAM
IP: 193.179.196.–
paul270
Návštěvník
17. 5. 2008   #6
-
0
-

Ok. Možná vám to nepřijde těžké, ale já to dneska vidím poprvé (teda podruhé, ještě včera večer). Prostě pořád to neumím využít, ale to se snad podá.

Ještě se zeptám na jedno a už nebudu otravovat.

Řekněme že v hlavní třídě mám tento kód:

public Osoba(string jmeno, string prijmeni)

{
this.jmeno = jmeno;
this.prijmeni = prijmeni;
}

public string Jmeno
{
get { return jmeno; }
set { jmeno = value; }
}

public string Prijmeni
{
get { return prijmeni; }
set { prijmeni = value; }
}


V odvozené třídě pak toto:

private int cisloUctu;


public Klient(string jmeno, string prijmeni, int cisloUctu) : base(jmeno, prijmeni)
{
this.cisloUctu = cisloUctu;
}


base(jmeno, prijmeni) - znamená, že přijaté paramentry string jmeno, string prijmeni "odešlu" do hlavní třídy, kde je nechám zpracovat. A a jelikož v hlavní třídě mám jak konstruktor, který ma za parametry string jmeno, prijmeni...tak tam mám vlastnosti pro zpracování jmena, prijmeni......a mě by zajímalo, jestli se z odvozené třídy odešle string jmeno, prijmeni do toho konstruktoru v hlavní třídě nebo to zpracuje daná vlastnost? Popřípadě šlo by jen - nebo v hlavní třídě je potřeba ten konstruktor:

Hlavní třída:
public string Jmeno

{
get { return jmeno; }
set { jmeno = value; }
}

public string Prijmeni
{
get { return prijmeni; }
set { prijmeni = value; }
}


Odvozená třída:

public Klient(string jmeno, string prijmeni, int cisloUctu) : base(jmeno, prijmeni)

{
this.cisloUctu = cisloUctu;
}

Nahlásit jako SPAM
IP: 88.103.71.–
17. 5. 2008   #7
-
0
-

To paul27 : Nešlo, tím : base(jmeno, prijmeni) voláš konstruktor základní třídy. Stejně tak můžeš volat jinej konstruktor odvozené třídy, jen místo base použiješ this (můžeš tím ušetřit nějakej ten řádek).

Není nad vlastní zkušenost, zkus si ten konstruktor základní třídy smazat a uvidíš sám.

Nahlásit jako SPAM
IP: 81.92.146.–
Dušan Janošík | web: djanosik.cz, @djanosik
paul270
Návštěvník
17. 5. 2008   #8
-
0
-

To djanosik : Jj už jsem taky zjistil. Pak by ale mohlo být jen:

using System;

using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
public class Zamestnanec
{
private string jmeno;

public string Jmeno
{
get
{
return this.jmeno;
}
set
{
if (value == "Pavel")
{
this.jmeno = "BB";
}
else { this.jmeno = value; }
}
}
}
public class Ja:Zamestnanec
{

}
class Program
{
static void Main(string[] args)
{
Ja ja = new Ja();

ja.Jmeno = "Pavel";

Console.Write(ja.Jmeno);
Console.ReadLine();
}
}
}


A jelikož to funguje, tak mi není jasný, proč v předešlým kódu byly zároveň konstruktory a vlastnosti na tu stejnou věc...když se stejně vlastnosti nevyužily. Maximálně by se tam hodil jeden konstruktor bez parametrů...který by ošetřil to, že kdyby byl dotaz někde z kódu na jméno a žádné bych zároveň neodesílal, tak aby se nevypsala jen mezera (nebo nic). Takže asi takhle:

using System;

using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
public class Zamestnanec
{
private string jmeno;

public Zamestnanec()
{
this.jmeno = "Nezadané jméno";
}

public string Jmeno
{
get
{
return this.jmeno;
}
set
{
if (value == "Pavel")
{
this.jmeno = "BB";
}
else { this.jmeno = value; }
}
}
}
public class Ja:Zamestnanec
{

}
class Program
{
static void Main(string[] args)
{
Ja ja = new Ja();

Console.Write(ja.Jmeno);
Console.ReadLine();
}
}
}


Ale možná neznám nějaké jiné souvislosti....ovšem funguje mi to.

Nahlásit jako SPAM
IP: 88.103.71.–
17. 5. 2008   #9
-
0
-

Ale ty vlastnosti se využily, zamysli se nad tím pořádně. K cíli vede mnoho cest, záleží jen na tobě, kterou se vydáš.

Nahlásit jako SPAM
IP: 81.92.146.–
Dušan Janošík | web: djanosik.cz, @djanosik
paul270
Návštěvník
17. 5. 2008   #10
-
0
-

djanosik napsal:
Ale ty vlastnosti se využily, zamysli se nad tím pořádně. K cíli vede mnoho cest, záleží jen na tobě, kterou se vydáš.



Ano využil se blok get, ale set podle mého ne.

Nahlásit jako SPAM
IP: 88.103.71.–
17. 5. 2008   #11
-
0
-

To paul27 : To ne, ale to neznamená, že ho nikdy nevyužiješ. Třeba budeš později chtít změnit jméno.

Nahlásit jako SPAM
IP: 81.92.146.–
Dušan Janošík | web: djanosik.cz, @djanosik
paul270
Návštěvník
17. 5. 2008   #12
-
0
-

djanosik napsal:
To paul27 : To ne, ale to neznamená, že ho nikdy nevyužiješ. Třeba budeš později chtít změnit jméno.


Vždyť jo, na to se hodí ty vlastnosti s blokem get i set, ale proč ještě konstruktor? Číst a nastavovat hodnotu datových složek přeci můžu jen pomocí vlastností -> pak už nepotřebuje konstruktor, když na to jsou vlastnosti (maximálně jak jsem psal, kdybych chtěl číst a zároveň nezadával...takže jeden konstruktor bez parametrů).

Nahlásit jako SPAM
IP: 88.103.71.–
17. 5. 2008   #13
-
0
-

To paul27 : Jak už jsem řekl ... k cíli vede mnoho cest, záleží jen na tobě, kterou se vydáš. Nikdo netvrdí, že základní třída musí mít explicitně definovanej konstruktor. Přestaň se prosím ptát na takové věci, v praxi zvolíš ten efektivnější způsob.

Nahlásit jako SPAM
IP: 81.92.146.–
Dušan Janošík | web: djanosik.cz, @djanosik
paul270
Návštěvník
17. 5. 2008   #14
-
0
-

Dobře. Jak myslíš. :smile13:

Nahlásit jako SPAM
IP: 88.103.71.–
F_Lupus0
Newbie
19. 5. 2008   #15
-
0
-

To paul27 : No uvažuješ správně :) Jen prostě nemáš zkušennosti. Obecně používám konstruktory k naplnění objektu v různých případech:

a) když objekt nemůže existovat bez toho že některé vlastnosti jsou prázdné. Konstruktor vynucuje jejich naplnění. Nevýhodou takového řešení je že v době vytváření objektu musíš hodnoty znát.

b) když si chci usnadnit práci. Např. je efektivnější napsat kód do konstruktoru:

public Osoba (string jmeno, string prijmeni)

{
m_jmeno = jmeno;
m_prijmeni = prijmeni;
}

a pak si vytvořit seznam osob:
List<Osoba> seznamOsob = new List<Osoba>();

seznamOsob.Add(new Osoba("Tomáš","Novák"));
seznamOsob.Add(new Osoba("Pepa","Dvořák"));
seznamOsob.Add(new Osoba("Martina","Malá"));

než to psat bez konstruktoru:
List<Osoba> seznamOsob = new List<Osoba>();

Osoba osoba1 = new Osoba();
osoba1.Jmeno = "Tomáš";
osoba1.Prijmeni = "Novák";
seznamOsob.Add(osoba1);
Osoba osoba2 = new Osoba();
osoba2.Jmeno = "Pepa";
osoba2.Prijmeni = "Dvořák";
seznamOsob.Add(osoba2);
//atd.


Na druhou stranu konstruktory, které plní objekty přestávají mít smysl v případě, že vlastností je hodně a nemusejí být naplněny všechny, je sice možný kostruktor si přetížit (napsat si několik jeho variant) ale třeba u takových 10ti už je na pováženou jestli to má smysl... Někdy má. Záleží na konkrétní situaci.

U Tvých prvních kódů bude celkem jedno jak se rozhodneš, jak ti budou přibývat zkušennosti poznáš kdy je co lepší.

Nahlásit jako SPAM
IP: 85.160.89.–
-SnakyWolf-
19. 5. 2008   #16
-
0
-

To F_Lupus : Přesně, jak píšeš. Většinou používám parametrizovaný konstruktor jen když potřebuju vynutit naplnění proměnných.

Ale třeba ten příklad se seznamem by nemusel bejt až tak tragickej.

List<Osoba> seznamOsob = new List<Osoba>(); 

seznamOsob.Add(new Osoba() {Jmeno = "Tomáš", Prijmeni = "Novák" });
seznamOsob.Add(new Osoba() {Jmeno = "Pepa", Prijmeni = "Dvořák"});
seznamOsob.Add(new Osoba() {Jmeno = "Martina", Prijmeni = "Malá"});


V případě potřeby naplnit větší počet vlastností už to podle mě ztrácí smysl (něco mi řiká, že to nebude dostatečně přehledný).


Nahlásit jako SPAM
IP: 84.21.124.–
Dušan Janošík | web: djanosik.cz, @djanosik
F_Lupus0
Newbie
19. 5. 2008   #17
-
0
-

To djanosik : A pravda... nějak moc v práci zatím nepužíváme framework 3.5 ... tak mi ty "novinky" nedochází... Díky :)

Nahlásit jako SPAM
IP: 88.208.91.–
-SnakyWolf-
paul270
Návštěvník
19. 5. 2008   #18
-
0
-

Díky všem.

Nahlásit jako SPAM
IP: 88.103.71.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 52 hostů

Podobná vlákna

Dedičnosť — založil zonda

Dedicnost ... — založil Koudis

Dědičnost — založil Bobek

Dědičnost — založil cheeester

Dedičnosť — založil Grungy

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý