본문 바로가기

웹_프론트_백엔드/JAVA

2020.08.11(JAVA_심화반)

1. 대표적인 IDE

 : 우리나라에서는 최근에 인텔리J 사용률이 많이 상승되었으나 아직까지는 이클립스를 많이 사용한다.

   Why? 아무래도 인텔리J 사용은 유료이고

           기존에 이클립스로 작업했던 프로젝트를 유지보수나 이어서 하기 때문이다.

 

** 2020년도 개발자 에코시스템의 현황 - Java

   https://www.jetbrains.com/ko-kr/lp/devecosystem-2020/java/

 

 

2. Java2 심화반에서는 이클립스 Photon 버전으로 수업 진행

 

 

3. The selection cannot be launched, and there are no recent launches. 에러

 : Window > Preferences 창 클릭

   > Run/Debug > Launching 선택, Launch Operation > Launch the associated project 선택



4. Casting
 : 메모리상으로, 부모 필드는 자식 필드보다 작다.
   따라서 부모 타입에 자식 값이 들어가게 되면 새롭게 추가된 필드가 잘려서 들어간다.
   하지만 재정의된 메소드는 그대로 덮어 쓰기 때문에 재정의된 기능으로 사용된다.
   만약 잘려나간 필드(자식에서 추가된 필드)를 다시 복구하고 싶다면,
   자식 타입에 up casting된 객체를 다시 넣어준다.
   다만 up casting된 객체의 타입은 부모 타입이므로 자식 타입으로 강제 형변환 후
   넣어주어야 한다.

1) up casting
 : 부모 타입에 자식 값을 넣는 기법(즉, 짤림)


2) down casting
 : up casting된 객체를 다시 자식 타입에 넣는 기법(즉, 복원)

[주의] 만약 자식 타입에 부모 값을 넣는 것은 오류(casting exception)이다.
         반드시 up casting된 객체를 자식 타입에 넣어주어야 한다.


** Casting을 사용하는 이유?
 : 다양한 자식들을 하나의 타입으로 묶은 후 필요한 필드가 있다면,
   down casting을 통해 복수하여 사용하기 위함

 

사용 예1)

 

 

사용 예2)

   Bank arBank = { new 우리(), new 국민(), new 신한() }

 

 

5. 객체 타입 비교
   객체명 instanceof 타입명 : 참 또는 거짓의 값
   객체가 해당 타입이면 참, 아니면 거짓

 

 

6. Casting, 객체타입비교 예제

package com.lec.java.casting;

class Car {
	String brand;
	String color;
	int price;
	
	// 기본생성자 만드는 단축키 : Ctrl + SpaceBar
	public Car() {}

	// 생성자 만드는 단축키 : Alt + Shift + S + O
	public Car(String brand, String color, int price) {
		super();
		this.brand = brand;
		this.color = color;
		this.price = price;
	}
	
	public void engineStart() {
		System.out.println("열쇠로 시동 킴");
	}
	
	public void engineStop() {
		System.out.println("열쇠로 시동 끔");
	}
	
} // end class Car

class SuperCar extends Car {
	String mode;
	
	public SuperCar() {}

	public SuperCar(String mode) {
		super();
		this.mode = mode;
	}
	
	@Override
	public void engineStart() {
		super.engineStart();	// 부모 클래스의 메소드 호출 
		System.out.println("음성으로 시동 킴");
	}
	
	@Override
	public void engineStop() {
		// 부모 클래스의 메소드 호출없이 재정의
		System.out.println("음성으로 시동 끔");
	}
	
	public void openRoof() {
		System.out.println("지붕 열기");
	}
	
} // end class SuperCar

public class CastingTest {
	public static void main(String[] args) {
		// Car(부모), SuperCar(자식)
		Car matiz = new Car();
		SuperCar ferrari = new SuperCar();
		
		// up casting
		Car noOptionFerrari = new SuperCar();
		
		// 자식 타입에 부모 값을 넣는 것은 오류(java.lang.ClassCastException)이다. 
		// 반드시 up casting된 객체를 자식 타입에 넣어주어야 한다.
		// 이때..! 컴파일상 오류가 나지 않고 빌드시에 오류 발생
		//SuperCar brokenCar = (SuperCar) new Car();
		
		//down casting
		SuperCar fullOptionFerrari = (SuperCar) noOptionFerrari;
		
		//★★★★★모든 자식은 부모 타입이다.★★★★★
		System.out.println(ferrari instanceof Car);
		System.out.println(ferrari instanceof SuperCar);
		System.out.println(ferrari instanceof Object);

		noOptionFerrari.engineStart();
		fullOptionFerrari.openRoof();
		
	} // end main()
	
} // end class CastingTest

 


7. 추상클래스(불안전한 클래스)
 : 클래스 안에 추상적인 필드가 있는 클래스를 추상클래스라 하고,
   구현되지 않은 메소드가 바로 추상적인 필드이다.
   이러한 미구현된 메소드를 추상 메소드라 하고,
   선언시 바디(중괄호)가 없는 채로 선언한다.

** 추상메소드 선언시 리턴타입 앞에 abstract 키워드를 작성해 주어야 한다.
   구현되지 않은 메소드는 바디가 없고, 구현이 안되었기 때문에 메모리에 할당할 수 없다.
   따라서 추상클래스를 상속받은 자식 클래스들은 반드시 구현(재정의)해야 한다.
   즉, 강제성을 부여하기 위해 사용한다.

   예) abstract 리턴타입 메소드명(자료형 매개변수,....);

 


8.  추상클래스 사용 예시
 : A회사의 가전 제품들은 전원on, 전원off 메소드가 반드시 필요하다.

   그렇기 때문에...!

   현재 A회사에서 판매되고 있는 가전 제품들(냉장고, TV, 세탁기)은 모두 전원on, 전원off 메소드가 있다.

   그러던 어느 날...!

   기존 개발자가 퇴사하고 새로운 개발자가 출근했다.

   출근과 동시에 A회사의 신제품..!!

   밥솥이 개발하는 업무를 맡게 되었다.
   이럴수가..!! 큰일났다..!!

   새로운 개발자는 신제품 밥솥에 전원on, 전원off 메소드를 깜빡하는 대형사고를 저질렀다.

   이런 대형 사고가 발생하는 것을 방지하기 위해서...!

   추상 클래스를 사용한다(즉, 강제성 부여).

 


9. 추상클래스 선언

 : 추상클래스는 클래스이기 때문에 일반 메소드도 선언 가능


   abstract class 추상클래스명 {
       // 추상 메소드
       abstract 리턴타입 메소드명(자료형 매개변수, ...... );
   
       // 일반 메소드
       리턴타입 메소드명(자료형 매개변수, ... ) {
       
       }
   }

 

 

10. 추상클래스에서 사용 가능한 3가지 메소드
    ① 추상메소드 : 반드시 재정의 필요
    ② 일반메소드 : 재정의 선택사항
    ③ final로 지정된 메소드 : 재정의 절대 불가능

 

 

11. 추상클래스 예시

** com.lec.java.abstractClass > Shape 추상클래스

package com.lec.java.abstractClass;

public abstract class Shape {
	double area;
	
	// 1) 추상메소드 : 반드시 재정의해...!
	abstract void getArea(double w, double h);
	
	// 2) 일반메소드 : 재정의 하고싶으면 하고 하기 싫으면 하지마...!
	//              너가 하고 싶은대로 해..!!
	public void f() {
		System.out.println("추상 클래스의 일반 메소드");
	}
	
	// 3) final로 지정된 메소드 : 재정의 절대 안돼...!
	public final void intro() {
		System.out.println("도형입니다.");
	}

}

 

** com.lec.java.abstractClass > Tri.java

package com.lec.java.abstractClass;

public class Tri extends Shape {

	@Override
	void getArea(double w, double h) {
		area = w * h / 2;
		//ㅊ + 한자키 : 제곱 첨자 문자 찾기
		System.out.println(area + "cm²");
	}
	
	@Override
	public void f() {
		System.out.println("세모입니다.");
	}

} // end class

 

[추상클래스 Shape에서 추상메소드 예시] 반드시 재정의 필요

[추상클래스 Shape에서 일반메소드 예시] 재정의는 선택사항

[추상클래스 Shape에서 final로 지정된 메소드] 재정의 절대 불가



12. 인터페이스(틀), "인터페이스도 타입이다"
 : 추상클래스를 고도화시킨 문법

   다양한 클래스에서 중복하여 선언되는 메소드를 인터페이스에 
   미리 선언해 놓고 지정한 클래스에서 구현하는 방식으로 사용한다.
   반드시 추상메소드만 선언해야 하고, 상수만 선언 가능하다.

 


13. 인터페이스 선언
   interface 인터페이스명 {
       상수, 추상메소드 선언
   }

 

14. 클래스에서 인터페이스를 지정받을때 extends를 사용하지 않고 inplements를 사용한다.
   ex) class A implements B_interface{}

 

 

15. 인터페이스 사용 예제

** com.lec.java.interfaceAdapter > Animal 인터페이스

package com.lec.java.interfaceAdapter;

// 인터페이스에서는 상수랑 추상메소드만 가능
public interface Animal {
	// 상수
	int leg = 4;			// 인터페이스에서는 final static 생략 가능
	final static int eye = 2;
	
	// 추상메소드
	void eat(String feed);	// 인터페이스에서는 abstract 생략 가능
	abstract void sleep();
	void walk();
}

 

** com.lec.java.interfaceAdapter > Dog.java

package com.lec.java.interfaceAdapter;

public class Dog implements Animal {

	@Override
	public void eat(String feed) {
		System.out.println(feed + "냠냠");
	}

	@Override
	public void sleep() {
		System.out.println("쿨쿨");
	}

	@Override
	public void walk() {
		System.out.println("아이 신나~");
	}

}

 

 

16. 인터페이스에 선언된 메소드를 모두 구현하고 싶지 않을 때에는
   추상클래스에 먼저 지정한 후 바디를 만들어 준다.
   바디가 생긴 추상 클래스를 상속받으면 이제 골라서 재정의할 수 있게 된다.
   따라서 안드로이드 어플 개발, 자바 GUI 개발 등에서 자주 사용되는 설계 방식이다.
   즉, 틀만 제공하고 구현은 사용자가 하며, 모두 구현할 때에는 인터페이스를,
   일부만 구현하고 싶을때는 추상 클래스를 지정 및 상속하여 사용한다.

 

17. Adapter 예제

 : Pig를 만들어보자...!!

   [주의] 인터페이스 예제를 통해 Dog를 만들었는데 Pig는 Dog와는 달리 산책하지 않는다..!! > 반영해서 만들어라...!!

 

1) Animal 인터페이스를 이용해보자...!!

   [결론] 오류난다

            Why? 인터페이스에 선언했던 추상메소드를 모두 재정의해줘야하는데

                    돼지는 산책을 안하기 때문에 walk() 메소드를 삭제했고 그로 인해 오류가 났다.

 

2) 그럼 어떻게 해야 오류를 해결할 수 있을지 고민해보자...!!

   [해결책] 인터페이스에 선언된 메소드를 모두 구현하고 싶지 않을 때에는
              Adapter를 이용, 추상클래스에 먼저 지정한 후 바디를 만들어 준다.

 

** com.lec.java.interfaceAdapter > AnimalAdapter 추상클래스

package com.lec.java.interfaceAdapter;

public abstract class AnimalAdapter implements Animal {

	@Override
	public void eat(String feed) {}

	@Override
	public void sleep() {}

	@Override
	public void walk() {}

}

 

** com.lec.java.interfaceAdapter > Pig.java

package com.lec.java.interfaceAdapter;

public class Pig extends AnimalAdapter{
	
	public static void main(String[] args) {
		System.out.println(new AnimalAdapter() {} instanceof Animal);
	} // end main()
	
	@Override
	public void eat(String feed) {
		// TODO Auto-generated method stub
	} // end eat()

	@Override
	public void sleep() {
		// TODO Auto-generated method stub
	} // end sleep()

} // end class

 

 

18. 다음 수업 내용 : 마커 인터페이스, 내부 클래스, 익명 클래스, GUI

'웹_프론트_백엔드 > JAVA' 카테고리의 다른 글

2020.08.27(JAVA_심화반)  (0) 2020.08.28
2020.08.25(JAVA_심화반)  (0) 2020.08.25
2020.02.25  (0) 2020.02.26
2020.02.24  (0) 2020.02.25
2020.02.21  (0) 2020.02.22