Przeciążenie operatopów

0

Mam takie dość ciekawe pytanie związku z operatorami przeciążonymi. po prostu do mojej wyobraźni
jakoś to nie wchodzi. np mam klase mojaKlasa i

public class mojaKlasa
{
int mojint;
int mojint2;
int mojint3;

// i przeciążam operator +
public static operator+(mojaKlasa mk,int ab)
{
   //i oczywiście 
   return mk.mojint+ab; //I w tym momencie pytanie

tutaj właśnie się deklaruje co konkretnie ma dodawać operator +, tak jak ja wyobrażam zamiast operator + z powodzeniem można napisać np : dodaj(mojaKlasa mk,int ab), czyli metoda dodaj zwróci mk.mojint + ab; no i do czego wymyślono ten operator+(-,*,/ itd) jeśli nie można np w funkcji Main dopiero decydować które pole ma dodawać. Nie wiem czy wyraźnie mówię spróbuję jaśniej.
A może np w funkcji Main dopiero będę mógł decydować czy ma być mojint dodane do ab, czy mojint2 ma być dodane do ab.czyli nie można zrobić tak żeby te operatory służyły jako operatory matematyczne a nie jako metody bardzo intuicyjne. wiem można robić get{} i sobie dodawać , ale dziwi mnie ten operator +.
Jaka jest jego rola,tylko ta żeby była ładniej czytelna?

Pozdrawiam

0

Chodzi o to, zeby bylo bardziej intuicyjnie. Np.

String a ="napis"; String b = "inny napis"; String c = "cos innego jeszcze"; String d = a+b+c; ``` wyglada bardziej intuicyjnie niz: ``` String d = a.add(b).add(c); ```

Poza tym, nie chodzi o to, zebys raz dodawal jedno pole, a raz dodawal inne. Obiekt jest obiektem - to calosc. Jak definiujesz dodawanie dwoch obiektow zalezy od Ciebie. Tak jak definiujesz np. dodawanie macierzy - jest jeden konkretny sposob. Oczywiscie mozesz zrobic tak, zeby raz dodawalo sie w jeden sposob a raz w inny (np. flagami). Przy przeladowaniu operatorow jednak duza uwage zwraca sie na czytelnosc i jasnosc takiej operacji. Np. przeladowanie operatora dodawania dla klasy Macierz czy Wektor ma sens (bo tak samo jest w matematyce) i taki zapis jest czytelny (bo podobny do zapisu matematycznego). Nie ma sensu przeladowanie operatora dzielenia dla dwoch Macierzy, bo taki zapis w matematyce jest bezsensowny i zaden uzytkownik takiej klasy nie bedzie wiedzial co masz na mysli - nawet jak jest dokumentacja.

0

Czyli ja dobrze zrozumiałem , chodzi tylko żeby była czytelna.A jeśli zechce dodać raz jeden a raz drugi, i potem trzeci to jak? trzi razy operator+ ? no i wyskoczy błąd jednoznaczności .

0

Nie, operator jest jeden. Czemu chcesz dodawac raz jeden, raz drugi a raz trzeci? Jaki to ma sens? W wiekszosci przypadkow takie cos oznacza blad projektowy. Chyba, ze jest jakos sensownie wytlumaczalne.

To na takiej samej zasadzie jak te macierze. Jakbys ich nie dodawal to zasada jest ta sama. Nie ma sensu tworzenia trzech roznych dodawan dla mecierzy (nawet jesli istnialyby 3 rodzaje), bo cala czytelnosc idzie sie ... - musisz sie za kazdym razem zastanawiac na ktora wersje operatora tym razem patrzysz - odpada.

0
johny_bravo napisał(a)

Nie, operator jest jeden. Czemu chcesz dodawac raz jeden, raz drugi a raz trzeci?

No np: mi jest potrzebne dodać tak jak w pierwszym poście napisałem, dodać pole z obiektu klasy do jakiejś liczby integer( a nie do drugiego pola). tak jak tu

mojaKlasa obj= new MojaKlasa();
ConsoleWriteLine(obj+55);// i tu będe miał wartośc mojint+55 nie?

// A jeśli zechce napisać jeszcze potem coś takiego : mojint2 + 55 to jak? znowu przeciążyć operator+ tak żeby zwracała wartość mojint2+ ab. I tutaj będzie jednoznaczność.
A może coś ja źle rozumiem?

0

Zdaje sie nie rozumiesz pojecia obiekt. Kiedy tworzysz klase robisz to z kilku powodow. Jednym z nich jest tzw. enkapsulacja - czyli zamkniecie kilku elementow w jedna klase, jedna calosc. Z punktu widzenia uzytkownika tej klasy nie istnieja jej skladowe, istnieje tylko obiekt jako calosc. Np. klasa Plakat skladac sie bedzie zapewne z napisu, listy obrazkow z pozycjami, logo firm, ktore plakat sponsorowaly, itp. Ale z punktu widzenia uzytkownika jest Plakat i nieistotne jest z czego sie sklada, a jak sie z niego korzysta. To jest jedna z zalet programowania obiektowego - nie musisz zaglebiac sie w szczegoly jesli nie chcesz. Tak samo z klasa Wektor (zeby bylo jasniej tlumaczyc operator) - sklada sie zapewne z jakiejs tablicy/listy/ciagu liczb definiujacych wektor. Ale dla Ciebie to nieistotne. Ciebie interesuje, ze masz Wektor i mozesz dwa Wektory do siebie dodac. Jak sie dokladnie dodaja? To juz problem autora tej klasy - on dba o to, zeby Wektory dodaly sie dobrze.

Dlatego odwolywanie sie wprost do skladowych, tak jak Ty bys chcial jest bledem projektowym. Nie istnieje taka potrzeba. Jesli chcesz zwiekszyc/zmniejszyc/zmienic jakas skladowa to piszesz osobna metode np. ChangeFirstMember - nazwa od razu mowi co to znaczy. Jezeli definiujesz operatory (jakiekolwiek) to ZAWSZE zakladasz, ze dotycza calego obiektu (np. calej macierzy, czy calego wektora, czy calego plakatu), nie jakiejs jego czesci. Po to zamykasz pewne elementy w calosc klasy, zeby nie zawracac sobie glowy szczegolami podczas uzywania tejze.

Czyli podsumowujac na przykladzie klasy Wektor

  • jesli chcesz zmienic jedna skladowa wektora piszesz metode UstawSkladowa albo tworzysz skladowe jako property i piszesz odpowiednie get
  • jesli dzialasz na CALYM obiekcie, bez wnikania w szczegoly implementacji, mozesz dla wygody przeladowac operator, ale tylko jesli ma to sensowne uzasadnienie(np. dodawanie wektorow, ale nie dodawanie plakatow do siebie)
0

Dzięki Johny_Bravo. dopiero się uczę i może i przez brak praktyki inaczej wyobrażałem.
po prostu zakładałem że:" jeśli będzie trzeba ". Ale chyba nie będzie coś takiego w praktyce trzeba
(tak jak mówisz) , no jeśli już(na upartego), to zużyje akcesory albo własne metody. A operatory to
są dla czytelności tak zrozumiałem.
Dziękuję za tłumaczenia jeszcze raz.Pozdrawiam.

0

??

1 użytkowników online, w tym zalogowanych: 0, gości: 1