본문 바로가기

카테고리 없음

Java day6

8. 추상클래스

추상클래스는 new로 인스턴스 생성이 불가하다

추상 메서드를 포함하면 추상 클래스

추상 클래스 안에는 추상 메서드와 구체적으로 구현된(보통의 메서드)메서드 모두 존재

{}가 있으면 코드가 없는 것이지 구현이 안된 건 아니기때문에 추상 메서드가 아님

abstract 키워드가 이쓰면 추상 클래스..

추상 클래스를 상속받은 애들이 구현을 함

package abstractex;

public abstract class Computer {
	
    // 지금 구현할 수 없는 메서드를 추상메서드로 구현한다
	public abstract void display();
	public abstract void typing();
	
	public void turnOn() {
		//구현된 메서드도 있다
		System.out.println("전원을 켭니다");
	}
	public void turnOff() {
		//구현된 메서드도 있다
		System.out.println("전원을 끕니다");
	}

}

추상 메서드를 선언하는 클래스는 추상 클래스여야함

 

상속받은 하위 클래스는 추상 메서드를 모두 구현하지 않으면 추상클래스로 선언해줘야한다

추상클래스는 나를 상속받아서 너네가 구현을 해라.. 고 만든.. 

상속 받은 클래스가 추상 메서드를  모두 구현하지 않으면 추상 클래스가 됨

 

추상 메서드가 포함된 클래스는 구현코드가 없기 때문에  인스턴스화될 수 없음

⁕ 모든 코드가 구현되어있어도 abstract 키워드가 있으면 인스턴스화될 수 없다

 

package abstractex;

public class ComputerTest {
	public static void main(String[] args) {
		
		Computer computer = new MyDesktop();
		Computer computer2 = new Notebook();
		
		computer.typing();
		computer2.display();
		
	}
}

컴퓨터(abstract) - 데스크탑(abstract- 일부 추상 메서드만 구현) -  마이 데스크탑(나머지 구현해서 not abstract)

package abstractex;

public abstract class Desktop extends Computer{

	@Override
	public void display() {
		System.out.println("내 컴퓨터");
		
	}

}
package abstractex;

public class MyDesktop extends Desktop{

	@Override
	public void typing() {
		System.out.println("나머지 메서드 구현");
		
	}

}

컴퓨터(abstract) - 노트북(모두 구현해서 not abstract)

package abstractex;

public class Notebook extends Computer {

	@Override
	public void display() {
		System.out.println("display method in notebook");
		
	}

	@Override
	public void typing() {
		System.out.println("typing method in notebook");
		
	}

}

 

run은 전체적인 시나리오를 담당하는 메서드로 변경되면 안됨

하위 클래스에서 재정의하도록 하면 안됨 -> final키워드 필요

final을 사용하면 하위 클래스애서 메서드를 재정의할 수 없음 

* 클래스에 final키워드를 사용하게 되면 더이상 상속할 수 없는 클래스가 됨

package template;

public class CarTest {

	public static void main(String[] args) {
    
            	Car aicar = new AICar();
		Car manualcar = new ManualCar();

		aicar.run();
		manualcar.run();

	}

}

run을 템플릿 메서드라고 함(전체적 흐름을 정의)

 

final 키워드 

- 변수에 사용하면 값이 변경될 수 없는 상수가 됨

-> 값을 한번만 할당할 수 있음

- 메서드에 사용하면 재정의 불가

- 클래스에 사용하면 상속되지 않음

 


9. 인터페이스 이해하기

인터페이스: 추상 메서드로만 이루어진 클래스 -> 인터페이스는 인스턴스화될 수 없다

인터페이스의 메서드: public abstract

변수: public static final == 상수

 

package interfaceex;

public interface Calc {
	
	// 인터페이스 안에서 변수를 선언하면 public static final이 자동으로 부여됨 -> 상수화
	// 인스턴스 생성시에 생성되는 변수가 아니므로 Calc.ERROR로 접근할 수 있음
	int ERROR = -99999;
	
	// 인터페이스 안에서 메서드를 선언하면 public abstract가 자동으로 부여됨
	int add(int num1, int num2);
	int substracts(int num1, int num2);
	int times(int num1, int num2);
	int divides(int num1, int num2);

}
package interfaceex;

public abstract class Calculator implements Calc{

	@Override
	public int add(int num1, int num2) {
		
		return num1+num2;
		
	}

	@Override
	public int substracts(int num1, int num2) {
		
		return num1-num2;
		
	}

}

->interface는 implement를 사용해서 상속받는다

package interfaceex;

public class CompleteCalculator extends Calculator {

	@Override
	public int times(int num1, int num2) {
		// TODO Auto-generated method stub
		return num1*num2;
	}

	@Override
	public int divides(int num1, int num2) {
		if(num2==0) {
			return Calc.ERROR;
		}
		return num1/num2;
	}

}

-> class는 extends를 사용해서 상속받는다

package interfaceex;

public class CalculatorTest {

	public static void main(String[] args) {

		int num1=10;
		int num2=2;
		
		Calc calculator = new CompleteCalculator();
		System.out.println(calculator.add(num1, num2));
		System.out.println(calculator.substracts(num1, num2));
		System.out.println(calculator.times(num1, num2));
		System.out.println(calculator.divides(num1, num2));
	}

}

 

인터페이스의 기본 요소는 상수와 추상메서드

+ 자바 8 이후 디폴트 메서드, 정적 메서드, 9부터 프라이빗 메서드 추가됨

디폴트 메서드 default

인터페이스 내부에서 디폴드로 선언된 메서드는

인터페이스를 구현한 클래스들이 모두 공유할 수 있는 기본 메서드가 된다

default void description(){}

-> new로 인스턴스를 만든 후에 사용 가능

-> 여러 인터페이스를 매번 구현하는 번거로움 방지

재정의 가능

정적 메서드 static

인스턴스 생성과 관계없이 인터페이스 이름.메서드로 바로 사용 가능

package interfaceex;

public interface Calc {
	
	// 인터페이스 안에서 변수를 선언하면 public static final이 자동으로 부여됨 -> 상수화
	// 인스턴스 생성시에 생성되는 변수가 아니므로 Calc.ERROR로 접근할 수 있음
	int ERROR = -99999;
	
	// 인터페이스 안에서 메서드를 선언하면 public abstract가 자동으로 부여됨
	int add(int num1, int num2);
	int substracts(int num1, int num2);
	int times(int num1, int num2);
	int divides(int num1, int num2);
	
	default void description() {
		
		System.out.println("정수의 사칙연산을 계산합니다");
		
	}
	
	static int total(int[] arr) {
		int total=0;
		for(int num: arr) {
			total+= num;
		}
		return total;
	}

}
package interfaceex;

public class CalculatorTest {

	public static void main(String[] args) {

		int num1=10;
		int num2=2;
		
		Calc calculator = new CompleteCalculator();
		System.out.println(calculator.add(num1, num2));
		System.out.println(calculator.substracts(num1, num2));
		System.out.println(calculator.times(num1, num2));
		System.out.println(calculator.divides(num1, num2));
	
		calculator.description();
		Calc newCalc = new CalcNew();
		newCalc.description();
		
		int[] numbers = new int[] {1,2,3,4,5,6,7,8,9,10};
		
		// 인스턴스의 생성(new)과 관계없이 Calc.으로 바로 사용가능
		int sum = Calc.total(numbers);
		System.out.println(sum);
	}

}

인터페이스 타입으로 사용가능 ?????????

 

 

프라이빗 메서드 private (Java 9)

인터페이스를 구현한 클래스에서 사용하거나 재정의할 수 없음

인터페이스 내부에서만 기능을 제공하기 위해 구현

프라이빗 일반 메서드/ 정적 메서드가 있음 -> 일반은 디폴트에서/ static은 static에서 사용함

 

여러개의 인터페이스를 implements할 수 있다

package interfaceex;

public interface Buyer {

	void buy();
	
	default void order() {
		System.out.println("buyer's order method ");
	}
	
}
package interfaceex;

public interface Seller {
	
	void sell();
	
	default void order() {
		System.out.println("seller's order method");
	}

}
package interfaceex;

public class Customer implements Buyer, Seller {

	@Override
	public void sell() {
	
		System.out.println("customer sells");
		
	}

	@Override
	public void buy() {
		
		System.out.println("customer buys");
		
	}

	@Override
	public void order() {
    
		System.out.println("customer overrides order method");
        
	}
	
}

-> 인터페이스를 2개 이상 구현할 때 인터페이스에 속한 메서드 이름이 중복되면 둘 중 하나를 쓰거나 오버라이딩을 한다

package interfaceex;

public class CustomerTest {

	public static void main(String[] args) {
		
		Customer customer = new Customer();
		
		customer.buy();
		customer.sell(); 
		customer.order(); //customer overrides order method
		
		Buyer buyer = customer;// customer가 Buyer타입에 대입될 수 있음 -> 타입에 바인딩되므로 buy, order 메서드만 호출 가능
		buyer.order(); //메서드는 가상 메서드이므로 customer에서 재정의된 order가 호출됨 -> customer overrides order method
		
		Seller seller = customer;
		seller.order(); //customer overrides order method
	}

}

 

10. 인터페이스 활용

 

인터페이스를 설계한다

인터페이스를 클래스가 implement한다~!

 

고객전화- 스케쥴러(다음 콜을 가져오고, 상담원에게 분배)

구현 방법(정책)- 라운드 로빈/ 리스트잡/ 프라이오리티 얼로케이션

 

클라이언트 측에서는 인터페이스가 중요함(사용방법!)

-> 사용할 때는 어떤 메서드가 사용되는지, 어떤 매개변수가 필요한지만 알면 되기때문에 실질적인 구현 방식은 알 필요가 없음

 

클라이언트 프로그램에 대한 일종의 계약사항을 명시한 스펙이라고 할 수 있음

 

객체는 인터페이스가 제공하는 함수를 구현한 것이고

클라이언트코드는 인터페이스의 정의를 이용해서 사용함 ex. jdbc

 

인터페이스를 사용해서 strategy pattern을 구현할 수 있음

sorting argorithm을 strategy design pattern을 이용해서 구현해보자~

 

Sort 인터페이스를 implement한 bubble, insertion, quick class가 있고 각각 구현함

package sort;

public interface Sort {
	
	void ascending(int[] arr);
	void descending(int[] arr);
	
	default void description() {
		System.out.println("sort description");
	}

}
package sort;

public class BubbleSort implements Sort{

	@Override
	public void ascending(int[] arr) {
		System.out.println("bubble ascending");
		
	}

	@Override
	public void descending(int[] arr) {
		System.out.println("bubble descending");
	}

	@Override
	public void description() {
		// 굳이 super로 불러주지 않아도 오버라이드 가능한 건 알고 있지
		Sort.super.description(); // sort description
		System.out.println("bubble sort description");
	}
	

}
package sort;

import java.io.IOException;

public class SortTest {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		System.out.println("정렬 방식을 선택하세요");
		System.out.println("B: bubble sort");
		System.out.println("Q: quick sort");
		System.out.println("I: insertion sort");
		
		int ch=System.in.read();// 입력값을 받음 -> 예외처리를 해줘야함
		Sort sort = null;
		
		if(ch=='B'|| ch=='b') {			
			sort= new BubbleSort();			
		}
		else if(ch=='Q'|| ch=='q') {			
			sort= new QuickSort();			
		}
		else if(ch=='I'|| ch=='i') {			
			sort= new InsertionSort();			
		}
		else {
			System.out.println("지원하지 않는 기능입니다.");
			return;
		}
		
		int [] myarray = new int[10];
		// 호출 - 입력받는 알팜벳에 따라서 다양한 구현 가능(다형성)
		sort.ascending(myarray);
		sort.descending(myarray);
		
		sort.description();
		
	}

}

JDBC

connection: 자바에서 db에 연결할 때 필요한 객체

인터페이스임

정의되어있는 메서드를 구현하면 사용할 수 있음 -> 우리는 오라클이나 mySQL이 구현해놓은 메서드를 사용

 

인터페이스 구현과 클래스 상속 사용

package bookshelf;

public interface Queue {
	
	void enQueue(String title);
	String deQueue();

}
package bookshelf;

import java.util.ArrayList;

public class Shelf {
	
	protected ArrayList<String> shelf;
	
	public Shelf() {
		shelf=new ArrayList<String>();
	}
	
	public int getCount() {
		return shelf.size();
	}

}

인터페이스 구현 및 클래스 상속

package bookshelf;

public class BookShelf extends Shelf implements Queue{

	@Override
	public void enQueue(String title) {
		shelf.add(title);	
	}

	@Override
	public String deQueue() {
		return shelf.remove(0);//후입선출이면 shelf.size()-1
	}

}
package bookshelf;

public class BookShelfTest {

	public static void main(String[] args) {
		
		Queue bookshelf =  new BookShelf();
		bookshelf.enQueue("책 제목1");
		bookshelf.enQueue("책 제목2");
		bookshelf.enQueue("책 제목3");
		
		System.out.println(bookshelf.deQueue());
		System.out.println(bookshelf.deQueue());
		System.out.println(bookshelf.deQueue());

	}

}

선입 선출이므로 책 제목1->책 제목2->책 제목3 순으로 출력된다