JavaRush /Java Blog /Random-KO /액세스 수정자. 비공개, 보호, 기본, 공개

액세스 수정자. 비공개, 보호, 기본, 공개

Random-KO 그룹에 게시되었습니다
안녕하세요! 오늘 강의에서는 " 액세스 한정자 " 의 개념에 대해 알아보고 이를 사용한 작업 예를 살펴보겠습니다. 액세스 수정자.  비공개, 보호, 기본, 공개 - 1"알자"라는 단어가 완전히 정확하지는 않지만 이전 강의에서 이미 대부분을 잘 알고 있습니다. 혹시라도 중요한 것에 대한 기억을 새로 고쳐 봅시다. 액세스 한정자는 코드의 다양한 부분에 대한 액세스 수준을 규제하는 키워드입니다. 왜 "가장 자주"입니까? 그 중 하나는 기본적으로 설정되어 있고 키워드로 표시되지 않기 때문이죠 :) 자바에는 총 4개의 접근 한정자가 있습니다. 가장 엄격한 것부터 가장 "부드러운" 것까지 순서대로 나열합니다.
  • 사적인;
  • 보호됨;
  • default(패키지 표시);
  • 공공의.
각각을 살펴보고 언제 우리에게 유용할 수 있는지 결정하고 예를 들어보겠습니다. :)

수정자 비공개

액세스 수정자.  비공개, 보호, 기본, 공개 - 2Private— 가장 제한적인 액세스 수정자입니다. 단일 클래스 내에서 데이터와 메서드의 가시성을 제한합니다. getter 및 setter에 대한 강의에서 이 수정자를 알고 있습니다. 이 예를 기억하시나요?
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;
   }
}
우리는 이전 기사 중 하나에서 이에 대해 살펴보았습니다. 여기서 우리는 심각한 실수를 범했습니다. 데이터를 열었고 그 결과 동료 프로그래머가 클래스 필드에 직접 액세스하고 해당 값을 변경할 수 있었습니다. 또한 이러한 값은 검사 없이 할당되었으며 그 결과 우리 프로그램에서는 나이가 -1000년이고 이름이 ""이고 체중이 0인 고양이를 생성할 수 있습니다. 이 문제를 해결하기 위해 우리는 getter 및 setter를 사용했으며 수정자를 사용하여 데이터에 대한 액세스도 제한했습니다 private.
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) {
       // checking the input parameter
       this.name = name;
   }

   public int getAge() {
       return age;
   }

   public void setAge(int age) {
       // checking the input parameter
       this.age = age;
   }

   public int getWeight() {
       return weight;
   }

   public void setWeight(int weight) {
       // checking the input parameter
       this.weight = weight;
   }
}
실제로 필드에 대한 액세스를 제한하고 getter-setter를 구현하는 것이 실제 작업에서 가장 일반적으로 사용되는 예입니다 . private 즉, 프로그램에서 캡슐화를 구현하는 것이 이 수정자의 주요 목적입니다. 그런데 이것은 필드에만 적용되는 것이 아닙니다. 귀하의 프로그램에 매우 복잡한 기능을 구현하는 메서드가 있다고 상상해 보십시오. 이를 예로 들어보겠습니다... 귀하의 메소드가 readDataFromCollider()데이터가 포함된 주소를 입력으로 취하고, Large Hadron Collider에서 바이트 형식으로 데이터를 읽고, 이 데이터를 텍스트로 변환하고, 파일에 쓰고 인쇄한다고 가정해 보겠습니다. 코드는커녕 메소드에 대한 설명조차 오싹해 보이네요 :) 코드의 가독성을 높이려면 메소드의 복잡한 로직을 한곳에 작성하지 않고 오히려 기능을 망가뜨리는 방식으로 작성하는 것이 좋을 것 같습니다. 별도의 방법으로. 예를 들어, 이 메서드는 readByteData()데이터 읽기, convertBytesToSymbols()충돌기에서 읽은 데이터를 텍스트로 변환, saveToFile()결과 텍스트를 파일에 저장 및 printColliderData()데이터 파일 인쇄를 담당합니다. 방법은 readDataFromCollider()훨씬 간단해집니다.
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) {

       // convert bytes to characters
   }

   public File saveToFile(String[] colliderData) {

       // save the read data to a file
   }

   public void printColliderData(File fileWithColliderData) {

       // print data from file
   }
}
그러나 인터페이스 강의에서 기억했듯이 사용자는 최종 인터페이스에만 접근할 수 있습니다. 그리고 우리의 4가지 방법은 그것의 일부가 아닙니다. 이는 보조적 입니다 . 코드 가독성을 높이고 네 가지 다른 작업을 하나의 방법에 밀어넣는 것을 방지하기 위해 만들었습니다. 사용자에게 이러한 메서드에 대한 액세스 권한을 부여할 필요는 없습니다. 사용자가 충돌체로 작업할 때 해당 메서드에 액세스할 수 있는 경우 convertBytesToSymbols()이 메서드가 무엇인지, 왜 필요한지 이해하지 못할 가능성이 높습니다. 어떤 바이트가 변환됩니까? 저들은 어디서 왔어요? 왜 텍스트로 변환합니까? 이 메서드에서 실행되는 논리는 사용자 인터페이스의 일부가 아닙니다. 메소드만 readDataFromCollider()이 인터페이스의 일부입니다. 이 네 가지 "내부" 메서드를 사용하여 무엇을 해야 할까요? 오른쪽! 수정자를 사용하여 해당 항목에 대한 액세스를 제한합니다 private. 이렇게 하면 클래스 내에서 작업을 쉽게 수행할 수 있고 각 클래스의 논리가 별도로 필요하지 않은 사용자를 혼란스럽게 하지 않을 수 있습니다.
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) {
       // convert bytes to characters
   }

   private File saveToFile(String[] colliderData) {
       // save the read data to a file
   }

   private void printColliderData(File fileWithColliderData) {
       // print data from file
   }
}

수정자 보호됨

다음으로 가장 제한적인 액세스 수정자는 입니다 protected. 액세스 수정자.  비공개, 보호, 기본, 공개 - 3 액세스 한정자로 지정된 필드와 메서드가 protected표시됩니다.
  • 우리와 동일한 패키지에 있는 모든 클래스 내에서;
  • 우리 클래스의 모든 후속 클래스 내에서.
이것이 언제 필요할지 즉시 상상하기는 어렵습니다. 놀라지 마십시오. protected에 비해 적용 사례가 훨씬 적고 private구체적입니다. AbstractSecretAgent특정 서비스의 비밀 요원을 나타내는 추상 클래스와 top_secret이 클래스 및 그 하위 항목을 포함하는 패키지 가 있다고 상상해 보십시오 . 구체적인 클래스( , FBISecretAgent등 )이 여기에서 상속됩니다. 추상 클래스 내에서 에이전트 카운터를 구현하려고 합니다. 프로그램 어딘가에 새 에이전트 개체가 생성되면 개체 수가 늘어납니다. MI6SecretAgentMossadSecretAgent
package top_secret;

public abstract class AbstractSecretAgent {

   public static int agentCount = 0;
}
하지만 우리 요원의 비밀은 비밀이에요! 이는 자신과 다른 누구도 자신의 번호를 알 수 없음을 의미합니다. protected필드에 수정자를 쉽게 추가할 수 agentCount있으며 다른 비밀 요원 클래스의 객체나 "비밀" 패키지에 있는 클래스가 해당 값을 얻을 수 있습니다 top_secret.
public abstract class AbstractSecretAgent {

   protected static int agentCount = 0;
}
수정자가 필요한 특정 작업을 위한 것입니다 protected. :)

패키지 표시 수정자

다음 목록에는 수정자 default또는 라고도 불리는 가 있습니다 package visible. Java에서는 모든 필드와 메소드에 대해 기본적으로 설정되어 있으므로 키워드로 표시하지 않습니다. 코드를 작성하면 -
int x = 10;
... 변수는 x이와 동일한 액세스 권한을 갖습니다 package visible. 메소드(또는 변수)가 어떤 수정자로 표시되지 않은 경우 "기본 수정자"로 표시된 것으로 간주됩니다. 이러한 수정자가 있는(즉, 전혀 없는) 변수나 메서드는 해당 수정자가 선언된 패키지의 모든 클래스에서 볼 수 있습니다. 그리고 그들에게만. modifier 와 마찬가지로 용도가 제한되어 있습니다 protected. 대부분의 경우 default-access는 이 패키지에 있는 다른 모든 클래스의 기능을 구현하지 않는 일부 유틸리티 클래스가 있는 패키지에서 사용됩니다. 예를 들어 보겠습니다. " services " 패키지가 있다고 상상해 보세요 . 그 안에는 데이터베이스와 함께 작동하는 다양한 클래스가 있습니다. UserService예를 들어, 데이터베이스에서 사용자 데이터를 읽는 클래스, CarService동일한 데이터베이스에서 자동차에 대한 데이터를 읽는 클래스, 그리고 각각 고유한 유형의 개체와 작동하고 데이터베이스에서 해당 개체에 대한 데이터를 읽는 기타 클래스가 있습니다 .
package services;

public class UserService {
}

package services;

public class CarService {
}
그러나 데이터베이스의 데이터가 한 형식인데 다른 형식이 필요한 경우 상황이 쉽게 발생할 수 있습니다. 데이터베이스에 있는 사용자의 생년월일이 TIMESTAMP WITH TIME ZONE... 형식으로 저장되어 있다고 상상해 보세요.
2014-04-04 20:32:59.390583+02
...대신 가장 간단한 객체가 필요합니다 java.util.Date. 이를 위해 패키지 내부에 services특수 클래스를 만들 수 있습니다 Mapper. 그는 데이터베이스의 데이터를 우리에게 친숙한 Java 개체로 변환하는 일을 담당합니다. 간단한 도우미 클래스. 우리는 일반적으로 모든 클래스를 로 생성 public class ClassName하지만 반드시 그럴 필요는 없습니다. 도우미 클래스를 다음과 같이 간단하게 선언할 수 있습니다 class Mapper. 이 경우에도 여전히 해당 작업을 수행하지만 패키지 외부의 누구에게도 표시되지 않습니다 services!
package services;

class Mapper {
}


package services;

public class CarService {

   Mapper mapper;
}
그리고 실제로 이것은 올바른 논리입니다. 왜 패키지 외부의 누군가가 동일한 패키지의 클래스에서만 작동하는 보조 클래스를 보게 될까요?

공개 수정자

그리고 목록의 마지막 항목이지만 가장 중요한 것은 수정자입니다 public! JavaRush에서 공부한 첫날 그를 만나서 public static void main(String[] args). 액세스 수정자.  비공개, 보호, 기본, 공개 - 4 이제 인터페이스에 대한 강의를 공부했으니 인터페이스의 목적이 분명해졌습니다 :) 결국 public사용자에게 무언가를 제공하기 위해 만들어졌습니다. 예를 들어, 프로그램의 인터페이스입니다. 당신이 번역기 프로그램을 작성했고, 이 프로그램이 러시아어 텍스트를 영어로 번역할 수 있다고 가정해 보겠습니다. translate(String textInRussian)필요한 논리가 구현되는 메서드를 만들었습니다 . 이 메소드를 단어로 표시하면 public이제 인터페이스의 일부가 됩니다.
public class Translator {

   public String translate(String textInRussian) {

       // translates text from Russian to English
   }
}
이 메서드에 대한 호출을 프로그램 화면의 "번역" 버튼과 연결할 수 있습니다. 그게 전부입니다! 누구나 사용할 수 있습니다. 수정자로 표시된 코드 부분은 public최종 사용자를 위한 것입니다. 실제 생활의 예를 들자면, private이는 TV가 작동할 때 내부에서 발생하는 모든 과정이며, public사용자가 TV를 제어할 수 있는 TV 리모컨의 버튼입니다. 동시에 그는 TV 작동 방식과 작동 방식을 알 필요가 없습니다. 리모콘은 , , , , 등 public의 방법 세트입니다 .on()off()nextChannel()previousChannel()increaseVolume()decreaseVolume()
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION