#0316_자바_프로그래밍_교육_4일차
접근 지정자(Access Modifier)
클래스 내 필드나 메서드의 접근 허용 범위를 지정한다.
접근 지정자 | 허용 범위 |
private | 같은 클래스 내에서만 접근 가능 |
없음(default) | 같은 디렉터리 내에서만 접근 가능 |
protected | 상속 관계에서는 어디서든 접근 허용(public) 상속이 아닌 경우 같은 디렉터리 내에서만 접근 허용(default) |
public | 어디서든 접근 허용 |
* 생성자는 접근지정자 지정하지 않으면 클래스의 접근 지정자를 따라간다.
class Parent{
public String publicVar = "public";
protected String protectedVar = "protect";
String var = "default";
private String privateVar = "private";
}
class Child extends Parent{
public void testAccess() {
System.out.println(publicVar); // (O)
System.out.println(protectedVar); // (O) 서로 다른 패키지이지만 상속관계이기때문에 접근 가능
System.out.println(var); // (X) The field Prarent.var is not visible.
System.out.println(privateVar); // (X) The field Prarent.privateVar is not visible.
}
}
상속(Inheritance)
다양한 서브(자식) 클래스들을 슈퍼(부모) 클래스에서 단일하게 관리하기 위해 사용한다. 동일한 부모 클래스를 상속받는 경우 자식 클래스들을 하나의 배열로 묶을 수 있다. 이러한 배열을 Heterogeneous Collection 라고도 한다.
다형성(Polymorphism)
부모 타입으로 다양한 객체를 생성하는 것이다.
class Child extends Parent{...}
// 부모 타입으로 지정 후 자식 생성자 호출
Child child = new Child();
Parent child = new Child();
다형성을 활용해 부모 타입으로 자식 객체 생성 시 주의해야할 점이 있다.
//부모 클래스
public class Parent{
private String p1;
private int p2;
public void parentMethod(){
...
}
}
//자식 클래스
public class Child extends Parent{
private String c1;
@Overriding
public void parentMethod(){
...
}
public void childMethod(){
...
}
}
위에 부모 클래스와 이를 상속받은 자식 클래스가 존재한다. 자식 클래스에서는 부모 클래스의 메서드를 오버라이딩한다. (코드에서 생성자는 생략함)
Parent obj = new Child();
obj.parentMethod(); // (O)
obj.childMethod(); // (X) The method childMethod() is undefined for the type Parent.
({필요한_클래스}) {형변환_대상_클래스}
Child obj2 = (Child) obj;
obj.childMethod();
// 또는
((Child)obj).childMethod();
public void childMethod(){
String s = super.p1; // Parent.p1
}
부모 타입과 자식 타입이 상속관계가 맞는지 확인하는 키워드는 instanceOf 이다.
A instanceOf B
A가 B에 속하거나 A가 B를 상속받는 경우 true를 리턴하고 아니면 false를 리턴한다.
Polymorphic Argument 부모 타입의 인자값을 hasing 함으로써 다양한 자식 클래스들을 단일하게 관리할 수 있다.
Static 키워드
static은 고정된 이라는 의미를 갖고 있다. 해당 키워드를 사용하여 만든 변수를 정적 변수(멤버) 또는 전역 변수라고도 한다.
class Example {
int count=1;
// #1 (O) 필드 레벨에서 static 사용 가능
static String name = "홍길동"; //static 변수 또는 class 변수라 한다.
static int age = 19;
public void method1() {
static String address = "민속촌"; // (X) 로컬 레벨(메서드 내 변수)에서 static 사용 불가
}
public static void method2() {
count++; // #2 (X) static 메서드 내에서 로컬 변수 사용 불가
}
}
// 필드 접근
public static void main(String[] args) {
Example.method2(); // #3 (O) static 필드 바로 사용 가능
Example.name; // (O)
Example e = new Example();
e.count; // #4 (O) static 아닌 필드 변수 생성 후 사용 가능
e.method1(); // O)
}
static의 동작 과정과 메모리 구조는 아래와 같다.
class Obj {
int num; // field
static int counter; // 필드, static 변수 둘 다 기본값 0으로 초기화
Obj() { // 생성자 - 카운터 증가 후 num에 저장
counter ++;
num = counter;
}
}
먼저 필드로 num과 static 변수인 counter를 지닌 클래스 Obj가 있다.
Obj obj1 = new Obj();
Obj obj2 = new Obj();
Obj obj3 = new Obj();
객체 Obj 3개를 생성했다.
System.out.println("obj1 "+obj1.num); //1
System.out.println("obj2 "+obj2.num); //2
System.out.println("obj3 "+obj3.num); //3
System.out.println("obj1 "+obj1.counter); //3
System.out.println("obj2 "+obj2.counter); //3
System.out.println("obj3 "+obj3.counter); //3
System.out.println("Obj "+Obj.counter); //3
final 키워드는 고정된 값을 지정하고자할 때 사용된다. 변수와 메서드, 클래스 모두에서 사용 가능한 키워드이다.
** 객체 생성 과정 생략을 위해 static을 남발해서는 절대 안된다!
static 지정 변수는 Heap이 아닌 Class Area 라는 JVM 내 다른 공간에 올라간다. Heap은 GC의 동작 대상인 반면 static 변수가 올라가는 Class Area는 대상이 아니다. static 변수 남발 시 메모리 해제가 되지 않고 곧 퍼포먼스 저하를 일으킨다.
(Heap에는 new 키워드를 통해 생성된 객체나 생성 후 참조가 끊어진 객체들이 있으며 GC(Garbage Collector)의 대상이다.)
싱글톤 패턴(SingleTone Pattern)
하나의 클래스 타입으로 오직 단 하나의 인스턴스만 생성되도록 코드를 강제하는 패턴이다.
객체 지향적인 자바 특성과는 다소 반대되는 개념이나 서비스단에서 사용, 요청에 대한 매핑을 메서드가 하도록하여 서버의 과부하를 방지한다.
메서드 하나가 서비스 하나 즉, 클래스가 아닌 메서드가 서비스의 단위가 되어야한다. 서비스 클래스는 1개여야하며 요청이 아무리 많아도 서비스 객체는 여전히 1개여야한다. 서비스 클래스 하나만 메모리에 올리고 서비스 메서드가 각 요청에 대한 비즈니스 로직을 처리하도록 한다.
하나의 클래스로부터 단 한 개의 인스턴스만 생성하는 패턴이다. 코드 작성 순서는 아래와 같다.
1. 일단 클래스 안에서 싱글톤 패턴을 적용시킬(생성할) 하나의 객체는 생성한다. > private static으로 지정한다.
private static XXService service = new XXService();
2. 다른 곳(클래스)에서는 해당 클래스 타입으로 객체 생성을 못하도록 막는다. > 생성자를 private로 지정하여 접근하지 못하게 한다.
private XXService() {};
3. 1번에서 하나 생성해둔 객체는 여기저기서 불러다 쓸 수 있도록(주입받을 수 있도록) public 메서드를 하나 만든다.
여기서 중요한 점은 객체 생성을 막아두었음으로 객체 생성 없이 쓸 수 있도록 static으로 지정한다.
public static XXService getInstance() {
return service;
}
4. 해당 객체를 사용할 곳에서 주입을 위한 메서드를 호출한다. static으로 지정했기에 변수 생성(new)없이 호출할 수 있다.
XXServcie.getInstance();
XXService s1 = XXService.getInstance();
XXService s2 = XXService.getInstance();
XXService s3 = XXService.getInstance();
System.out.println(s1); // XXService@626b2d4a
System.out.println(s2); // XXService@626b2d4a
System.out.println(s3); // XXService@626b2d4a 모두 같은 주소값
Service 클래스의 기능들은 클라이언트가 요청하는 각각의 서비스를 수행하는 것들이다. 요청 당 서비스 클래스가 매핑되는 것이 아니라 서비스 클래스의 기능(메서드) 하나가 완벽하게 매핑되는 구조이다. 서비스 클래스는 아무리 요청이 많이 들어와도 무조건 하나만 서버상에 생성되고 하나의 객체 안의 기능들이 요청을 처리하는 완벽한 단위가 되어야한다.
* 스프링 DAO의 경우 서버에서 디폴트로 싱글톤으로 동작하도록 설정되어있다고 하는데 이는 더 알아봐야겠다.
** field | static variable | local variable
지정자(Modifiler)
JAVA 버전 8, 11, 17 차이 알아보기 (JDK, JRE, JVM과 버전 명명법) (0) | 2024.06.22 |
---|---|
[JAVA] 자바 프로그래밍 교육 5일차(과 후기) (0) | 2023.03.27 |
[JAVA] 자바 프로그래밍 교육 3일차 (0) | 2023.03.27 |
[JAVA] 자바 프로그래밍 교육 2일차 (0) | 2023.03.27 |
[JAVA] 자바 프로그래밍 교육 1일차 (0) | 2023.03.13 |
댓글 영역