Thread: [Java] public voor class zetten?
-
12-02-2010, 23:05 #1
[Java] public voor class zetten?
Beste 9livers
Ik ben zelf al redelijk lang met java bezig en sinds vandaag de eerste les gehad op school (daarvoor was het altijd C++).
Nu zet ik voor elke class public, en ook voor elke lidfunctie. Nu doen ze dit op school niet en wordt het iets als volgt
Nu, ik schreef altijd public voor de class en ook voor alle lidfuncties. Dus dan wordt hetCode:class Student { private String name; Student(String name) { this.name = name; } Student() { this("unknown"); } String getName() { return this.name; } }
Het verschil is dat wanneer je er public voor zet deze ook buiten zijn package bereikbaar is. Maar wat doen jullie altijd? Of kijken jullie of hij effectief buiten zijn package bereikbaar moet zijn, is dit niet het geval zet je het erbij?Code:public class Student { private String name; public Student(String name) { this.name = name; } public Student() { this("unknown"); } public String getName() { return this.name; } }
Graag wat meer informatie.
Alvast bedanktno votes
-
-
12-02-2010, 23:48 #2Member
- Registered
- 24/03/03
- Location
- Gent/World
- Posts
- 2,321
- iTrader
- 22 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 0/5
Imo zou ik er altijd public/protected/private bij zetten. Per default maak ik m'n methodes public.
no votes
-
12-02-2010, 23:55 #3
Ja dat zou ik ook denken, dan is ook meteen duidelijk te zien dat die methodes public zijn. Maar eens afwachten wat andere programmeer guru's hier op te zeggen hebben.
no votes
-
13-02-2010, 01:17 #4Member
- Registered
- 23/11/03
- Location
- Landeurp
- Posts
- 1,791
- iTrader
- 0
- Mentioned
- 0 Post(s)
- Reputation
- 10/17
Google eens op encapsulation. De idee is dat je implementatiedetails van een klasse (klassevariabelen en methods) zoveel mogelijk verborgen houdt (private, package, protected) voor de gebruiker en de interface beperkt tot een aantal public methods.
Een beperkte interface heeft een aantal voordelen: 1) de klasse is eenvoudiger in gebruik, 2) hoe minder de gebruiker van de binnenkant ziet, hoe minder kans dat hij de klasse verkeerd gebruikt en 3) zolang je de publieke interface hetzelfde houdt, kan je de interne implementatie veranderen zonder dat gebruikers er iets van merken (programming to an interface).
Een leuk neveneffect van encapsulation is dat synchronisatie bij multithreading ook eenvoudiger wordt.
Op package-niveau gebeurt hetzelfde: als je klassen van buiten de package moet kunnen aanspreken, maak je ze public, als dat niet het geval is (de klassen zijn louter helpers van klassen die wel public zijn), geef je ze package scope.
Conclusie: members private en klassen package scope, tenzij je een goede reden hebt om dat niet te doen.no votes
-
13-02-2010, 19:03 #5
als je geen public, private of protected zet heb je "package visability"
Dit is de default en is iets tussen private en protected in.
Het houd in dat je de klasse enkel in de klasse zelf kan zien (in geval van een innerclass) of in andere klasse van dezelfde package. Bij subklassen kan je de klasse enkel zien bij subklassen in dezelfde package.PSN: Shaddix-beno votes
-
22-02-2010, 20:35 #6Approved 9liver
- Registered
- 08/03/06
- Location
- .
- Posts
- 9,439
- iTrader
- 29 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 1/217
Fractal Design R6 -- Intel Core i7 8700k @ 5.0Ghz -- Asus Hero X -- Corsair Vengeance 16GB -- MSI Gaming X 1080 TI @ 2040Mhz/1000mV-- Corsair RM850x (2018) -- Custom water loop
Samsung 970 EVO 500GB -- Samsung 850 EVO 500GB -- Seagate Barracuda ST500DM002 -- Acer XB271HU (165hz 1440p IPS)
Corsair K70 -- Zowie FK2 -- Steelseries QcK heavy -- Sennheiser HD598 + Modmic 4.0no votes
-
24-02-2010, 00:36 #7Approved 9-lifer
- Registered
- 27/08/04
- Location
- Leuven
- Posts
- 930
- iTrader
- 0
- Mentioned
- 0 Post(s)
- Reputation
- 11/38
no votes
-
24-02-2010, 12:06 #8
Als het deel is van de class interface is zet ik het public, en anders protected. Ik heb nooit echt gesnapt waarom iets op private moet gezet worden. Als iemand persee een method wil overriden of een interne member wil accessen (in een drived class) dan mag die dat van mij
.
In welk geval beslis je trouwens "Oei, deze member/method ga ik op private zetten ipv op protected, want die mag zeker niet overridden worden"?no votes
-
24-02-2010, 17:37 #9
Prima, maar dan heb je geen encapsulatie meer. Al je protected members zijn vrij toegankelijk voor elke class die van jouw class erft. Ze zijn voor die ervende class dus net zo goed public. Als jij later beslist om de implementatie te wijzigen in de base class die je protected ipv private hebt gemaakt dan sta je daar.
Da's dus de omgekeerde (verkeerde) redenering. Access kun je later altijd versoepelen mocht dat nodig blijken, omgekeerd gaat niet (tenzij je al de client code wilt aanpassen natuurlijk).no votes
-
24-02-2010, 23:08 #10
Vroeger was ik inderdaad ook van deze mening, en traditionele OOP kan niet zonder encapsulation. Bijna alle cursussen en boeken leggen een enorme nadruk op encapsulation en op zoveel mogelijk proberen af te schermen.
Maar sinds ik python heb leren kennen ben ik van mening veranderd. Hoe meer je afschermt, hoe minder bruikbaar je class wordt. Hoe een class normaal gebruikt wordt is redelijk goed in te schatten, en dus ook hoe je best de (public) interface definieert. Maar als het op derived classes aankomt is het al heel wat moeilijker.
Bij derived classes willen je gebruikers een deel van je functionaliteit veranderen of uitbreiden. Het aantal mogelijkheden is hier erorm, en heel moeilijk in te schatten wat er allemaal mogelijk is. Zelf heb ik het al meermaals voorgehad dat je functionaliteit van andere classes wil gebruiken, maar dat ze net te veel hebben afgeschermd om bruikbaar te zijn.
Op python newsgroups zijn hier ook enorme discussies over geweest met Java/C++ fanboys, dus waarschijnlijk is het meer een kwestie van persoonlijke voorkeur. Ik weet wat encapsulation inhoud, heb het vroeger altijd toegepast, maar ik verkies om OO te programmeren met een soepelere aanpak.
Dit doet mij denken aan iets wat ik een tijdje gelezen heb van een python programmeur, die de meer traditionele OOP programmeertalen als BSD-languages omschreef (Bondage Submission and Domination)
. Mijn gebruikers mogen mijn classes gebruiken zoals ze zelf willen
, je kan trouwens toch niet eeuwig backwards compatible blijven, zelfs met je public interfaces.
Last edited by kwitters; 25-02-2010 at 09:05.
no votes
-
25-02-2010, 13:07 #11
Neen dat hoeft niet moeilijk te zijn. Tenzij het een class betreft die specifiek is ontworpen om te worden afgeleid kan er zelfs iets voor gezegd worden om de class final te maken. Ik wil er op wijzen dat wat het uitbreiden (en niet wijzigen - zie Open/Closed principle) van een class betreft, object composition wordt verkozen boven implementation inheritance, (onder meer) omdat implementation inheritance je encapsulatie breekt en object composition gebruikt maakt van de bestaande public interface.
Neen. Je verkiest om op een niet object-georiënteerde manier te programmeren in een object-georiënteerde programmeertaal.
Een wijziging die in de implementatie van een base class wordt aangebracht (bugfixing, veranderde requirements, enz...) kan potentiële gevolgen hebben voor de afgeleide classes, de classes die die afgeleide classes gebruiken, de classes die op hun beurt weer die classes gebruiken enzovoort enzoverder. Ik ben eens benieuwd of jouw gebruikers dat backwards compatibiliteitsexcuus lang gaan slikken als ze potentieel grote stukken code moeten aanpassen telkens er een (kleine) wijziging aan de implementatie van de base class moet aangebracht worden.no votes
-
25-02-2010, 14:59 #12
Wel, ik verkies composition voor "has a"-relationships en inheritance voor "is a"-relationships. Duidelijk en simpel.
Wil je zeggen dat bv python geen OO ondersteunt omdat die geen stricte encapsulatie ondersteunt? Ik, net zoals enorm veel andere mensen, programmeer OO in python, en ja, zonder dat die stricte encapsulatie heeft. Mensen met jou mening beschouwen we om die reden dan ook als "traditionele OO'ers", die meer de nadruk leggen op restricties dan op functionaliteit.
Wel, als je je classes final maakt dan heb je dit probleem natuurlijk niet, maar dan heb je natuurlijk ook geen inheritence gebruikers.
De beste programmeurs zijn diegenen die de juiste afwegingen kunnen maken, en hier gaat het om functionaliteit vs backwards compatibility. Ik verkies het om meer functionaliteit bloot te stellen ten koste van potentieel toekomstige aanpassingen. Jij verkiest het om zo weinig mogelijk functionaliteit bloot te stellen zodat toekomstige aanpassingen een minimale impact hebben.
Ieder zijn ding natuurlijk, maar de reden waarom ik programmeer is voor functionaliteit aan te bieden, niet om ze weg te steken. De argumenten die je aanhaalt zijn trouwens typische textbook redeneringen van het Java/C++ tijdperk. Been there done that. Wake up and smell the coffee.no votes
-
25-02-2010, 15:43 #13
Hoe zou jij pakweg Collections.unmodifiableList() implementeren als ik vragen mag (en dan doel ik vooral ook op de class die wordt gereturned)?
Encapsulatie is een van de pijlers waarop OO is gebaseerd. Als je encapsulatie in de wind slaat, omdat je dan zogezegd geen functionaliteit kan leveren, dan ben je naar mijn mening inderdaad niet bijster object-georiënteerd bezig. Natuurlijk, de ene is wat stricter in die regels als de andere.
Coupling tussen classes en objecten tot een minimum beperken zodat aanpassingen in één class zo weinig mogelijk impact heeft op de rest van het systeem is allesbehalve restrictief, wat jullie in jullie Python clubje daar ook maar van mogen vinden.
In ieder geval geen implementation inheritance, neen.
Hier doe je weer alsof een systeem "volgens de regels van de OO kunst ontworpen" niet voldoende functionaliteit kan leveren. Dit is onzin. Het grootste deel van de Java API maakt gebruik van die regels die jij passé noemt. Moet ik nu aannemen dat die API niet voldoende functionaliteit levert? Flauwekul.
Nogmaals. Er wordt geen functionaliteit weggestoken, enkel de implementatie van die functionaliteit.
En ik heb nog altijd geen deftige argumenten gelezen waarom die typische textbook redeneringen niet opgaan. Enkel persoonlijke meningen die nergens op slaan.no votes
-
25-02-2010, 15:58 #14Member
- Registered
- 06/04/06
- Location
- BXL
- Posts
- 4,415
- iTrader
- 1 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 2/40
Voor de goede orde: Python kent wel encapsulatie, maar die wordt by convention afgedwongen in plaats van door de compiler. Tenzij je verdomd goed weet waar je mee bezig bent wordt het omzeilen van scope gezien als een very bad practice.
Voor de grote statische talen is dat niet anders. Zowel in Java als C# is het een eitje om via reflectie toegang te krijgen tot de private scope van een klasse.I caught a glimpse and now it haunts me.no votes
-
25-02-2010, 20:43 #15
Waarom zou ik in godsnaam zoiets implementeren?
. In de 15 jaar dat ik programmeer heb ik zoiets nog nooit nodig gehad.
Ik zal eens een simpel voorbeeldje geven dat mijn punt (hopelijk) duidelijk maakt. Jij bent de developer van een SDK. Onderdeel daarvan is een class die een simpel filmpje afspeelt (Ik hou de implementatie heel simpel). Hier in pseudocode met zeer stricte encapsulation:
Ik ben gebruiker van die class, en kan op geen manier uw class breken (omdat je deftige encapsulation hebt). Probleem is dat ik iets nodig heb zoals uw class, maar niet helemaal. Uw animatie loopt, maar bij mij moet die blijven stilstaan op de laatste frame. Ik zou mijn class trouwens ook willen gebruiken overal waar Animation kan gebruikt worden. Met polymorphism gaat dit, maar damn, dat gaat niet want jou class is final! "Ollie, wilt ge die class eens niet final maken zodat ik die als base class kan gebruiken, en mag ik een protected getter die checked dat de huidige frame de laatste is". Als ge zo vriendelijk zijt doet ge dat, en zoniet drop ik gewoon uw SDK voor een meer gebruiksvriendelijkere (of mijn eigen).Code:public final class Animation { private List<Picture> myAnimationFrames private int myCurrentFrameNumber public Animation( List<Image> animationFrames ) { myAnimationFrames = animationFrames myCurrentFrameNumber = 0 } public void draw( Screen targetScreen ) { drawCurrentFrameOnScreen( targetScreen ) increaseFrameNumber() } private void drawCurrentFrameOnScreen( Screen screen ) { Picture currentPicture = myAnimationFrames[ myCurrentFrameNumber ] // Complex stuff here to get that picture onto the screen ... } private void increaseFrameNumber() { myCurrentFrameNumber = (myCurrentFrameNumber + 1) % myAnimationFrames.length } }
Ik kan nu mijn class deriven, en draw overriden met die protected check, zodat ik bij de laatste frame increaseFrameNumber niet meer oproep.
Maar damn, enkele dagen later heb ik een animatie nodig die niet loopt maar een ping-pong animatie afspeelt. Weer kan ik niet verder want ik kan myCurrentFrameNumber niet decreasen. Weer vraag ik aan u om wat open te stellen en voor extra functionaliteit.
Kijk, zolang gij private functionaliteit of members hebt, kan ik dingen bedenken dat net die geencapsuleerde zaken nodig heeft. Probeer maar uit als je wilt.
Om nu bij het punt van mijn 1ste post te komen: als je nu alles protected ipv private had gezet, dan had dat zowel mij als u veel tijd en frustratie bespaard. En ja, dat gaat in tegen alle regels van OO encapsulation, so fucking what? Je moet ook een beetje pragmatisch denken he.
En ja, de members ook protected
. Als ik myCurrentFrameNumber groter laat worden dan de frames length, dan is dat mijn probleem en niet het uwe.
Dus ja, dingen volledig afschermen beperkt de functionaliteit. En daarom dat ik public voor de interface gebruik, en protected voor de rest.no votes

