Jawna implementacja metod interfejsu

Jawna implementacja metod interfejsu
RU
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 5 lat
  • Postów:211
0

Cześć

Zastanawiam się czemu przy jawnej implementacji metody z interfejsu nie mogę zrobić takiej metody publicznej:

Kopiuj
        public void ITransakcje.Metoda3(int z1)
        {
            Console.WriteLine("Metoda 3: {0}", z1);
        }

Dostaję komunikat:

The modifier 'public' is not valid for this item
W pisaniu kodu mi to nie przszkadza jakoś specjalnie, bo wystarczy się dostosować ale spać przez to nie mogę.

mad_penguin
mad_penguin
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 3 lata
  • Lokalizacja:Rzeszów
4

Ponieważ możesz zaimplementować dzięki temu kilka metod o takiej samej sygnaturze, ale z innych interfejsów:

Kopiuj
class MojaKlasa : ITransakcje, IInneTransakcje
{
        public void ITransakcje.Metoda3(int z1)
        {
            Console.WriteLine("Metoda 3 z ITransakcje: {0}", z1);
        }

        public void IInneTransakcje.Metoda3(int z1)
        {
            Console.WriteLine("Metoda 3 z IInneTransakcje: {0}", z1);
        }
}

Gdyby te metody miały być publicznie widoczne w klasie to przy wywołaniu bezpośrednio na obiekcieobiekt.Metoda3(42) nie wiadomo by było, która z nich ma zostać wywołana.

Kopiuj
var obiekt = new MojaKlasa();
(obiekt as ITransakcje).Metoda3(42); // odpala się pierwsza metoda
(obiekt as IInneTransakcje).Metoda3(42); // odpala się druga metoda
obiekt.Metoda(42); // która ma się odpalić?
lion137
  • Rejestracja:około 8 lat
  • Ostatnio:około 14 godzin
  • Postów:4935
1

Metody z interfejsu sa zawsze publiczne, wiec nie ma sensu I jest bledem umieszczanie modyfikatorow dostepu.


somekind
W jakim języku?
RU
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 5 lat
  • Postów:211
0
mad_penguin napisał(a):

Ponieważ możesz zaimplementować dzięki temu kilka metod o takiej samej sygnaturze, ale z innych interfejsów:

Kopiuj
class MojaKlasa : ITransakcje, IInneTransakcje
{
        public void ITransakcje.Metoda3(int z1)
        {
            Console.WriteLine("Metoda 3 z ITransakcje: {0}", z1);
        }

        public void IInneTransakcje.Metoda3(int z1)
        {
            Console.WriteLine("Metoda 3 z IInneTransakcje: {0}", z1);
        }
}

Gdyby te metody miały być publicznie widoczne w klasie to przy wywołaniu bezpośrednio na obiekcieobiekt.Metoda3(42) nie wiadomo by było, która z nich ma zostać wywołana.

Kopiuj
var obiekt = new MojaKlasa();
(obiekt as ITransakcje).Metoda3(42); // odpala się pierwsza metoda
(obiekt as IInneTransakcje).Metoda3(42); // odpala się druga metoda
obiekt.Metoda(42); // która ma się odpalić?

Ale to nie po to używa sę np. takiej składni?:

Kopiuj
            Program p1 = new Program();
            ITransakcje transakcje = (ITransakcje)p1;
            transakcje.Metoda3(1);

            Program p2 = new Program();
            ITransakcje2 transakcje2 = (ITransakcje2)p2;
            transakcje2.Metoda3(1);

Lub podany przez Ciebie przypadek.
Samo rzutowanie określa mi jaką metode chcę użyć. Nieużywanie modyfikatora dostępu public to takie dodatkowe "zabezpieczenie"?

RU
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 5 lat
  • Postów:211
0
lion137 napisał(a):

Metody z interfejsu sa zawsze publiczne, wiec nie ma sensu I jest bledem umieszczanie modyfikatorow dostepu.

Przy implementowaniu kompilator wymusza na mnie podanie modyfikatora dostępu, przy niejawnej implementacji.

mad_penguin
mad_penguin
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 3 lata
  • Lokalizacja:Rzeszów
1
rubesom napisał(a):

Nieużywanie modyfikatora dostępu public to takie dodatkowe "zabezpieczenie"?

Jawnie implementowane metody interfejsu nie mogą być publiczne, bo jak wcześniej ustaliliśmy prowadziłoby to do paradoksu, stąd umieszczanie przy nich modyfikatora public jest bez sensu, stąd kompilator nie zezwala na to :)

Riddle
Paradoks w programowaniu, dobre :D
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 6 godzin
  • Lokalizacja:Koszalin
  • Postów:10094
1
mad_penguin napisał(a):
rubesom napisał(a):

Nieużywanie modyfikatora dostępu public to takie dodatkowe "zabezpieczenie"?

Jawnie implementowane metody interfejsu nie mogą być publiczne, bo jak wcześniej ustaliliśmy prowadziłoby to do paradoksu, stąd umieszczanie przy nich modyfikatora public jest bez sensu, stąd kompilator nie zezwala na to :)

Oczywiście to jest prawda jeśli w klasie są dwie takie metody. Jeśli miałaby być jedna, to w sumie czemu nie?

mad_penguin
mad_penguin
słuszne pytanie :)
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:3 dni
  • Lokalizacja:Wrocław
0
rubesom napisał(a):

Samo rzutowanie określa mi jaką metode chcę użyć. Nieużywanie modyfikatora dostępu public to takie dodatkowe "zabezpieczenie"?

Zabezpieczenie? Chyba tylko przed brakiem logicznego kodu. Gdybyś mógł nadać public, to nie musiałbyś rzutować na interfejs, bo metoda byłaby dostępna na poziomie zmiennej typu klasy. I skąd wiadomo by było, którą wtedy metodę wywołać?

TomRiddle napisał(a):

Oczywiście to jest prawda jeśli w klasie są dwie takie metody. Jeśli miałaby być jedna, to w sumie czemu nie?

A po co komplikować kompilator dla jakiegoś przypadku brzegowego, który nie miałby sensu praktycznego?

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 6 godzin
  • Lokalizacja:Koszalin
  • Postów:10094
0
somekind napisał(a):
rubesom napisał(a):

Samo rzutowanie określa mi jaką metode chcę użyć. Nieużywanie modyfikatora dostępu public to takie dodatkowe "zabezpieczenie"?

Zabezpieczenie? Chyba tylko przed brakiem logicznego kodu. Gdybyś mógł nadać public, to nie musiałbyś rzutować na interfejs, bo metoda byłaby dostępna na poziomie zmiennej typu klasy. I skąd wiadomo by było, którą wtedy metodę wywołać?

TomRiddle napisał(a):

Oczywiście to jest prawda jeśli w klasie są dwie takie metody. Jeśli miałaby być jedna, to w sumie czemu nie?

A po co komplikować kompilator dla jakiegoś przypadku brzegowego, który nie miałby sensu praktycznego?

Implementacja jednego interfejsu to przypadek brzegowy? ;|

mad_penguin
mad_penguin
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 3 lata
  • Lokalizacja:Rzeszów
0

Część metod z interfejsu może mieć explicit a część implicit implementation. Możesz po prosty wybrać implicit dla tych metod które mają być publiczne i gotowe.

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:3 dni
  • Lokalizacja:Wrocław
0
TomRiddle napisał(a):

Implementacja jednego interfejsu to przypadek brzegowy? ;|

Co najmniej brzegowy, a może nawet i szalony. W jakim celu implementować explicite jeden interfejs?

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 6 godzin
  • Lokalizacja:Koszalin
  • Postów:10094
0
somekind napisał(a):
TomRiddle napisał(a):

Implementacja jednego interfejsu to przypadek brzegowy? ;|

Co najmniej brzegowy, a może nawet i szalony. W jakim celu implementować explicite jeden interfejs?

Skoro tak, to ktoś by powiedział że pisanie this.field (zamiast field, gdy nie ma zmiennej lokalnej field.) to jest brzegowy/szalony pomysł, i powinno się tego zakazać. Po co pisać this explicite, skoro jest tylko jedno pole field?

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:3 dni
  • Lokalizacja:Wrocław
0

Używanie this jest kwestią konwencji. Zaimplementowanie interfejsu explicite jest kwestią potrzeby, która występuje w konkretnych sytuacjach. W jakiej sytuacji występuje potrzeba zaimplementowania jednego interfejsu explicite? To generalnie byłoby wyłącznie utrudnieniem, więc po co to robić?
Chciałbym zobaczyć konkretny przykład z życia.

Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:Wrocław
  • Postów:13042
1

Prosz - dwie klasy, które implementują jeden interfejs, całkowicie bez konieczności implementacji dodatkowych:

Kopiuj
interface SomeStrategy {
  void doSomething();
}

class StrategyA: SomeStrategy {
  /* ... */
}

class StrategyB: SomeStrategy {
  /* ... */
}

edytowany 3x, ostatnio: cerrato
Patryk27
@cerrato: nie wrzuciłem pełnego kolorowania składni, ponieważ miał to być pseudokod :-P
cerrato
OK, myślałem, że to przeoczenie ;) Ale i tak z kolorami wygląda ładniej.
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:3 dni
  • Lokalizacja:Wrocław
0

@Patryk27: nie podałeś ciała klas, więc nie wiadomo, czy interfejsy zostały zaimplementowane explicite, czy nie.
A jeśli explicite, to ponawiam pytanie - w jakim celu?

Patryk27
Ach, ok - teraz zrozumiałem istotę sporu. Fakt, implementacja explicite byłaby tutaj nadmiarowa.
somekind
No właśnie - nie wyobrażam sobie takiego sensownego przypadku. Ale może faktycznie istnieje, dlatego pytam.
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 6 godzin
  • Lokalizacja:Koszalin
  • Postów:10094
0
somekind napisał(a):

Używanie this jest kwestią konwencji. Zaimplementowanie interfejsu explicite jest kwestią potrzeby, która występuje w konkretnych sytuacjach. W jakiej sytuacji występuje potrzeba zaimplementowania jednego interfejsu explicite? To generalnie byłoby wyłącznie utrudnieniem, więc po co to robić?
Chciałbym zobaczyć konkretny przykład z życia.

Z jednej strony rozumiem czemu możesz uważać że to jest redundant. Z drugiej nie rozumiem, czemu miałoby to komuś przeszkadzać. Można by też powiedzieć że !! w silnie typowanych językach jest redundant, ale nikt nie wyobraża sobie uważana więcej niż jednego wykrzyknika jako błąd.

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:3 dni
  • Lokalizacja:Wrocław
0

@TomRiddle: nie uważam tego za redundantne tylko za bezsensowne, bo jedynie utrudnia. A nawet jeśli to ma sens w jakimś przypadku, to jest tak rzadki, że nie warto w tym celu komplikować kompilatora.

I serio pytam - możesz podać jakiś konkretny sensowny przykład użycia?

edytowany 1x, ostatnio: somekind
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 6 godzin
  • Lokalizacja:Koszalin
  • Postów:10094
0
somekind napisał(a):

@TomRiddle: nie uważam tego za redundantne tylko za bezsensowne, bo jedynie utrudnia. A nawet jeśli to ma sens w jakimś przypadku, to jest tak rzadki, że nie warto w tym celu komplikować kompilatora.

I serio pytam - możesz podać jakiś konkretny sensowny przykład użycia?

No z definicji coś redundantego nie ma przypadku użycia, podobnie jak == true. Modyfikatory public są redundant w interfejsach (w Javie) ale nikt się nie czepia żeby ich zakazać. Albo return w metodach void, Skoro w innych przypadkach się da, to po co robić z tego przypadek szczególny?

edytowany 1x, ostatnio: Riddle
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:3 dni
  • Lokalizacja:Wrocław
0
TomRiddle napisał(a):

No z definicji coś redundantego nie ma przypadku użycia

Ale nie tylko redundantne rzeczy mogą nie mieć przypadku użycia.

Modyfikatory public są redundant w interfejsach (w Javie) ale nikt się nie czepia żeby ich zakazać.

Ale to już problem Javy.

Albo return w metodach void,

Ależ wcale nie jest redundantny, jest przydatny i całkiem często stosowany.

Skoro w innych przypadkach się da, to po co robić z tego przypadek szczególny?

Przypadek ogólny jest taki, że w przypadku implementacji metody interfejsu explicite nie można jej nadać modyfikatora dostępu public. Ty chcesz zrobić przypadek szczególny, że jeśli klasa implementuje tylko jeden taki interfejs (więc nie ma kolizji nazw metod), to żeby się dało nadać modyfikator dostępu.
No więc pytanie do Ciebie - po co robić przypadek szczególny?

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.