instanceof 연산자

Mia Lee·2021년 12월 23일
0

JAVA

목록 보기
79/98
package ex_type_casting;

public class Ex1 {

	public static void main(String[] args) {

		/*
		 * instanceof 연산자
		 * 
		 * < 기본 문법 >
		 * boolean 변수명 = a instanceof B
		 * => a : 객체(참조변수)
		 * => B : 클래스타입
		 */
		
		Parent p = new Parent();
		
		// if문을 사용하여 Parent 객체가 Child 타입으로 변환 가능 여부 판별
		// => p is a Child에 대한 판별 수행
		if (p instanceof Child) {
			// 판별 결과가 true이면 무조건 Child 타입으로 변환 가능
			System.out.println("p -> Child 타입으로 형변환 가능!");
			
		} else {
			// 판별 결과가 false이면 어떠한 변환도 불가능
			System.out.println("p -> Child 타입으로 형변환 불가능!");
			
		}
		
		System.out.println("===================================");
		
		Parent p2 = new Child(); // 업캐스팅
		
		// if문을 사용하여 p2 객체가 Child 타입으로 변환 가능 여부 판별
		if (p2 instanceof Child) {
			// 판별 결과가 true 이면 무조건 Child 타입으로 변환 가능
			System.out.println("p2 -> Child 타입으로 형변환 가능!");
			// => 서브클래스를 이미 업캐스팅 해 놓은 상태이므로 형변환 가능하다는 true 리턴
//			Child c = p2; // 자동형변환은 불가능한 관계
			Child c = (Child) p2; // 강제형변환
			
		} else {
			// false이면 변환 불가능
			System.out.println("p2 -> Child 타입으로 형변환 불가능!");
			
		}
		
		System.out.println("=============================");
		
		// SmartPhone 인스턴스 생성
		SmartPhone 내폰 = new SmartPhone();
		
		// 내폰은 SmartPhone 입니까? true
		if (내폰 instanceof SmartPhone) {
			
			System.out.println("내폰은 SmartPhone 이다!");
			// 그러므로 SmartPhone 타입 변수에 저장 가능
			SmartPhone 동생폰 = 내폰;
			동생폰.call();
			동생폰.sms();
			동생폰.kakaoTalk();
			동생폰.youtube();
			
		} else {
			
			System.out.println("내폰은 SmartPhone 아니다!");
			
		}
		
		System.out.println("=================================");
		
		// 내폰은 HandPhone 입니까?
		if (내폰 instanceof HandPhone) {
			System.out.println("내폰은 HandPhone 이다!");
			System.out.println("그러므로 HandPhone으로 형변환 가능!");
			HandPhone 엄마폰 = 내폰; // 업캐스팅
			엄마폰.call();
			엄마폰.sms();
//			엄마폰.kakaoTalk(); // 오류 발생! 참조영역 축소!
			
		} else {
			System.out.println("내폰은 HandPhone 아니다!");
			
		}
		
		System.out.println("=================================");
		
		HandPhone 엄마폰 = new HandPhone();
		
		// 엄마폰은 SmartPhone 입니까? 
		if (엄마폰 instanceof SmartPhone) {
			
			System.out.println("엄마폰은 SmartPhone 이다!");
			
		} else {
			
			System.out.println("엄마폰은 SmartPhone이 아니다!");
//			SmartPhone 내폰2 = 엄마폰; // 다운캐스팅 필요!
//			SmartPhone 내폰2 = (SmartPhone) 엄마폰; // 실행 시 오류 발생!
			
		}
		
		System.out.println("=================================");
		
		HandPhone 엄마폰2 = new SmartPhone(); // 업캐스팅
		
		if (엄마폰2 instanceof SmartPhone) {
			
			System.out.println("엄마폰2는 SmartPhone 이다!");
//			SmartPhone 내폰2 = 엄마폰2; // 강제형변환 필요
			SmartPhone 내폰2 = (SmartPhone) 엄마폰2;
			내폰2.call();
			내폰2.sms();
			내폰2.kakaoTalk();
			내폰2.youtube();
			
		} else {
			
			System.out.println("엄마폰2는 SmartPhone 아니다!");
			
		}
		
	}

}

class Parent {}

class Child extends Parent {}


class HandPhone {
	
	public void call() {
		System.out.println("HandPhone의 전화 기능!");
		
	}
	
	public void sms() {
		System.out.println("HandPhone의 문자 기능!");
		
	}
	
}

// SmartPhone 클래스 정의 - HandPhone 클래스 상속
class SmartPhone extends HandPhone {
	
	public void kakaoTalk() {
		System.out.println("SmartPhone의 카톡 기능!");
		
	}
	
	public void youtube() {
		System.out.println("SmartPhone의 유튜브 기능!");
		
	}
	
}


연습



package ex_type_casting;

public class Test1 {

	public static void main(String[] args) {

		Employee emp = new Employee("1111", "홍길동", 4000);
		System.out.println("Employee");
		emp.calcSalary();
		
		Manager man = new Manager("2222", "이순신", 5000, "영업팀");
		System.out.println("Manager");
		man.calcSalary();
		
		Engineer eng = new Engineer("3333", "강감찬", 3000, 3);
		System.out.println("Engineer");
		eng.calcSalary();
		
		
		
	}

}

/*
 * 사원(Employee) 클래스
 * 멤버변수 : 사원번호(id, 문자열), 사원이름(name, 문자열), 연봉(salary, 정수)
 * 사원번호, 이름, 연봉을 전달받아 초기화하는 생성자 정의
 * 사원 정보(사원번호, 이름, 연봉)를 문자열로 결합하여 리턴하는 getEmployee() 메서드 정의
 * 
 * 매니저(Manager) 클래스 - Employee 클래스 상속
 * 멤버변수 : 관리부서명(depart, 문자열)
 * 사원번호, 이름, 연봉, 관리부서명을 전달받아 초기화하는 생성자 정의
 * 사원 정보(사원번호, 이름, 연봉, 관리부서명)을 문자열로 결합하여 리턴하는 
 * getEmployee() 메서드 오버라이딩
 * 
 * 엔지니어(Engineer) 클래스 정의 - Employee 클래스 상속
 * 멤버변수 : 자격증 갯수(certCount, 정수)
 * 사원번호, 이름, 연봉, 작겨증 갯수를 전달받아 초기화하는 생성자 정의
 * 사원 정보(사원번호, 이름, 연봉, 자격증 갯수)를 문자열로 결합하여 리턴하는
 * getEmployee() 메서드 오버라이딩
 * 
 */

class Employee {
	String id;
	String name;
	int salary;
	
	// 사원번호와 이름, 연봉을 전달받아 초기화하는 생성자 Employee() 정의
	public Employee(String id, String name, int salary) {
		super();
		this.id = id;
		this.name = name;
		this.salary = salary;
	}
	
	// 사원 전보를 문자열로 결합하여 리턴하는 getEmployee() 메서드 정의
	public String getEmployee() {
		return id + ", " + name + ", " + salary;
		
	}
	
	// 1. 메서드 오버라이딩을 통해 각 클래스에서 따로 연봉 계산할 경우
	// 연봉을 계산하는 calcSalary() 메서드 정의
	public void calcSalary() {
		System.out.println("연봉 : " + salary);
		
	}
	
	// 2. 슈퍼클래스인 Employee 에서 모든 직원 연봉을 다 계산할 경우
	// => 메서드 하나로 Employee, Manager, Engineer 인스턴스를 모두 전달받아야 하므로
	//    업캐스팅 활용
	public void calcSalary(Employee emp) {
		// Employee 타입으로 업캐스팅 할 경우
		// Manager, Engineer 클래스에 선언된 멤버에 접근이 불가능해짐
		// => Employee에서 상속된 공통 멤버에만 접근 가능
		// 따라서 다운캐스팅을 통해 상세 멤버에 접근할 수 있어야 함
		// => instanceof 연산자를 사용하여 Employee, Manger, Engineer 판별
		// 주의사항!
		// instanceof 연산자를 사용하여 형변환 가능 여부 판별 시
		// 슈퍼클래스 타입보다 서브클래스 타입을 먼저 판별!!
		if (emp instanceof Engineer) {
			// 엔지니어의 연봉 계산 => 다운캐스팅 필요
			Engineer e = (Engineer) emp;
			System.out.println("자격증 갯수 : " + e.certCount + "에 따른 연봉 계산");
			// ex) certCount 갯수 * 10만원의 보너스 추가
			System.out.println("엔지니어의 연봉 : " + salary);
			
		} else if (emp instanceof Manager) {
			
		}else if (emp instanceof Employee) {
			
		}
		
	}
	
}

// 매니저 클래스
class Manager extends Employee {
	
	String depart;
	
	public Manager(String id, String name, int salary, String depart) {
		super(id, name, salary); // 슈퍼클래스의 생성자를 호출하여 대신 초기화
		
//		this.id = id;
//		this.name = name;
//		this.salary = salary;
		// => 슈퍼클래스 Employee에 기본 생성자가 없으므로 파라미터 생성자를 명시적으로
		//    호출하지 않으면 오류 발생!
		
		this.depart = depart;
		
	}

	@Override
	public String getEmployee() {
		
		return super.getEmployee() + ", " + depart;
		// => 오버라이딩으로 인해 은닉된 슈퍼클래스의 메서드를 호출하라면
		//    레퍼런스 super를 통해 접근
//		return id + ", " + name + ", " + salary + ", " + depart; // 동일한 문장
		
	}

	// 1. 메서드 오버라이딩을 통해 각 클래스에서 따로 연봉 계산할 경우
	@Override
	public void calcSalary() {
		System.out.println("관리 부서 : " + depart + " 에 따른 연봉 계산");
		// ex) depart 가 "영업팀" 일 경우 보너스 50% 향상 등 수행
		System.out.println("매니저의 연봉 : " + salary);
		
	}
	
}

class Engineer extends Employee {
	
	int certCount;

	public Engineer(String id, String name, int salary, int certCount) {
		super(id, name, salary);
		this.certCount = certCount;
	}

	@Override
	public String getEmployee() {
		return super.getEmployee() + ", " + certCount;
		
	}

	// 1. 메서드 오버라이딩을 통해 각 클래스에서 따로 연봉 계산할 경우
	@Override
	public void calcSalary() {
		System.out.println("자격증 갯수 : " + certCount + "에 따른 연봉 계산");
		// ex) certCount 갯수 * 10만원의 보너스 추가
		System.out.println("엔지니어의 연봉 : " + salary);
		
	}
	
}










0개의 댓글