지구정복
[JAVA] 11/12 | 접근제한자, getter와 setter, 패키지 본문
ㅇ복습
한 개일 때
-class 선언
멤버필드
인스턴스 멤버필드
스태틱 멤버필드
초기화블럭
인스턴스
스태틱
메서드
인스턴스 메서드
스태틱메서드
*constructor(멤버필드 초기화)
*main
*overloading
*가변인자
*this: 자기참조 / this(): 자기참조생성자
두 개일 때
-has -a : 포함관계
-is -a : 상속관계
class 자식클래스 extends 부모클래스
override
super 부모참조 / super() 부모생성자 사용
final클래스명: 상속거부
final메서드명: 재정의 거부
final필드명 : 상수
OOP : 객체지향프로그래밍
캡슐(은닉, DATA HIDING)
상속
추상
다형
ㅇ접근 제한자
접근 제한 | 적용 대상 | 접근가능 클래스 |
public | 클래스, 필드, 생성자, 메소드 | 모두 접근가능 |
protected | 필드, 생성자, 메소드 | 다른패키지에서 자식클래스, 같은 패키지 클래스 가능 다른 패키지의 클래스는 안된다. |
default | 클래스, 필드, 생성자, 메소드 | 다른 패키지에 속한 클래스빼고 다 가능 |
private | 필드, 생성자, 메소드 | 모든 외부 클래스는 접근 불가 |
일반적으로 멤버필드는 엄격하게(private)만들고, 메소드는 접근가능하게(public)하게 만든다.
class Modifier {
//멤버필드는 엄격하게 만든다 : pruvate
//메서드는 접근가능하게 만든다. : public
String data1 = "default1";
public String data2 = "public";
protected String data3 = "protected";
private String data4 = "private";
public void viewData() {
System.out.println(this.data1);
System.out.println(this.data2);
System.out.println(this.data3);
System.out.println(this.data4); //메소드를 통해서 data4 호출이 가능하다
}
void method1() { System.out.println("method1"); }
public void method2() { System.out.println("method2"); }
protected void method3() { System.out.println("method3"); }
private void method4() { System.out.println("method4"); }
void method() {
this.method1();
this.method2();
this.method3();
this.method4(); //같은 클래스 내에서는 private 접근제한 호출 가능
}
}
public class Ex111201 {
public static void main(String[] args) {
Modifier m = new Modifier();
System.out.println("***필드 접근제한자***");
System.out.println("-메소드로 필드값 출력");
m.viewData();
System.out.println("\n-필드 바로 출력");
System.out.println(m.data1);
System.out.println(m.data2);
System.out.println(m.data3);
//System.out.println(m.data4); //메소드를 통하지않고 바로 호출하면 접근제한이 걸린다.
System.out.println("\n***메소드 접근제한자***");
System.out.println("-같은 클래스에서 메소드 호출");
m.method();
System.out.println("\n-메인 클래스에서 메소드 호출");
m.method1();
m.method2();
m.method3();
//m.method4(); //method4는 private 접근제한이기때문에 호출 불가
}
}
private인 필드로 접근하려면 아래와 같이 메소드를 이용해서 간접접근 해야한다.
class Modifier {
private String data;
//접근용 메서드 선언
//데이터 읽기용 메서드
public String readData() { return this.data; }
//데이터 쓰기용 메서드
public void writeData(String data) { this.data = data; }
}
public class Ex111202 {
public static void main(String[] args) {
Modifier m = new Modifier();
//필드에 직접 접근방법
//m.data = "테스트";
//System.out.println(m.data);
//필드에 간접 접근방법
m.writeData("테스트");
System.out.println(m.readData());
}
}
하지만 이렇게 매번 읽기, 쓰기 메소드를 개발자가 직접 만들기 힘들기 때문에 자바는 이러한 메소드를 자동적으로
만들어준다.
ㅇGetter와 Setter 메소드
만드는 방법은 읽기전용 메소드는 'get데이터명', 쓰기전용은 'set데이터명' 이다.
이때 데이터명의 첫 글자는 대문자이다.
class Car {
private int speed;
private boolean stop;
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
if(speed<0) {
this.speed = 0;
return;
} else {
this.speed = speed;
}
}
public boolean isStop() {
return stop;
}
public void setStop(boolean stop) {
this.stop = stop;
this.speed = 0;
}
}
public class Ex111203 {
public static void main(String[] args) {
Car myCar = new Car();
//잘못된 속도변경
myCar.setSpeed(-50);
System.out.println("현재속도: "+myCar.getSpeed());
//올바른 속도변경
myCar.setSpeed(60);
System.out.println("현재속도: "+myCar.getSpeed());
//멈춤
if( !myCar.isStop()) {
myCar.setStop(true);
}
System.out.println("현재속도: "+myCar.getSpeed());
}
}
ㅇ패키지
프로젝트 개발시 클래스를 체계적으로 관리하지 않으면 클래스 간의 관계가 뒤엉켜서 복잡하고 난해한 프로그램이 되어간다. 클래스를 체계적으로 관리하기 위해 패키지(package)를 사용한다.
패키지는 클래스를 유일하게 만들어주는 식별자 역할을 한다. 클래스 이름이 동일하더라도 패키지가 다르면 다른 클래스로 인식한다.
클래스의 전체이름은 "패키지명+클래스명" 인데 패키지가 상하위로 구분뒤어 있다면
상위패키지.하위패키지.클래스 로 표현된다.
-패키지 선언하고 컴파일하기
패키지가 없는 클래스는 디폴트 패키지라고 한다. 아래와 같은 PackA 클래스이다.
//패키지가 없는 것을 디폴트 패키지
public class PackA {
public PackA() {
System.out.println("PackA() 호출");
}
}
패키지를 만드려면 아래와 같이 package를 선언한다.
package com;
public class PackB {
public PackB() {
System.out.println("PackB() 호출");
}
}
다음 cmd에서 컴파일한다. 컴파일 방법은 아래와 같다.
javac -d . ClassName.java (현재 폴더 내에 생성)
이때 실제 폴더를 보면 com과 exam이 생긴 것을 알 수 있다.
이제 실행클래스에서 패키지 내에 있는 클래스로 객체를 만들어보자.
패키지를 import하지않으면 원래 주석처리된 부분처럼 사용해야하지만 매번 객체 생성시마다
클래스 앞에 com.을 붙이는 것은 번거롭기 때문에 보통 import 패키지명.클래스명; 을 사용하고
패키지 내에 있는 모든 클래스를 가져올 때는 import 패키지명.*; 을 사용한다.
import com.PackB;
public class PackAEx01 {
public static void main(String[] args) {
PackA a = new PackA();
//com.PackB b = new com.PackB(); //import안했으면 이렇게 사용해야 한다.
PackB b = new PackB();
}
}
패키지를 지정하고 클래스를 만들었는데 컴파일할 때 -d .을 붙이지 않으면 나중에 패키지를 호출해도 호출되지 않는다.
package com.exam;
public class PackD {
public PackD() {
System.out.println("PackD() 호출");
}
}
import com.PackB;
public class PackAEx01 {
public static void main(String[] args) {
com.exam.PackD d = new com.exam.PackD();
}
}
또한 메인클래스에서 패키지를 선언하고 컴파일할 때 -d .하고 실행하려고하면 실행이 되지 않는다.
package exam.com; //실행클래스에 패키지 선언
public class PackEx02 {
public static void main(String[] args) {
System.out.println("hello PackEx02");
}
}
이럴 때는 실행할 때 패키지를 지정해야 한다.
이제 패키지를 다르게 해서 클래스의 접근제한을 확인해보자
package exam01.package1;
class A {} //default 접근제한
package exam01.package1;
public class B{
A a; //A 클래스 접근 가능( 필드로 선언할 수 있음 )
}
package exam01.package2; //패키지가 다름
import exam01.package1.*;
public class C {
//A a; //A클래스 접근 불가 (A클래스 default이기 때문))
B b; //B클래스 접근 가능 (public)
}
C클래스는 패키지가 A, B클래스와 다르므로 접근제한이 default인 A클래스는 접근이 불가능하고
B클래스는 public이므로 다른 패키지에서도 접근이 가능하다.
'데이터 엔지니어링 정복 > JAVA & JSP' 카테고리의 다른 글
[JAVA] 11/16 | String클래스, StringBuffer클래스, Math클래스, 포장(Wrapper)클래스, 문자열 형변환, System클래스, 프로세스, Date와 Calendar클래스 (0) | 2020.11.16 |
---|---|
[JAVA] 11/13 | 기본API, Object클래스, String클래스 (0) | 2020.11.13 |
[JAVA] 11/11 | 생성자오버로딩, 정적초기화블럭, final필드, 상수, 객체배열, 상속, 메소드재정의, 부모메소드 호출, fianl클래스와 메소드 (0) | 2020.11.11 |
[JAVA] 11/10 | 메소드의 매개변수 배열로 받기, 전역변수와 지역변수, 정적멤버 (0) | 2020.11.10 |
[JAVA] 인터페이스 (0) | 2020.11.04 |