organize/자바

Java 11

001cloudid 2024. 4. 23. 20:50
728x90

제어자(modifier)

클래스와 클래스의 멤버(멤버 변수, 메서드)에 부가적인 의미를 부여
하나의 대상에 여러 제어자를 같이 사용가능(접근 제어자는 하나만) 접근 제어자를 가장 먼저 사용하는 경향이 있음
종류
접근 제어자 : public protected, (default), private => 4개 중 1개만
그     외 : static, final, abstract, native, transient, synchronized, volatile, strictfp

static - 클래스의, 공통적인
멤버 변수 : 모든 인스턴스에 공통적으로 사용되는 클래스 변수가 됨, 클래스 변수는 인스턴스를 생성하지 않고도 사용 가능, 클래스가 메모리에 로드될 때 생성
메서드 : 인스턴스를 생성하지 않고도 호출이 가능한 static 메서드가 됨, static메서드 내에서는 인스턴스 멤버들을 직접 사용할 수 없음

final - 마지막의, 변경될 수 없는
클래스 : 변경될 수 없는 클래스, 확장될 수 없는 클래스가 됨. final로 지정된 클래스는 다른 클래스의 부모(조상)이 될 수 없음. 상속계층도에 가장 아래에 있음. String, Math
메서드 : 변경될 수 없는 메서드, final로 지정된 메서드는 오버라이딩을 통해 재정의 불가
멤버변수, 지역변수 : 변수 앞에 final이 붙으면, 값을 변경할 수 없는 상수가 됨

abstract - 추상의, 미완성의
추상 클래스를 상속받아서 완전한 클래스(구상 클래스)를 만든 후 객체 생성 가능
클래스 : 클래스 내에 추상 메서드가 선언되어 있음을 의미. 추상메서드를 가지고 있다면 추상 클래스. 인스턴스 생성불가
메서드 : 선언부만 작성하고 구현부는 작성하지 않은 추상 메서드임을 알림

 

package chapter07;

class ParentS9E1{
	private int privateVariable; 	//같은 클래스
	int defaultVariable; 			//같은 패키지
	protected int protectedVariable;//같은 패키지 + 자손(다른 패키지)
	public int publicVariable;		//접근제한이 없음
	
	public void printMembers() {
		System.out.println(privateVariable);
		System.out.println(defaultVariable);
		System.out.println(protectedVariable);
		System.out.println(publicVariable);
	}

}

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

		ParentS9E1 parentS9E1 = new ParentS9E1();
//		System.out.println(parentS9E1.privateVariable); //에러. 접근 범위가 안맞음
		System.out.println(parentS9E1.defaultVariable);
		System.out.println(parentS9E1.protectedVariable);
		System.out.println(parentS9E1.publicVariable);
		
		
		
	}

}

 

package chapter07;

class ChildS9E1 extends ParentS9E1{

	public void printMembers() {
//		System.out.println(privateVariable); //에러
		System.out.println(defaultVariable);
		System.out.println(protectedVariable);
		System.out.println(publicVariable);
	}
	
	//만약 다른 패키지에 있는 클래스는
//	public void printMembers() {
//		System.out.println(privateVariable); //에러
//		System.out.println(defaultVariable); //에러
//		System.out.println(protectedVariable);
//		System.out.println(publicVariable);
//	}
	
}

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

	}

}

 

캡슐화

캡슐화와 접근 제어자
접근 제어자를 사용하는 이유 => 외부로부터 데이터를 보호하기 위해서(Study10Ex1)
외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해(접근 제어자 범위는 좁을 수록 좋음 필요하면 넓히는 것으로 해야함)

 

package chapter07;

class Time{
	//접근 제어자를 private으로 하여 외부에서 직접 접근하지 못하도록 함
	private int hour;
	private int minute;
	private int second;
	
	//메서드를 통해서 iv에 접근. 메서드를 통해 간접 접근 허용 
	public int getHour() {
		return hour;
	}
	
	public void setHour(int hour) {
		if(isNotValidHour(hour)) {
			return;
		}
		this.hour = hour;
	}

	//매개변수로 넘겨지 hour가 유효한지 확인해서 알려주는 메서드
	private boolean isNotValidHour(int hour) {
		return hour < 0 || hour >24;
	}
	
}

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

		Time time = new Time();
//		time.hour = -1;
		time.setHour(21); //hour의 값을 21로 변경
		System.out.println(time.getHour());
		time.setHour(100);
		System.out.println(time.getHour());
		
	}
	
}

 

다형성(polymorphism)

여러 가지 형태를 가질 수 있는 능력
조상 타입 참조 변수로 자손 타입 객체를 다루는 것

객체와 참조변수의 타입이 일치할 때와 일치하지 않을 때 차이?
SmartTV sTV = new SmartTV(); //참조 변수와 인스턴스의 타입이 일치 => 모든 기능 사용 가능
TV tv = new SmartTV(); //조상 타입 참조변수로 자손 타입 인스턴스 참조 => TV 기능만 사용 가능

자손 타입의 참조변수로 조상 타입의 객체를 가리킬 수 없음
TV tv = new SmartTV(); //허용
SmartTV sTV = new TV(); //에러. 허용안됨. 없는 기능을 호출해서 에러가 발생

 

package chapter07;

class TVS11E1{
	boolean power; //전원상태
	int channel;
	
	void power() {
		power = !power;
	}
	void channelUp() {
		++channel;
	}
	void channelDown() {
		--channel;
	}
}

class SmartTVS11E1 extends TVS11E1{
	String text; //자막을 보여주기 위한 문자열
	void caption() {
		//구현부
	}
}


public class Study11Ex1 {

	public static void main(String[] args) {

		//타입이 일치
		TVS11E1 tvs11e1 = new TVS11E1();
		SmartTVS11E1 smartTVS11E1 = new SmartTVS11E1();
		
		//타입 불일치
		TVS11E1 t = new SmartTVS11E1();
		
	}
	
}

 

참조변수의 타입은 인스턴스의 타입과 반드시 일치해야하는가? => 보틍은 일치하지만 일치하지 않을 수도 있음(다형성)
참조변수가 조상타입일 때와 자손타입일 때의 차이는? => 참조변수로 사용할 수 있는 멤버의 개수가 달라짐
자손타입의 참조변수로 조상타입의 객체를 가리킬 수 있을까? => ㄴㄴ. 자손 기능이 더 많기 때문에 허용되지 않음

 

참조변수의 형 변환

기본형 형변환의 경우 값이 바뀌며, 참조변수의 형 변환은 사용할 수 있는 멤버의 갯수를 조절하는 것 
조상-자손 관계의 참조변수는 서로 형 변환 가능(Study12Ex1)

 

package chapter07;

class CarS12E1{
	String color;
	int door;
	
	void drive() {
		System.out.println("운전하는 기능");
	}
	
	void stop() {
		System.out.println("정지하는 기능");
	}
}

//		자식					부모
class FireTruckS12E1 extends CarS12E1{
	void water() {
		System.out.println("물을 뿌리는 기능");
	}
}

class AmbulanceS12E1 extends CarS12E1{
	void siren() {
		System.out.println("사이렌 울리는 기능");
	}
}

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

		FireTruckS12E1 fireTruck = new FireTruckS12E1();
		CarS12E1 car = (CarS12E1)fireTruck; //조상(부모) 타입으로 형변환(생략 가능)
		FireTruckS12E1 fireTruck2 = (FireTruckS12E1)car; //자손(자식) 타입으로 형변환(생략 불가)
//		AmbulanceS12E1 ambulance = (AmbulanceS12E1)fireTruck; //상속관계가 아닌 클래스 간의 형변환 불가
		
		
	}

}

 

instanceof 연산자

참조변수의 형변환 가능여부(조상-자손) 확인에 사용. 가능하면 true 반환
형변환 확인 -> 형변환(instanceof 연산자 사용)
형변환 전 반드시 instanceof로 확인해야함

 

package chapter07;

class CarS13E1{
	String color;
	String type;
	
	void start() {
		System.out.println("시동을 거는 기능");
	}
	
	void stop() {
		System.out.println("시동을 멈추는 기능");
	}
}

class FireEngineS13E1 extends CarS13E1{
	void water() {
		System.out.println("물을 뿌리는 기능");
	}
}

public class Study13Ex1 {

	public static void main(String[] args) {
		
		CarS13E1 car = new CarS13E1();
		FireEngineS13E1 fe = new FireEngineS13E1();
		System.out.println(fe instanceof CarS13E1);
		System.out.println(fe instanceof FireEngineS13E1);

	}

}

 

참조변수의 형변환은 왜함? => 참조변수를 변경함으로써 사용할 수 있는 맴버의 개수를 조절하기 위해서
instanceof 연산자는 언제 사용? => 참조변수를 형변환하기 전에 형변환 가능 여부를 확인할 때

728x90

'organize > 자바' 카테고리의 다른 글

Java 13  (0) 2024.04.25
Java 12  (0) 2024.04.24
Java 10  (0) 2024.04.22
Java 9  (0) 2024.04.21
자바 처음부터 다시 시작하기 8  (1) 2024.04.20