Java공부(코딩)

코딩초보의 자바(Java)공부 9일차-2 { 접근 제어자 }

동곤일상 2024. 12. 14. 18:15
반응형
 접근 제어자에
대해서 알아보겠습니다!
보안과 관련된 챕터이므로
잘 봐주세요!!!

 


1) 접근제어자 이해

자바는 `public` , `private` 같은

접근 제어자(access modifier) 제공한다.

접근 제어자를 사용하면 해당 클래스외부에서

특정 필드나 메서드에 접근하는 것을

허용하거나 제한할 있다.

예제를 통해 접근 제어자가 필요한 이유를 알아보자!

 

 

냉방온도 23 도 밑으로 떨어지지않게

소프트웨어로 제어한다고 생각해보자

 

public class AirCond {

int temperature;

 

public AirCond(int temperature) {

this.temperature = temperature;

}

void tempUp() {

temperature++;

System.out.println("온도 +1");

}

 

void tempDown() {

if(23>= temperature) {

System.out.println("온도를 내릴 수 없어");}

else {

temperature--;

System.out.println("온도 -1");

}}

void tempShow() {

System.out.println("현재온도 : "+temperature);

}}

다음과 같이 23도보다 작거나 같다면

온도를 내리지 못하게 막아놓은

클래스를 만들었습니다.

 

 

하지만 여기서는 문제가 있습니다.

필드가 defalt(같은패키지에서 접근가능)

 

다음과 같은 오류가 있을 수 있어요

public class AirCon_Main {

public static void main(String[] args) {

AirCond airCon = new AirCond(26);

airCon.tempUp();

airCon.tempShow();

airCon.tempDown();

//필드(멤버변수)에 직접 참조

airCon.temperature = 18;

airCon.tempShow();}}

 

//출력

온도 +1

현재온도 : 27

온도 -1

현재온도 : 18

 

이와 같이 필드에 직접접근해서 악용하는 사례가

있을 수 있기 때문에

접근제어자를 통해

다른곳에서 접근할 수 없게

설정 해주어야함.

 

int temperature ;

-->

private int temperature

로 변경 후 다시 실행

The field AirCond.temperature is not visible

컴파일 오류 발생 !!

(접근제어자를 통해 필드접근 막음)


2) 접근제어자 종류

 

private)

다른클래스에서도 접근 불가능

(모든 외부노출 막기)

 

defalut)

패키지내에선 접근 허용

( 기본값 )

 

protected)

같은 패키지안에서 호출은 허용한다.

패키지가 달라도 상속 관계의 호출은 허용한다.

 

public)

모든 외부노출 허용


 

접근제어자 사용 예)

public class AirCond { //클래스의 접근제어자

private int temperature; // 필드의 접근제어

 

public AirCond(int temperature) { //생성자

if(23 < temperature) {

this.temperature = temperature;}

else {return;}

}

public void tempUp() { //메서드

temperature++;

System.out.println("온도 +1");

}

 


접근 제어자의 핵심은 속성과 기능을 외부로부터 숨기는 것이다.

`private` 나의 클래스 안으로 속성과 기능을 숨길 사용,

외부 클래스에서 해당 기능을 호출할 없다.

 

`default` 나의 패키지 안으로 속성과 기능을 숨길 사용

, 외부 패키지에서 해당 기능을 호출할 없다.

 

`protected` 상속 관계로 속성과 기능을 숨길 사용,

상속 관계가 아닌 곳에서 해당 기능을 호출할 없다.

 

`public` 기능을 숨기지 않고

어디서든 호출할 있게 공개한다.


3) 접근제어자 코드로 !

package access;

 

public class PublicClass {

int defalutField;

private int privateField;

public int publicField;

 

public void publicMethod() {

System.out.println("publicMethod");

}

private void privateMethod() {

System.out.println("privateMethod");

}

 

void defalutMethod() {

System.out.println("defalutMethod");

}

 

public void innerMethod()

System.out.println("@@내부호출@@");

publicMethod();

privateMethod();

defalutMethod();

}

}

다음과 같이 각 접근제어자별로

필드와 메서드를 생성해봤습니다 

(패키지를 주의깊게 봐주세요)

 

같은패키지에서 생성한 메인코드

package access;

 

public class Inner_Access {

 

public static void main(String[] args) {

PublicClass a = new PublicClass();

a.publicField = 10;

// a.privateFiled = 20; 외부에선 private를 호출 불가능

a.defalutField=30; //같은 패키지는 접근 가능

a.publicMethod();

// a.privateMethod();

a.defalutMethod(); //같은패키지는 접근 가능

a.innerMethod();

/

/ 내부호출은 public으로 지정해놨기때문에 가능

같은 클래스 안에서 메서드호출이 일어나므로

private도 접근이 가능함

}}

 

/////////////////

 

출력)

publicMethod

 

defalutMethod

 

@@ 내부호출 @@

publicMethod

 

privateMethod

 

defalutMethod

 

 

다른패키지에서 호출

package access.a;

 

import access.*;

public class Outer_Access {

 

public static void main(String[] args) {

PublicClass a = new PublicClass();

a.publicField = 10;

// a.privateFiled = 20;

// a.defalutFiled=30;

 

a.publicMethod();

System.out.println();

// a.privateMethod();

// a.defalutMethod(); //다른패키지이므로 호출 불가능

a.innerMethod();}}

publicMethod

 

@@ 내부호출 @@

publicMethod

 

privateMethod

 

defalutMethod

 

내부 호출에 대해서 궁금할겁니다

private , defalut

다른 클래스 , 패키지에서

호출이 안된다했는데

어떻게 호출한거지????

하는 의문이 들 수 있어요

 

innterMethod를 호출하는 과정을

서툴지만 그림을 통해

알려드리겠습니다 !


4) 캡슐화

캡슐화는 속성과 기능을 한곳에 묶고

외부에 꼭 !!필요한 기능만

외부에 노출시키는 방식.

(객체지향개념에서 중요)

 

1. 데이터를 숨겨라

(사용자가 데이터를 함부로

조작해서는 안됨)

 

2.기능을 숨겨라

(사용자가 꼭 필요한

기능만 외부로 노출)


5) 예제

문제 - 쇼핑 카트

`ShoppingCartMain` 코드가 작동하도록

`Item` , `ShoppingCart` 클래스를 완성해라.

 

**요구사항**

**접근 제어자를 사용해서 데이터를 캡슐화 하세요.**

**해당 클래스는 다른 패키지에서도 사용할 있어야 합니다.**

장바구니에는 상품을 최대 10개만 담을 있다.

10 초과 등록시: "장바구니가 가득 찼습니다." 출력

 

ShoppingCartMain

package access.ex;

public class ShoppingCartMain {

public static void main(String[] args) {

ShoppingCart cart = new ShoppingCart();

Item item1 = new Item("마늘", 2000, 2);

Item item2 = new Item("상추", 3000, 4);

 

cart.addItem(item1);

cart.addItem(item2);

cart.displayItems();}}

package access.ex;

 

public class Item {

String name;

int price;

int quantity;

 

public Item(String name, int price, int quantity) {

 

this.name = name;

this.price = price;

this.quantity = quantity;

}

 

public String getName() {

return name;

}

 

public int total() {

return price * quantity;

}

}

 

public class ShoppingCart {

private Item[] items = new Item[10];

private int count;

 

public void addItem(Item item) {

if(count >= items.length) {

System.out.println("장바구니가 찼어요(10개)");

return;

}

items[count] = item;

count++;

}

public void displayItems() {

System.out.println("장바구니 상품 출력");

for (int i = 0; i < count; i++) {

Item item = items[i];

System.out.println("상품명:" + item.getName() + ", 합계:" +

item.total());

}

}

 

////

출력

 

장바구니 상품 출력

상품명:마늘, 합계:4000

상품명:상추, 합계:12000