관리 메뉴

거니의 velog

230726 자바 강의 본문

대덕인재개발원_Java

230726 자바 강의

Unlimited00 2023. 7. 26. 18:08

[인터페이스]

(1) 정적 변수

(2) 추상 메서드만 있음. 몸통이 없으므로 객체 생성 불가

(3) public abstract

(4) 추상 메서드가 하나 이상 추가된 것이 추상 클래스. new 연산자의 대상이 아니다.  
    완성되지 않은 추상 메서드가 있기 때문.

(5) 인터페이스를 부모 타입으로 해서 다형성 구현.


[JDBCUtil.java]

package ddit.chap07.sec03;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

	public class JDBCUtil {

		// 싱글톤 패턴 예제
		private static JDBCUtil instance = null;
		private JDBCUtil() {}
		public static JDBCUtil getInstance() {
			if(instance==null) instance = new JDBCUtil();
			return instance;
		}
		
		// thin = ojdbc.java 파일 연동. 범용이라 안정적이지만 느리다. 전용을 쓰면 빠르나 범용성이 없음.
		// localhost : 127.0.0.1
		// 가상 주소 값. ipconfig
		// :1521. 컴퓨터에 오라클이 설치 되었을 때 오라클을 구별하는 논리적으로 배정되어진 포트 번호.
		// :xe. sqldeveloper에 계정 등록할 때 제일 밑에 sid 값이 기술됨. express edition의 약자. 
		// :orcl. 정식 버전.
		private String url = "jdbc:oracle:thin:@localhost:1521:xe"; 
		private String user = "pc_21";
		private String password = "java";
		
		private Connection conn = null; // 연결 객체. ojdbc에서 제공 되는 DriverManager.getConnection() 매개변수로 url, user, password을 쓰면 이것을 가지고 접속을 시도.
		private Statement stmt = null; // 동적 쿼리 변환 // 정적 쿼리. 이미 조건을 다 제시해서 설정한 쿼리.
		private PreparedStatement pstmt = null; // 정적 쿼리 변환 // 동적 쿼리. 사용자로부터 입력 받은 값으로 변경되는 쿼리.
		private ResultSet rs = null; // select 문에서 뷰(가상 테이블)을 반환하여 ResultSet에 저장.
		
		public List<Map<String, Object>> selectlist(String sql, List<Object> param) {
			
			List<Map<String, Object>> list = null;
			
			try {
				conn = DriverManager.getConnection(url, user, password);
				pstmt = conn.prepareStatement(sql); // 연결 객체를 명령어 객체로 변환.
				for(int i=0; i<param.size(); i++) {
					pstmt.setObject(i+1, param.get(i));
				}
				rs = pstmt.executeQuery(); // executeQuery(sql). select 문장만 실행하는 메서드.
				/*
				 * MEM_ID, MEM_PASS, MEM_NAME, MEM_REGNO1, MEM_REGNO2, MEM_BIR, MEM_ZIP, MEM_ADD1, MEM_ADD2, MEM_HOMETEL, MEM_COMTEL, MEM_HP, MEM_MAIL, MEM_JOB, MEM_LIKE, MEM_MEMORIAL, MEM_MEMORIALDAY, MEM_MILEAGE, MEM_DELETE
				 */
				ResultSetMetaData rsmd = rs.getMetaData();
				int columnCount = rsmd.getColumnCount();
				
				while(rs.next()) {
					// <> 제너릭. 컬렉션 프레임 워크는 그 안에 들어가는 자료가 클래스 타입이어야 한다. 클래스 이외의 것은 들어갈 수 없다. 객체만 들어감.
					// 객체만 넣으면 뽑아 쓸 때가 문제. 어떤 것인지 알 수 없기 때문.
					// 그래서 그 안에 들어가는 데이터를 제한한다. 다운 캐스팅이 필요 없어짐.
					Map<String, Object> row = new HashMap<>(); 
					for(int i=0; i<columnCount; i++) {
						String key = rsmd.getColumnLabel(i+1);
						Object value = rs.getObject(i);
						row.put(key, value);
					}
					list.add(row);
				}
			}catch(SQLException e) {
				e.printStackTrace(); // jvm의 call stack메모리에 담긴 오류 메시지 출력.
			}finally {
				if(rs != null) try {rs.close();} catch(Exception e) {} // 예외 클래스의 조상 클래스는 Exception
				if(stmt != null) try {stmt.close();} catch(Exception e) {}
				if(conn != null) try {conn.close();} catch(Exception e) {} // 연 순서의 반대 순서로 차례대로 닫는다.
			}
			return list;
		}
	
}

[DBTestExample.java]

package ddit.chap07.sec03;

import java.util.ArrayList;
import java.util.List;

public class DBTestExample {

	public static void main(String[] args) {
		
		JDBCUtil jdbc = JDBCUtil.getInstance();
		
		String sql = "SELECT MEM_ID, MEM_NAME, MEM_REGNO1, MEM_REGNO2, MEM_HP, MEM_MILEAGE ";
		sql += "FROM MEMBER WHERE MEM_ID = ? "; // 동적 쿼리.
//		sql += "FROM MEMBER WHERE MEM_ID >= 'c001' ";
//		sql += "FROM MEMBER WHERE MEM_REGNO1 LIKE '0%' "; // 2000년대 이후 출생자.
//		sql += "FROM MEMBER WHERE SUBSTR(MEM_ADD1, 1, 2) ";
		
//		List<Object> list = new ArrayList();
//		list.get(1); // 컬럼의 인덱스 값으로 반환
		
//		jdbc.selectlist(sql, list);
		
		test();

	}
	
	public static void test() {
		List<Integer> list = new ArrayList<Integer>();
		
		// Object e를 매개변수로 받는 업캐스팅. 5를 집어 넣으면 Wrapper 클래스 중 하나인 Integer 클래스 타입으로 변환(오토 박싱). 업캐스트.
		// list.get(e); 인덱스 넘버를 반환. 오토 언박싱 되어 Integer 클래스가 int형으로 자동으로 바뀜. 
		// 제네릭. 특정 클래스 타입으로만 입력 데이터를 제한. 
		list.add(5);
//		list.add("홍길동"); // 제네릭으로 <Integer> 을 제한하면 String 입력 시에 데이터 검증을 해줌.
		list.add(100);
		System.out.println(list);
		
		int sum = 0;
		for(int i=0; i<list.size(); i++) {
//			System.out.println(list.get(i));
			sum += list.get(i); // 오류. The operator += is undefined for the argument type(s) int, Object
		}
		
		System.out.println(sum);
	}

}


[Book.java]

package ddit.chap07.sec03;

public class Book {

	String isbn; // 도서번호
	String title; // 제목
	int price; // 가격
	
	Book() {} // 기본 생성자

	// 매개변수 생성자
	public Book(String isbn, String title, int price) {
		this.isbn = isbn;
		this.title = title;
		this.price = price;
	}
	
	// 할인가격 설정 메서드
	public void setSalePrice(double discountRate) {
		price -= (int)(price * discountRate);
	}
	
	public void printInfo() {
		System.out.println("제목 : " + title);
		System.out.println("가격 : " + price);
	}
	
}

[Novel.java]

package ddit.chap07.sec03;

public class Novel extends Book {

	String genre; // 장르

	Novel() {}
	
	Novel(String isbn, String title, int price, String genre) {
		super(isbn, title, price);
		this.genre = genre;
	}
	
	@Override
	public void printInfo() {
		System.out.println("장르 : " + genre);
		System.out.println("제목 : " + title);
		System.out.println("가격 : " + price);
	}
	
	public void refund() {
		System.out.println(title + "소설책을 반품합니다.");
	}
	
}

[TextBook.java]

package ddit.chap07.sec03;

public class TextBook extends Book {

	String major; // 전공분야

	TextBook() {}
	
	TextBook(String isbn, String title, int price, String major) {
		super(isbn, title, price);
		this.major = major;
	}
	
	@Override
	public void printInfo() {
		System.out.println("전공분야 : " + major);
		System.out.println("제목 : " + title);
		System.out.println("가격 : " + price);
	}
	
	public void supplyBook(String buyer) {
		System.out.println(buyer + "에게 " + title + " 책을 납품합니다.");
	}
	
}

[BookExample.java]

package ddit.chap07.sec03;

public class BookExample {

	public static void main(String[] args) {
		
//		Book b1 = new Book("4848-71", "난장이가 쏘아올린 작은 공", 15000); // 상속 불가
//		
//		Novel n1 = new Novel("1232-42", "아낌없이 주는 나무", 5000, "동화"); // 상속 가능
//		n1.printInfo();
//		n1.setSalePrice(0.2); // Book 클래스에 정의된 것을 사용.
//		n1.printInfo(); // Book 클래스에 정의된 것을 재정의.
//		
//		TextBook t1 = new TextBook("3535-53", "Real-World Software", 18000, "SE"); // 상속 가능
//		t1.printInfo();
//		t1.setSalePrice(0.1); // Book 클래스에 정의된 것을 사용.
//		t1.printInfo(); // Book 클래스에 정의된 것을 재정의.
		
		Book b2 = new Novel("1232-42", "아낌없이 주는 나무", 5000, "동화");
		Book b3 = new TextBook("3535-53", "Real-World Software", 18000, "SE");
		
		// 업캐스트 되었을 때 b2, b3 접근 가능 변수는 Book 클래스에서만 정의한 멤버 변수만 접근 가능.
		// 접근 메서드는 setSalePrice(), printInfo();
		// setSalePrice()는 재정의되지 않았으므로 부모 것이 호출됨.
		// printInfo();는 각기 자식 클래스에서 재정의했기 때문에 자식 것이 호출됨.
		
		b2.printInfo(); // 자식 클래스인 new Novel() 것이 호출됨.
//		b2.refund(); // 자식 클래스  new Novel()의 refund() 메서드는 재정의 하지 않았으므로 자식의 고유 메서드임. 부모 클래스는 호출 불가.
//		b3.major = "IT Technology"; // b3(new TextBook())가 접근할 수 있는 변수는 부모 클래스인 Book()의 멤버 변수 밖에 없다.
		
		// TextBook 클래스의 supplyBook() 호출이 요구될 때 b3를 이용하려면? Down casting.
		// instanceof 연산자 사용해야 함.
		if(b3 instanceof TextBook) {
			TextBook tb1 = (TextBook) b3;
			tb1.supplyBook("한국대학교"); // 한국대학교에게 Real-World Software 책을 납품합니다.
		}
		
		
	}

}


[추상 클래스]

완성이 되지 않은 메소드를 가지고 있는 클래스

객체가 되어질 수 없다.

추상 클래스와 인터페이스의 공통적인 기능?
PL(팀장)인 경우, 내 밑에 프로그래머들이 여러 명 있을 것. AA, TA 등이 맡음.
팀장이 팀원을 제어할 때, 업무를 분배해야 함. 어떤 수단과 방법을 가리지 않고 개발 해야 함.
일감을 주면서 템플릿을 하나 제공한다. 처음 해보거나 익숙하지 않은 프로그래머는 스스로 알아서 하기 힘듦. 결정적으로 3명에게 일감을 분배했기 때문에, 서로 다른 클래스명을 주고 개발하면 합치는 것이 더 힘들다.
혼자 만드는 것만도 못하기 때문에, 니가 만들어 쓰되, 이 클래스를 상속 받아서 써야 한다는 제일 위에 껍데기를 정의하여 분배.

메서드 이름, 매개변수, 반환 타입만 정의.

구조를 결정해 줄 때 사용. 다음에 이들을 이용해서 생성될 클래스의 기본 구조를 정의해 줄 목적으로 활용.

정의하는 방법
(1) 제일 위에서 제일 밑에 내려오는 것. -다운 방식 : 구체화 방법(specialize)
(2) 제일 밑에서 공통적인 것을 뽑아서 위로 올라가는 방식. 일반화 방법, 추상화 방법

메서드의 시그니처만 제공하여 기본 구조를 제공.

객체가 만들어질 실체 클래스의 공통적 특성을 가진 메서드를 정의하는 것이 추상 클래스. 따라서 추상 메서드를 가지고 있어야 한다. 몸통이 없고 헤드만 있는 메서드. 따라서, 미완성 메서드. 객체로 만들어질 수 없다. new 연산자의 대상이 될 수 없고 상속이 되어진 클래스에서 재정의로 몸통을 달아줘야 한다.

여러 자식 클래스의 템플릿, 구조를 결정해 주는 역할.

건물을 지을 때 설계도, 조감도 역할임.


[Point.java]

package ddit.chap07.sec04;

public class Point {

	int x;
	int y;
	
	Point() { 
		this(0, 0);
	}
	
	Point(int x, int y) {
		this.x = x;
		this.y = y;
	}
	
}

[Shape.java]

package ddit.chap07.sec04;

public abstract class Shape {

	String kind;

	Shape() {}
	
	Shape(String kind) {
		this.kind = kind;
	}
	
	public abstract void draw(); // 추상 메서드

	@Override
	public String toString() { // 오버라이딩된 자식 클래스의 접근 지정자 범위를 부모 클래스 범위보다 좁게 설정할 수 없다. 반환 타입이나 메서드 이름, 매개변수 변경 불가.
		return kind;
	}
	
}

[Circle.java]

package ddit.chap07.sec04;

public class Circle extends Shape {
	
	private Point p;
	private int radius;
	
	Circle() {}
	
	Circle(String kind, Point p, int radius) {
		super(kind);
		this.p = p;
		this.radius = radius;
	}
	
	@Override
	public void draw() {
		System.out.println("원점이 " + p + " 이고 반지름이 " + radius + "cm 인 "+ kind +"을 그리다.");
	}
	
}

[Rectangle.java]

package ddit.chap07.sec04;

public class Rectangle extends Shape {

	private int width;
	private int height;
	
	Rectangle() {}
	
	Rectangle(String kind, int width, int height) {
		super(kind);
		this.width = width;
		this.height = height;
	}
	
	@Override
	public void draw() {
		System.out.println("가로의 길이가 " + width + "cm 이고, 세로의 길이가 " + height + "cm 인 " + kind + "을 그리다.");
	}
	
}

[ShapeExample.java]

package ddit.chap07.sec04;

public class ShapeExample {

	public static void main(String[] args) {
		
		Shape p1 = new Circle("원", new Point(200, 100), 15);
		p1.draw();
		
		Shape p2 = new Rectangle("직사각형", 30, 20);
		p2.draw();
		
	}

}

 

'대덕인재개발원_Java' 카테고리의 다른 글

230728 자바 강의  (0) 2023.07.29
230727 자바 강의  (0) 2023.07.29
230725 자바 강의  (0) 2023.07.25
230724 자바 강의  (0) 2023.07.24
230721 자바 강의  (0) 2023.07.21