računarski praktikum 3 vježbe 04
DESCRIPTION
Računarski praktikum 3 Vježbe 04. Vinko Petričević. Sučelja. Sučelja (interface). C# ne podržava višestruko nasljeđivanje klasa, međutim svaka klasa/struktura može zadovoljavati više sučelja sučelje je ugovor koji nam garantira da se klasa ‘zna’ ponašati na određeni način - PowerPoint PPT PresentationTRANSCRIPT
Računarski praktikum 3Vježbe 04
Vinko Petričević
Sučelja
Sučelja (interface)
C# ne podržava višestruko nasljeđivanje klasa, međutim svaka klasa/struktura može zadovoljavati više sučelja
sučelje je ugovor koji nam garantira da se klasa ‘zna’ ponašati na određeni način
sučelje možemo shvatiti kao čisto-apstraktnu klasu, koja može imati metode, svojstva, indeksere i događaje, ali ne može imati varijable
Interface
struktura je vrijednosti tip
modifikator pristupa isti kao kod klasa uobičajeno je nazive interfacea započimati velikim I
(IStorable, IDisposable…) tijelo opisuje metode koje implementirajuća klasa treba
implementirati nema modifikatora pristupa – sve je public nema implementacije metoda
[pristup] interface naziv [: popis osnovnih sučelja]{
// tijelo sučelja}
Primjer sučelja
konstruktori se ne nasljeđuju. ako nemamo defaultni konstruktor, moramo ga pozvati eksplicitno
interface IPohranjivo { object Citaj(); void Pisi(object o); int Status { get; set; }}// deklaracija klase koja implementira sučelje IPohranjivoclass Osoba : IPohranjivo { // implementacija sučelja public object Citaj() {
Console.WriteLine("Implementacija metode Citaj() iz IPohranjivo");return "Nesto je procitano";
} public void Pisi(object o) {
Console.WriteLine("Implementacija metode Pisi() iz IPohranjivo"); } private int status = 0; // sprema vrijednost za svojstvo public int Status {
get { return status; }set { status = value; }
}// Ostatak implementacije klase public string Ime, Prezime; public Osoba(string ime, string prezime) {
this.Ime = ime;this.Prezime = prezime;
}}
Pretvaranje u sučelje
Instancu sučelja ne možemo izravno stvoriti, ali možemo stvoriti instancu klase koja implementira sučelje, te ju pretvoriti u sučelje
dogodila se implicitna pretvorba:
metode sučelja pozivamo kao da se radi o klasi
Osoba o = new Osoba("Ivan", "Ivanković"); IPohranjivo ipOsoba = o;
IPohranjivo ipOsoba = (IPohranjivo) o;
ipOsoba.Status = 0; ipOsoba.Citaj();
Pretvaranje u sučelje
Instancu sučelja ne možemo izravno stvoriti, ali možemo stvoriti instancu klase koja implementira sučelje, te ju pretvoriti u sučelje
implicitna pretvorba:
eksplicitna pretvorba
void f(IPohranjivo ip) { ... }
Osoba o = new Osoba("Ivan", "Ivanković"); IPohranjivo ipOsoba = o;
f(o);
object obj = o; f((IPohranjivo)obj);
Primjer sučelja
nije toliko bitno kako klasa implementira metode
bitno je da da ih implementira sve
class Osoba : IPohranjivo { public object Citaj() { ... } public void Pisi(object o) { ... } public int Status {
get { ... }set { ... }
}}
interface IPohranjivo { object Citaj(); void Pisi(object o); int Status { get; set; }}
Implementiranje više sučelja
sada klasa Osoba mora implementirati oba sučelja
novo sučelje sada ima sve metode oba sučelja
class Osoba : IPohranjivo, IKompresibilno
interface IBiljezivoKompresibilno : IKompresibilno{
void ZabiljeziPohranjeneBajtove();}
interface IPohranjivoKompresibilno : IPohranjivo, IBiljezivoKompresibilno{
void ZabiljeziOriginalnuVelicinu();}
Operator as i is
kao dynamic_cast
ako samo želimo provjeriti je li moguće tip pretvoriti, možemo koristiti operator is
ISifrabilno isOsoba = o; // implicitna pretvorbaISifrabilno isOsoba = (ISifrabilno)o; // eksplicitna pretvorba pomoću cast operatoraISifrabilno isOsoba = o as ISifrabilno; // pretvorba pomoću operatora as
ISifrabilno isOsoba = o as ISifrabilno;if (isOsoba != null) ...
if (o is ISifrabilno) …
apstraktne klase i interface
vrlo slično, ipak kod apstraktne klase nema višestrukog nasljeđivanja
interface IPohranjivo{
void Citaj();void Pisi(object o);int Status { get; set; }
}
abstract class Pohranjivo{
abstract public void Citaj();abstract public void Pisi(object o);abstract public int Status { get; set; }
}
premošćivanje implementacije implementirajuća klasa može neke metode
sučelja označiti kao virtualne. Tada izvedene klase mogu premostiti te implementacije
interface IPohranjivo { void Citaj(); }
class Osoba : IPohranjivo { public virtual void Citaj() {
Console.WriteLine("Implementacija metode Citaj() u klasi Osoba"); }}
class Student : Osoba { public override void Citaj() {
Console.WriteLine("Premošćena metoda Citaj() u klasi Student"); }}
Zadatak 1
Napišite sučelje IPovrsina koje racuna povrsinu
Napišite sučelje IOpseg koje racuna opseg Napišite klasu lik. Iz te klase izvedite klasu
trokut, cetverokut, kvadrat, te krug napisite program koji ispisuje povrsinu i
opseg danog lika (ako je to moguce)
Eksplicitna implementacija ako više sučelja ima istu metodu
interface IPohranjivo { void Citaj(); void Pisi();}interface IPrevodljivo { void Citaj(); void Prevedi();}class Osoba : IPohranjivo, IPrevodljivo { public virtual void Citaj() { Console.WriteLine("Implementacija IPohranjivo.Citaj()"); } public void Pisi() { …. } void IPrevodljivo.Citaj() { Console.WriteLine("Implementacija IPrevodljivo.Citaj()"); } public void Prevedi() { …. }}
Eksplicitna implementacija kod eksplicitne implementacija nema modifikatora
pristupa, ona je javna. Ne možemo staviti ni obstract, virtual, override ili new.
pozivamo ih preko reference sučelja
class Program { static void Main(string[] args) {
Osoba o = new Osoba();
IPohranjivo ipohranjivoOsoba = o;ipohranjivoOsoba.Citaj();
IPrevodljivo iprevodljivoOsoba = o;iprevodljivoOsoba.Citaj();
o.Citaj(); // poziva se metoda sučelja IPohranjivo
}}
Implementacija u strukturi bolje pozivati direktno, jer se prilikom pretvorbe u
interface vrši pakiranje, pa se mijenja zapakirani objekt, a ne sama strukturainterface IPohranjivo{ void Citaj(); int Status { get; set; }}
public struct TestStruct : IPohranjivo { public void Citaj() { Console.WriteLine("Implementacija IPohranjivo.Citaj()"); } private int status; public int Status {
get { return status; }set { status = value; }
}}
Implementacija u strukturistatic void Main(string[] args) {
// stvaramo instancu struktureTestStruct ts = new TestStruct();ts.Status = 0; // inicijaliziramo svojstvoConsole.WriteLine("Instanca inicijalizirana.");Console.WriteLine("ts.Status: {0}", ts.Status);
// mijenjamo vrijednost instancits.Status = 1;Console.WriteLine("Instanca promijenjena.");Console.WriteLine("ts.Status: {0}", ts.Status);
// pretvaramo u IPohranjivo (implicitno pakiranje u referentni tip)IPohranjivo ipTemp = (IPohranjivo)ts;
// postavljamo novu vrijednost kroz referencu sučeljaipTemp.Status = 2;Console.WriteLine("Sučelje promijenjeno.");Console.WriteLine("ts.Status: {0}, ipTemp.Status: {1}", ts.Status, ipTemp.Status);
// ponovno mijenjamo vrijednost instancits.Status = 3;Console.WriteLine("Instanca promijenjena.");Console.WriteLine("ts.Status: {0}, ipTemp.Status: {1}“, ts.Status, ipTemp.Status);
}