Java >> Java tutorial >  >> Java

Indkapsling i Java

En af de fire søjler i OOP-konceptet er indkapsling. Arv, polymorfi og abstraktion er de tre andre.

I Java kombinerer indkapsling data (variabler) og kode, der virker på dataene (metoderne) til en enkelt enhed. Indkapsling betyder, at en klasses variabler er skjult for andre klasser og kun kan tilgås gennem dens nuværende klasses metoder. Derfor er det også kendt som dataskjulning.

Målet med indkapsling er at holde implementeringsdetaljer skjult for brugerne. Andre medlemmer af samme klasse kan kun få adgang til et privat datamedlem. Ingen ekstern klasse har adgang til en klasses private datamedlem (variabel).

Antag dog, at vi opretter offentlige getter- og setter-metoder til at opdatere (f.eks. void setEmployee(int ID)) og læse (f.eks. int getEmployee()) de private datafelter. I så fald kan den eksterne klasse bruge disse offentlige metoder til at få adgang til de private datafelter. Private felter og deres implementering er skjult for eksterne klasser, da offentlige metoder kun kan få adgang til data.

Indkapsling i Java

For at implementere indkapsling i Java,

  • Erklære en klasses variabler som private.
  • For at ændre og inspicere variablernes værdier skal du angive public setter- og getter-metoder.

Herefter vil vi se på den syntaks, du bruger, når du implementerer indkapsling i Java. Syntaksen er som følger:

<Access_Modifier> class <Class_Name> {

 private <Data_Members>;

 private <Data_Methods>;

}

Lad os udforske eksempelprogrammet nedenfor for at forstå indkapslingsprocessen bedre.

Eksempel:Følgende kode illustrerer, hvordan man implementerer Encapsulation i Java.

/* File name : CodeEncapsulation.java */

public class CodeEncapsulation {

   private String name;
   private String idNum;
   private int age;

   public int getAge() {
      return age;
   }

   public String getName() {
      return name;
   }

   public String getIdNum() {
      return idNum;
   }

   public void setAge( int newAge) {
      age = newAge;
   }

   public void setName(String newName) {
      name = newName;
   }

   public void setIdNum( String newId) {
      idNum = newId;
   }
}

De offentlige setXXX()- og getXXX()-metoder giver adgang til CodeEncapsulation-klassens instansvariabler. Disse metoder omtales almindeligvis som getters og settere. Som et resultat bør enhver klasse, der har brug for adgang til variablerne, bruge disse gettere og sættere. CodeEncapsulation-klassevariablerne tilgås med følgende program:

/* Filename : RunCodeEncapsulation.java */
public class RunCodeEncapsulation {

   public static void main(String args[]) {
      CodeEncapsulation encapVar = new CodeEncapsulation();
      encapVar.setName("Green");
      encapVar.setAge(53);
      encapVar.setIdNum("TY905");

      System.out.print("Name : " + encapVar.getName() + " Age : " + encapVar.getAge());
   }
}

Getter og Setter-metoder

Getter

En getter-metode er en metode, der giver dig adgang til og hente en forekomst af en privat variabel.

Setter

Setter-metoden er i stand til at opdatere eller indstille en privat variabel instans.

package Codeunderscored;

public class CodeEmployee {

private String c_name;

public String getCodeName() {

return c_name;

}

public void setCodeName(String c_name){  

this.c_name=c_name ;

}

}

package Codeunderscored;

public class CodeTestGettersSetters {

public static void main(String[] args) {

CodeEmployee empOne = new CodeEmployee();

empOne.setCodeName("Green");

System.out.println(empOne.getCodeName());

}

}

//Output: Green

Fordele ved indkapsling

  • Du kan gøre en klasse skrivebeskyttet eller skrivebeskyttet ved kun at angive en setter- eller getter-metode.
  • Med andre ord er getter- og setter-metoderne valgfrie.
  • De mest almindelige IDE'er giver mulighed for at generere gettere og sættere. Oprettelse af en lukket klasse i Java er således enkel og hurtig. I forlængelse heraf letter dette hele processen med at skrive programmer.
  • Indkapsling i Java giver dig mulighed for at genbruge din kode.
  • Indkapsling giver dig mulighed for hurtigt at foretage ændringer af eksisterende kode.
  • Det giver dig fuld kontrol over dine data. Du kan skrive logikken inde i setter-metoden, hvis du kun vil indstille værdien af ​​id til at være større end 100. Du kan implementere logik i setter-metoderne for at forhindre negative heltal i at blive lagret.
  • En klasse kan have fuldstændig kontrol over indholdet af dens felter.
  • Fordi andre klasser ikke vil være i stand til at få adgang til dataene gennem de private datamedlemmer, er det en måde at opnå dataskjul i Java. Det er nemt at teste den medfølgende klasse. Som følge heraf er den mere egnet til enhedstestning.
  • Enhedstestkoden skrevet med indkapsling er enkel.

Indkapsling i Java:Et simpelt eksempel

Lad os se på et simpelt indkapslingseksempel med kun ét felt og setter- og getter-metoder.

// A Java class that is completely enclosed. It has a getter and setter method and a private data member.

package com.codeunderscored;  

public class CodeStudent{  

  //the data member  is  private
  private String name;  

  // name's getter method
  public String getName(){  
    return name;  
  }  
  //names' setter method
  public void setName(String name){  
    this.name=name  
    }  
}  


//The Java class here tests the encapsulated class above
package com.codeunderscored;  

class CodeTest{  

  public static void main(String[] args){  

    //first, create an instance of the encapsulated class  

    CodeStudent codeStudent = new CodeStudent();  

    // using the setter method to assign value to the name member  
    codeStudent.setName("Green");  

    // Using the name's get method to fetch the value of the name member  
    System.out.println(codeStudent.getName());  
  }  
}  

Følgende er en skrivebeskyttet klasse.

//Only getter methods are available in this Java class.

public class CodeStudent{  

  //The data member is  private
  private String code_school="Code Underscored";  

  // code_school's getter method
  public String getCodeSchool(){  
    return code_school;  
  }  
}

Du kan ikke længere redigere værdien af ​​code_school-datamedlemmet "Code Underscored."

codeStudent.setCodeSchool("w3schools");// the code renders a compile time error

Følgende er en skrivebeskyttet klasse:

//Only setter methods are available in this Java class.
public class CodeStudent{  

  //data member  is private
  private String code_school;  

  //code_school's setter method
  public void setCodeSchool(String code_school){  
    this.code_school=code_school;  
  }  
}  

Du kan ikke længere få adgang til kode_skolens værdi; i stedet kan du kun opdatere værdien af ​​kode_skole-datakomponenten.

System.out.println(codeStudent.getCodeSchool());//There is no such procedure, resulting in a Compile Time Error.
System.out.println(codeStudent.code_school);//Because the college data member is private, there is a Compile Time Error.
//As a result, it is not accessible from outside the class.

Endnu et Java-eksempel på indkapsling

Lad os se på et andet indkapslingseksempel med kun fire felter og setter- og getter-funktioner.

//   An Account class that is completely contained.
// It has a getter and setter method and a private data member.

class CodeAccount {  

  //The data members are private

  private long code_acc_no;  
  private String code_name,code_email;  
  private float code_amount;  

  //These getter and setter methods  are all public
  public long getCodeAccNo() {  
    return code_acc_no;  
  }  
  public void setCodeAccNo(long code_acc_no) {  
    this.code_acc_no = code_acc_no;  
  }  
  public String getCodeName() {  
    return code_name;  
  }  
  public void setCodeName(String code_name) {  
    this.code_name = code_name;  
  }  
  public String getCodeEmail() {  
    return code_email;  
  }  
  public void setCodeEmail(String code_email) {  
    this.code_email = code_email;  
  }  
  public float getCodeAmount() {  
    return code_amount;  
  }  
  public void setCodeAmount(float code_amount) {  
    this.code_amount = code_amount;  
  }  

}  




//A Java class for testing the encapsulated Account class.

public class CodeTestEncapsulation {  

  public static void main(String[] args) {  

    //creation of CodeAccount class instance
    CodeAccount codeAccount=new CodeAccount();  

    //Using the setter methods to set values
    codeAccount.setCodeAccNo(111THY78645);  
    codeAccount.setCodeName("Code Underscored");  
    codeAccount.setCodeEmail("[email protected]");  
    codeAccount.setCodeAmount(250f);  

    // using the getter methods to fetch respective  values
    System.out.println(codeAccount.getCodeAccNo()+" "+codeAccount.getCodeName()+" "+codeAccount.getCodeEmail()+" "+codeAccount.getCodeAmount());  
  }  
}  

Eksempel:Indkapsling i Java

class CodeArea {

  // fields for calculating the area
  int c_length;
  int c_breadth;

  // constructor for values initialization

  CodeArea(int c_length, int c_breadth) {
    this.c_length = c_length;
    this.c_breadth = c_breadth;
  }

  // method responsible for area calculate
  public void getCodeArea() {
    int resultantArea = c_length * c_breadth;
    System.out.println("Resultant Area is: " + resultantArea);
  }
}

class Main {
  public static void main(String[] args) {

    // create object of Area
    // pass value of length and breadth
    resultantArea rec = new resultantArea(12, 16);
    rec.getCodeArea();
  }
}

Vi etablerede en klasse kaldet CodeArea i det foregående eksempel. Klassens primære mål er at beregne arealet. To variable, c_length og c_breadth, plus en metode, getCodeArea, er nødvendige for at bestemme arealet. Som et resultat kombinerede vi disse attributter og metoder i én klasse.

Egenskaberne og metoderne for denne klasse kan også være tilgængelige fra andre klasser. Som følge heraf er dette ikke dataskjul. Det er kun et resumé. Vi grupperer bare sammenlignelige koder. Mens mange mennesker tænker på indkapsling som dataskjul, er dette ikke helt nøjagtigt. Indkapsling er sammensætningen af ​​lignende felter og procedurer. Du kan bruge det til at skjule information. Dataskjul er derfor ikke det samme som indkapsling.

Hvad er formålet med indkapsling?

Indkapsling i Java giver os mulighed for at gruppere relevante felter og metoder, hvilket gør vores kode klarere og lettere at læse.

Det hjælper med styringen af ​​vores datafelters værdier. For eksempel,

class CodeEmployee {
  private int age;

  public void setCodeAge(int c_age) {
    if (age >= 0) {
      this.c_age = c_age;
    }
  }
}

Variablen c_age er nu privat, og logik anvendes i setCodeAge()-metoden. c_age er ikke længere en negativ faktor. Vores klassefelter kan eksistere som skrivebeskyttet eller skrivebeskyttet. Sidstnævnte er afhængig af enten at bruge getter- og setter-metoderne. For eksempel,

getCodeName()  // provides access for read-only
setCodeName() // provides access for write-only

Det hjælper med afkoblingen af ​​systemkomponenter. Vi kan for eksempel opdele kode i flere bundter. Disse adskilte komponenter (bundt) kan bygges, testes og fejlfindes på deres egen tid. Desuden har eventuelle ændringer i en komponent ingen indflydelse på de andre. Indkapsling kan også bruges til at skjule data. Hvis vi indstiller længde- og breddevariablerne til private i det foregående eksempel, er adgangen til disse felter begrænset. De holdes også hemmelige for overklassen. Det omtales som dataskjulning.

Skjuler data

Dataskjul er en metode til at begrænse datamedlemmers adgang til vores data ved at skjule implementeringsdetaljer. Indkapsling gør det også muligt at skjule data. Du kan skjule data ved at bruge adgangsmodifikatorer.

Følgende er de fire adgangsspecifikationer:

Standard

Den første linje med skjult data er standard. Hvis der ikke er angivet nogen adgangsspecifikation for en given Java-klasse, vil compileren bruge 'default' som adgangsspecifikation. Standardadgangsspecifikationen ligner meget den offentlige adgangsspecifikation med hensyn til funktionalitet.

Offentlig

Den mindst restriktive adgangsmodifikator er denne. Metoder og egenskaber med den offentlige modifikator kan være tilgængelige både inden for og uden for din nuværende klasse.

Den offentlige API for din klasse og enhver komponent, du inkluderer, inkluderer offentlige metoder og attributter. Det er normalt aldrig en god idé for nogen egenskab. Vær derfor forsigtig, når du anvender denne modifikation på en metode. Når en metode gøres offentlig tilgængelig, skal den være tilstrækkeligt beskrevet og i stand til at håndtere inputværdier. Husk, at denne teknik vil blive brugt af en del af dit program, hvilket gør det vanskeligt at opdatere eller fjerne.

Din offentlige API skal generelt være så let som muligt. Kun de metoder, der bruges af andre dele af programmet eller eksterne klienter, er inkluderet i offentlige API'er. Offentlig adgangsspecifikationen giver klasseadgang til dens adgangsspecifikationer for adgang fra hvor som helst i programmet.

Eksempel:

package Codeunderscored;

class CodeVehicle {

public int c_tires;

public void CodeDisplay() {

System.out.println("Codeunderscored owns a vehicle.");

System.out.println("The vehicle has " + c_tires + " number of wheels.");

}

}

public class CodeTestVehicle {

public static void main(String[] args) {

CodeVehicle codeVehicle = new CodeVehicle();

codeVehicle.tires = 8;

codeVehicle.display();

}

}

//Output: Codeunderscored owns a vehicle.
// It has 8 number of wheels.

Privat

Den private modifikator, den mest restriktive og udbredte adgangsmodifikator, begrænser adgangen til en attribut eller metode til andre medlemmer af samme klasse. Denne attribut eller metode er ikke tilgængelig for underklasser eller andre klasser i den samme eller en anden pakke.

Som standard skal du vælge den private modifikator for alle attributter og interne metoder, du ikke bør kalde fra eksterne klasser. Du skal muligvis gøre en undtagelse fra denne regel, når du bruger arv. Nogle underklasser, der kræver direkte adgang til en egenskab eller intern metode, bør også undtages. I stedet for at bruge den private modifikator, bør du bruge den beskyttede modifikator. Datamedlemmerne bruger specifikationen for privat adgang til tilgængelighed. På den anden side er datametoderne begrænset til selve klassen.

Eksempel:

package Codeunderscored;

class CodeEmployee {

private int code_rank;

public int getCodeRank() {

return code_rank;

}

public void setCodeRank(int code_rank) {

this.code_rank = code_rank;

}

}

public class CodeTestEmployee {

public static void main(String[] args) {

CodeEmployee codeEmployee = new CodeEmployee();

codeEmployee.setCodeRank(1);

System.out.println("The Code Employee's rank is " + codeEmployee.getCodeRank());

}

}

// Output:
// The Code Employee's rank is 1

Beskyttet

Ligesom specifikationen for privat adgang, beskytter specifikationen for beskyttet adgang klassens metoder og medlemmer. Den vigtigste skelnen er, at i stedet for at begrænse adgangen til en enkelt klasse, er pakken som helhed begrænset. Interne metoder, der skal kaldes eller tilsidesættes af underklasser, får normalt den beskyttede modifikator. Du kan også bruge den beskyttede modifikator til at give underklasser direkte adgang til en superklasses interne attributter.

package Codeunderscored;

class Computer {

protected String code_stream;

protected void CodeDisplay() {

System.out.println("Hello, people refer to me as the " + code_stream + " Technology");

}

}

public class SuperComputer extends Computer {

public static void main(String[] args) {

SuperComputer superComputer = new SuperComputer();

superComputer.stream = " super computer  because of my ";

SuperComputer.CodeDisplay();

}

}

//Output:
// Hello, people refer to me as the  super computer  because of my Technology

Eksempel:Dataskjulning

class CodeEmployee {

  // private field
  private int c_age;

  // getter method
  public int getCodeAge() {
    return c_age;
  }

  // setter method
  public void setCodeAge(int c_age) {
    this.c_age = c_age;
  }
}

class Main {
  public static void main(String[] args) {

    // creating a Person's Object
    CodeEmployee empOne = new CodeEmployee();

    // using the setter method to change the  c_age
    empOne.setCodeAge(32);

    // using the getter method to access c_age
    System.out.println("My Current age is :" + empOne.getCodeAge());
  }
}

Vi har et privat felt c_age i eksemplet ovenfor. Du kan ikke få adgang til den uden for klassen, fordi den er privat. I dette eksempel brugte vi de offentlige metoder getCodeAge() og setCodeAge() til at hente c_age. Disse er kendt som getter og setter metoder. Vi var i stand til at forbyde ulovlig adgang uden for klassen ved at gøre alder hemmelig. Dette er dataskjul. Forsøg på at få adgang til feltet c_age fra hovedklassen vil få en fejl.

// error: c_age has private access in CodeEmployee
empOne.c_age = 36;

Indkapsling vs. abstraktion

Abstraktion og indkapsling forveksles ofte. Lad os undersøge-

  • Indkapsling handler hovedsageligt om "Hvordan" for at opnå funktionalitet.
  •  
  • Abstraktion handler primært om "hvad" en klasse kan udrette.

En mobiltelefon er en nem måde at forstå forskellen på, hvor printkortets sofistikerede kredsløb er indkapslet i en berøringsskærm med en grænseflade til at abstrahere det væk.

Eksempel:Program til demonstration af variabel adgang ved hjælp af indkapsling i Java

class CodeEncapsulate {

	// The following private variables declared below can only be accessed by the class's public methods

	private String codeName;
	private int codeRoll;
	private int codeAge;

	// getting the method for age to access
	// private variable codeAge
	public int getCodeAge() { return codeAge; }

	// getting the method for name to access
	// private variable codeName
	public String getName() { return codeName; }

	// getting the method for roll to access
	// private variable codeRoll
	public int getCodeRoll() { return codeRoll; }

	// setting the method for age to access
	// private variable codeAge
	public void setCodeAge(int codeAge) { codeAge = codeAge; }

	// setting the method for codeName to access
	// private variable codeName
	public void setCodeName(String codeName)
	{
		codeName = codeName;
	}

	// set method for roll to access
	// private variable geekRoll
	public void setRoll(int newRoll) { geekRoll = newRoll; }
}

public class TestCodeEncapsulation {
	public static void main(String[] args)
	{
		CodeEncapsulate codeEncapsulate = new CodeEncapsulate();

		// setting values of the variables
		codeEncapsulate.setCodeName("Green");
		codeEncapsulate.setCodeAge(34);
		codeEncapsulate.setCodeRoll(198);

		// Displaying the variable values
		System.out.println("Code's name: " + codeEncapsulate.getCodeName());
		System.out.println("Code's age: " + codeEncapsulate.getAge());
		System.out.println("Code's roll: " + codeEncapsulate.getRoll());

		// Direct access of CodeRoll is not possible because of encapsulation
		// System.out.println("Code's roll: " +// codeEncapsulate.CodeName);
	}
}

Konklusion

I Java kombinerer indkapsling kode og data i en enkelt enhed, såsom en kapsel, der indeholder flere lægemidler. Yderligere kan vi i Java oprette en fuldt lukket klasse ved at holde alle klassens datamedlemmer private. Vi kan nu indstille og få data ved hjælp af setter og getter metoder. Java Bean-klassen repræsenterer en fuldt indeholdt klasse. Det bruges ofte til at implementere en metode til at skjule data. Denne strategi minimerer egenskabernes tilgængelighed til den aktuelle klasse og kontrollerer og begrænser ekstern adgang til disse attributter ved hjælp af offentlige getter- og setter-metoder. Disse metoder lader dig specificere, hvilke egenskaber der kan læses eller opdateres og validere den nye værdi, før du foretager en ændring.

Indkapsling har den grundlæggende egenskab at skjule data og sikre brugerdatas sikkerhed. Indkapsling er en god OOP-praksis. Det fungerer dog bedst, når det kombineres med en pålidelig APM-løsning som Retrace til fejlovervågning.


Java tag