Szia! A mai leckében megismerkedünk a hozzáférés-módosítók fogalmával , és példákat tekintünk meg a velük való munkavégzésre. Természetesen az „ismerkedj meg” szó nem egészen helyes: a legtöbbjüket már ismered az előző leckékből. Minden esetre frissítsük fel emlékezetünket a legfontosabb pontról. A módosító hozzáférés leggyakrabban olyan kulcsszavak, amelyek a kód különböző részeihez való hozzáférést szabályozzák. Miért "leggyakrabban"? Mert az egyik alapból kulcsszó használata nélkül van beállítva :) A Java-nak négy hozzáférésmódosítója van. Sorrendben soroljuk fel őket a legszigorúbbtól a legenyhébbig:
A privát a leginkább korlátozó hozzáférésmódosító. Egyetlen osztályon belül korlátozza az adatok és metódusok láthatóságát. Ezt a módosítót a getterekről és szetterekről szóló leckéből ismeri. Emlékszel erre a példára?
hozzáférés-módosítóval jelölt mezők és módszerek láthatók lesznek:
Most, hogy áttanulmányoztad az interfészekről szóló leckét, egyértelmű számodra a célja :) Végül is a nyilvános módosítót azért hozták létre, hogy adjon valamit a felhasználóknak. Például a program felülete. Tegyük fel, hogy írt egy fordítóprogramot, amely képes orosz szöveget angolra fordítani. Létrehozott egy translate(String textInRussian) metódust, amely megvalósítja az összes szükséges logikát. Ezt a metódust a public szóval jelölte meg , és most a felület része:
- magán;
- alapértelmezett (a csomag látható);
- védett;
- nyilvános.
A privát módosító

public class Cat {
public String name;
public int age;
public int weight;
public Cat(String name, int age, int weight) {
this.name = name;
this.age = age;
this.weight = weight;
}
public Cat() {
}
public void sayMeow() {
System.out.println("Meow!");
}
}
public class Main {
public static void main(String[] args) {
Cat cat = new Cat();
cat.name = "";
cat.age = -1000;
cat.weight = 0;
}
}
Egy előző leckében gondoltuk át. Itt súlyos hibát követtünk el: adatainkat nyilvánossá tesszük, ami lehetővé tette a programozótársaknak, hogy közvetlenül hozzáférjenek a mezőkhöz, és módosítsák azok értékeit. Sőt... ezeket az értékeket minden ellenőrzés nélkül hozzárendelték. Ez azt jelenti, hogy a programunk képes létrehozni egy "" nevű macskát, amelynek életkora -1000 év és súlya 0. A probléma megoldásához gettereket és settereket használtunk, valamint a privát módosítóval korlátoztuk az adatokhoz való hozzáférést.
public class Cat {
private String name;
private int age;
private int weight;
public Cat(String name, int age, int weight) {
this.name = name;
this.age = age;
this.weight = weight;
}
public Cat() {
}
public void sayMeow() {
System.out.println("Meow!");
}
public String getName() {
return name;
}
public void setName(String name) {
// input parameter check
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
// input parameter check
this.age = age;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
// input parameter check
this.weight = weight;
}
}
Alapvetően a mezőkhöz való hozzáférés korlátozása, valamint a getterek és setterek megvalósítása a leggyakoribb példák arra, hogyanvalós munkában használnák. Más szavakkal, ennek a módosítónak a fő célja a programba való beágyazás elérése. Ez egyébként nem csak a mezőkre vonatkozik. Képzeld el, hogy a programodban van egy módszer, amely NAGYON összetett funkciókat valósít meg. Mit ajánlhatunk példaként? Tegyük fel, hogy a readDataFromCollider() metódus bemenetként elfogad egy adatcímet, beolvassa az adatokat a Large Hadron Colliderből bájt formátumban, ezeket az adatokat szöveggé alakítja, fájlba írja és kinyomtatja. Még a metódus leírása is ijesztőnek tűnik, a kódról nem is beszélve :) A kód olvashatóbbá tétele érdekében az a legjobb, ha nem írjuk egy helyre a metódus összes összetett logikáját. Ehelyett a funkcionalitást külön módszerekre kell felosztanunk. Például a readByteData()metódus felel az adatok kiolvasásáért, a convertBytesToSymbols() metódus az ütközőből kiolvasott adatokat szöveggé alakítja, a saveToFile() metódus a kapott szöveget fájlba menti, a printColliderData() metódus pedig kiírja az adatfájlunkat. Végül a readDataFromCollider() metódusunk sokkal egyszerűbb lesz:
public class ColliderUtil {
public void readDataFromCollider(Path pathToData) {
byte[] colliderData = readByteData(pathToData);
String[] textData = convertBytesToSymbols(colliderData);
File fileWithData = saveToFile(textData);
printColliderData(fileWithData);
}
public byte[] readByteData(Path pathToData) {
// Reads data in bytes
}
public String[] convertBytesToSymbols(byte[] colliderDataInBytes) {
// Converts bytes to characters
}
public File saveToFile(String[] colliderData) {
// Saves read data to a file
}
public void printColliderData(File fileWithColliderData) {
// Prints data from the file
}
}
Azonban, mint az interfészekről szóló leckéből emlékszik, a felhasználó csak a külső felülethez fér hozzá. És a mi 4 módszerünk nem része ennek. Segítő módszerek: azért hoztuk létre őket, hogy javítsuk a kód olvashatóságát, és ne zsúfoljunk bele négy különböző feladatot egy metódusba. Nem kell hozzáférést adnia a felhasználónak ezekhez a módszerekhez. Ha a felhasználók hozzáférhetnek a convertBytesToSymbols() metódushoz, amikor az ütközővel dolgoznak, akkor valószínűleg egyszerűen összezavarodnak a módszertől, és kíváncsiak, hogy mire való. Milyen bájtok konvertálódnak? Honnan jöttek? Miért alakítsuk át őket szöveggé? Az ebben a metódusban végrehajtott logika nem része a felhasználó számára elérhető felületnek. Csak a readDataFromCollider()metódus az interfész része. Tehát mit kezdjünk ezzel a négy „belső” módszerrel? Jobb! Használja a privát módosítót a hozzáférés korlátozásához. Ez lehetővé teszi számukra, hogy békésen végezzék munkájukat az osztályon belül anélkül, hogy megzavarnák a felhasználót, akinek nem kell ismernie az egyes módszerek logikáját.
public class ColliderUtil {
public void readDataFromCollider(Path pathToData) {
byte[] colliderData = readByteData(pathToData);
String[] textData = convertBytesToSymbols(colliderData);
File fileWithData = saveToFile(textData);
printColliderData(fileWithData);
}
private byte[] readByteData(Path pathToData) {
// Reads data in bytes
}
private String[] convertBytesToSymbols(byte[] colliderDataInBytes) {
// Converts bytes to characters
}
private File saveToFile(String[] colliderData) {
// Saves read data to a file
}
private void printColliderData(File fileWithColliderData) {
// Prints data from the file
}
}
A védett módosító
A következő legkorlátozóbb módosító védett . A védett
- minden osztályon belül, amelyek ugyanabban a csomagban vannak, mint a miénk;
- minden osztályon belül, amely az osztályunkat örökli.
public abstract class AbstractSecretAgent {
public static int agentCount = 0;
}
De az ügynökeink titkosak! Ez azt jelenti, hogy ők és senki más nem tudhatja, hányan léteznek belőlük. A védett módosítót könnyen hozzáadhatjuk az agent_counter mezőhöz. Ekkor a titkos ügynök osztályok példányai és a top_secret csomagunkban található egyéb osztályok megkaphatják az értékét.
public abstract class AbstractSecretAgent {
protected static int agent_counter = 0;
}
És ez az a fajta speciális feladat, amelyhez a védett módosító szükséges :)
A csomag látható módosítója
Következő a listán az alapértelmezett módosító, más néven a csomag látható módosítója. Ezt nem jelzi kulcsszó, mivel a Java alapértelmezés szerint minden mezőre és metódusra alkalmazza. Ha a következőket írja be a kódjába:
int x = 10
az x változónak látható hozzáférése lesz ehhez a csomaghoz . Könnyű megjegyezni, mit csinál. Alapvetően alapértelmezett = védett öröklődés :) A védett módosítóhoz hasonlóan az alkalmazása is korlátozott. Leggyakrabban az alapértelmezett hozzáférést olyan csomagban használják, amelynek vannak olyan segédprogramosztályai, amelyek nem valósítják meg a csomag összes többi osztályának funkcióit. Mondjunk egy példát. Képzelje el, hogy van egy „szolgáltatási” csomagunk. Különféle osztályokat tartalmaz, amelyek adatbázissal működnek. Például van egy UserService osztály, amely beolvassa a felhasználói adatokat az adatbázisból, egy CarServiceosztály, amely beolvassa az autóadatokat ugyanabból az adatbázisból, és más osztályok, amelyek mindegyike meghatározott típusú objektumokkal működik, és a megfelelő adatokat olvassa be az adatbázisból.
package services;
public class UserService {
}
package services;
public class CarService {
}
De könnyen előfordulhat, hogy az adatbázisban lévő adatok egy formátumban lennének, és szükségünk van rá egy másik formátumban. Képzelje el, hogy a felhasználók születési dátuma az adatbázisban <IDŐZÓNA IDŐBÉLYEGZÉS>ként van tárolva...
2014-04-04 20:32:59.390583+02
...és helyette a legegyszerűbb objektumra van szükségünk – egy java.util.Date . A probléma megoldására a szolgáltatáscsomagon belül létrehozhatunk egy speciális Mapper osztályt. Feladata lesz az adatbázisból származó adatok átalakítása ismerős Java objektumainkká. Egy egyszerű segítő osztály. Általában minden osztályt nyilvános osztályként Osztálynévként deklarálunk , de ez nem követelmény. Segítő osztályunkat egyszerűen Mapper osztálynak nyilváníthatjuk . Ebben az esetben továbbra is teszi a dolgát, de a szolgáltatáscsomagon kívül nem látja senki !
package services;
class Mapper {
}
package services;
public class CarService {
Mapper mapper;
}
És itt van az alapvető érvelés: miért kellene bárkinek a csomagon kívül látnia egy olyan segítő osztályt, amely csak a csomagban lévő osztályokkal működik?
A nyilvános módosító
És végül, de nem utolsósorban a nyilvános módosító! Ezzel a módosítóval a CodeGym első tanulmányi napján találkoztál, amikor először futtattad a nyilvános static void main(String[] args) .
public class Translator {
public String translate(String textInRussian) {
// Translates text from Russian to English
}
}
Ezt a módszert a képernyőn lévő „Fordítás” gombhoz kötheti, és kész! Bárki használhatja. A nyilvános módosítóval jelölt kódrészek a végfelhasználónak szólnak. Valós példát mutatva a privát a TV-n belül végbemenő összes folyamatra vonatkozik, de a nyilvános a távirányítón a tévé kezeléséhez használt gombokra. Sőt, a felhasználónak nem kell tudnia, hogyan épül fel vagy hogyan működik a televízió. A távirányító a nyilvános -metódusok halmaza : on() , off() , nextChannel() , previousChannel() , expandVolume() , csökkentésVolume() stb. A tanultak megerősítése érdekében javasoljuk, hogy nézzen meg egy videóleckét a Java-tanfolyamról
GO TO FULL VERSION