윗부분 생략 (JAVA)


공부 방향

자바에 데이터베이스 연동

- java.sql.* 패키지 사용

- 데이터베이스 설치하고 기본사용법 알아야 자바로 연동가능하다

- 본격적인 오라클은 자바가 완전히 끝난다음에 오라클에 대한 내용볼것이고 가장 기본적 연동에 필요한 SQL 문 설명할것

오라클 데이터베이스 설치 (윈도우 기준)
- 오라클은 https://www.oracle.com/ 으로 가서 다운가능 

- 오라클을 설치만 한다면 학원에서만 실습가능 외부에선 안보임
- 학원에서는 강사님 컴으로 ip로 접근해서 강사님 오라클로 접근 가능

 

오라클 버전
- 최신버전받으려면 용량이 크다. 1G이상

- XE버전의 경우엔 exe 파일만 실행하면 쉽게 설치가능

- 강사님이 주신 경량화된 오라클은 실습으로 쓰기 좋은 XE 버전임, 원래는 공식사이트 Oracle.com 가서 설치해야함

- 설치한 XE버전은 제어판에서 프로그램 추가됨, 제거하고싶으면 제어판에서 제거하면됨

XE버전만 그렇다 다른 버전 Enterprise version이나 등등은 설치도 어렵고 삭제도 어렵다

오라클 설치할떄 주의해야할 사항

기본 DB 관리자 계정 비밀번호 설정

- 설치할떄 기본적으로 데이터베이스관리자 DB 관리자가 두개 만들어져있다
- 오라클이 설치되는 과정에서 자동으로 생성되는 관리자 계정 2개  sys와 system
- 내가 만들지는 않지만 비밀번호는 내가 설정해야함

sys 계정 비번 : oracle
system 계정 비번 : oracle

- 설치시 비번 oracle로 하면 sys와 system 둘다 동일하게 oracle로 설정됨

 

기본 DB 관리자 계정 (간략)

1. SYS 계정 : 설치시 기본적으로 접속가능 계정, 가장 많은 권한을 가짐

2. SYSTEM 계정 : 설치시 기본적으로 접속가능 계정, 관리하기 위한 계정
3. SCOTT 계정 : 교육용 계정, 활성화 시켜야함, 비번은 tiger

4. HR 계정 : 교육용 계정, 활성화 시켜야함, 비번은 tiger


SCOTT 계정

- 우리는 SCOTT 계정으로 실습할 것
- SCOTT 활성화시키면 테이블 4개와 데이터까지 이미 들어가있음

- SCOTT 계정은 데이터베이스 버전에따라 사용법 다름
- 우리가 쓰는 XE는 비활성화되어있고 안에 테이블 없는 상태, 나중에 활성화시킬것 작업 필요
+ HR계정은 바로 사용가능

설치 경로
- 설치 경로 기본은 C드라이브 하위 OracleEx 폴더 하위에 설치됨

오라클 설치 완료

+ 설치시 문제 생기면 제어판 들어가서 프로그램 제거로 들어가서 목록에 오라클이 나타남, 필요없을때도 지우면됨
- 설치 완료!

 

오라클 서버 구동 방법, 중지 방법


- 구동은 오라클 설치시 자동 구동된다

필요하지 않을때 중지하는법
- 내 PC 오른쪽마우스 눌러서 [관리] -> [컴퓨터 관리]-> [서비스 및 응용 프로그램] -> [서비스] 메뉴 에서 부팅할때 실행할 서비스, 실행하지 않을 서비스들 목록을 볼 수 있고 수정 가능
- Oracle로 시작하는 5개 중에서 OracleServiceXE와 OracleXETNSListener 구동되어있어야 나중에 클라이언트가 DB에 접근가능함
- 현재는 설치시 자동으로 구동되기때문에 클라이언트가 접속가능함
- 시작유형이 자동이라 되어있으므로 부팅될때 자동으로 구동되는것임, 단 부팅시간 많이 걸림

자동실행 막기
- 오라클 안쓸때는 이걸 수동으로 바꾸면 부팅할때 자동 실행되지 않음
- 오른마우스 해서 중지 누르면됨
- 또는 시작 유형 변경할때 오른버튼 속성으로 들어가서 시작유형을 바꿀수있다(ex) 자동-> 수동)

클라이언트에서 오라클 DB 접속
- 클라이언트가 접속을 하도록 해보자
- 아무 프로그램 설치안하고 기본적인 접속가능하다, 가장 기본적인 접속 방법은 명령프롬프트로 접속
- 현재는 sys와 system 계정에만 들어갈수있다 다른계정은 락이 걸려있으므로 못감

명령 프롬프트 창에서 오라클 DB 접속하기

sqlplus system/oracle
// sqlplus 계정명/비번

- sqlplus 계정명/비번 을 입력하면 오라클의 해당 계정에 접근 가능

- sqlplus 명령이 들어가있는 bin 디렉토리까지 path가 자동으로 잡혀있으므로 바로 쓰면된다

- 오라클은 설치시 경로를 다 잡아준다, bin까지 path를 가장 앞쪽에 잡아놓기 때문에 아무위치에서나 sqlplus로 오라클 접속 가능
+ 자바는 설치시 path 안잡아 주므로 우리가 잡아야한다

 

- 이후 저 코드를 치면 SQL> 로 바뀜 

 

접속한 계정명 확인

show user

- 현재 접속한 계정명을 알려줌

 

접속 빠져나오기

exit;
// quit;

- 빠져나올땐 exit; 나 quit; 으로 빠져나올 수 있다, Disconnected 됨

sqlplus 만 입력시
- sqlplus 명령만입력하면 user-name 물어봄 이때 여기에 system이라 입력하고 비번 입력
- 계정명과 비번 맞으면 인증받아서 로그인하게 됨

 

SYS 계정 접근 하는 방법

- 같은 방법으로 sys계정으로 접속시도시 접속이 안된다
- ERROR 이유 : sys는 오라클에서 가장 많은 권한 가진 유저라서 이렇게 쉽게 접속 불가

- 접속하기 위해 권한을 부여해야함 as sysdba 를 뒤에 붙인다

sqlplus system/oracle as sysdba

- 데이터베이스 설치 복구 등 system 계정으로 하기 힘든일만 sys에서 한다

설치된 오라클 파일 구조

- 오라클은 c드라이브 하위 oraclexe 폴더 하위에 오라클이 설치되어있다

C:\oraclexe\app\oracle\product\11.2.0\server\bin

- bin 디렉토리는 명령어들이 모여있는 디렉토리, sql 명령어 실행파일들이 모여있다

ex) 지금 쓰고있는 sqlplus라는 명령어도 이 bin 디렉토리 안에 있음

ex) 여러 백업이나 복원시 쓰는 명령어도 이 bin 디렉토리에 있음

 

PATH 관련

- 오라클 설치되는 과정에서 sqlplus 명령이 들어가있는 bin 디렉토리까지 path가 자동으로 잡혀있으므로 명령어를 바로 쓰면된다
- 내PC->[설정] -> [고급 시스템 설정] -> [환경변수]

- 가장 앞쪽에 path설정된거 볼 수 있다
- path 가 C:\oraclexe\app\oracle\product\11.2.0\server\bin 로 잡혀 있음

기본 DB 관리자 계정
SYSTEM, SYS 계정

- 데이터베이스 관리자 줄여서 DBA 계정

- DB를 관리하기 위한 계정임
- 일반적인 용도로는 잘 쓰지 않음, 이 계정으로 실습을 해선 안됨
- 관리를 위한 계정이므로 두 계정으로 들어가면 기본적으로 관리하기 위한 시스템 테이블들이 여러개 만들어져있다

 

실습을 위한 DB 계정

- 실습이나 프로젝트를 위해서는 다른 일반계정이 필요함
- 일반계정 새로 생성해서 작업하든지 아니면 교육용 제공되는 SCOTT 이나 HR 계정으로 실습많이함
- SCOTT, HR 계정은 실습하기위한 테이블까지 제공되므로 실습을 쉽게할수있다

 

SCOTT 계정
- SYSTEM, SYS 계정은 관리할때만 쓰고 지금부턴 쓰지 않음. SCOTT 계정으로 실습을 할것이다
- SCOTT 계정은 DB종류에 따라 활성화 시키는 방법이 다르게 되어있다

- 다른 버전은 시스템계정으로 들어가서 스콧계정에 걸린 락을 풀어주기만해도되지만 xe버전은 활성화시키는 방법 복잡함

 

+ 테이블 보기
- 각 계정별로 기본적으로 테이블들을 가지고있다
- 테이블 목록 보려면

select * from tab;


- 하면 보여줌

+ 테이블 목록확인할땐 ; 빠뜨리면 안됨

- 단 DBA 계정들의 시스템 테이블을 건드리면안된다, 그 테이블은 관리를 위한 테이블이다
ex) sys계정에서 이 명령어 실행하면 몇천개의 시스템 테이블이 나온다

 

계정 전환하기
- 접속 된 상태에서 다른 계정으로 계정 전환하고 싶으면

connect system/oracle 
// connect 변경해야할계정명/비번

- 하면 system 계정으로 계정 전환됨
- connect 대신 conn 까지만 써도 됨

- 단, sys로 갈떄는 

connect sys/oracle as sysdba

- 까지 해야 sys계정으로 전환가능
- sys계정은 그냥 갈 수 없음


+ system은 174개정도 테이블 있다

 

SCOTT 계정 활성화 시키는 방법
+ scott.sql 파일이 필요함

c:\> sqlplus scott/tiger
c:\> sqlplus system/oracle

SQL> @c:\scott.sql

SQL> alter user scott identified by tiger; (alter user 계정명 identified by 비번;)

SQL> conn scott/tiger (scott계정으로 전환)

SQL> select * from tab; (테이블 목록, 4개의 테이블이 보임)

SQL> quit; (종료)

- 가장 먼저 sqlplus 로 system 계정으로 접속한다 비번 oracle
- 접속 되고나면 SQL> 로 바뀜
- 이때 scott.sql 파일을 불러와야함
+ 이 파일을 만약 C드라이브에 저장했으면 @c:\scott.sql 해줌

@ 명령어
- @는 sqlplus 명령어 중 하나임
- @는 확장자가 sql로 되어있는 파일을 실행시켜주는 명령임
- @라는 sqlplus 명령어로 실행시켜라는 의미

scott.sql 파일

- SCOTT 계정 소유의 4개의 테이블을 생성하고 실습을 하기위한 데이터를 Insert시키는 내용이 이 파일안에 있다

- 백업을 해둔 이 파일을 실행하면 4개의 클래스 생성되고 데이터 insert됨

- scott.sql 파일 안에 보면 4개의 테이블 생성하는게 보인다

 

scott.sql 파일 부분
CREATE TABLE DEPT //부서테이블 생성
CREATE TABLE EMP //사원테이블 생성
INSERT INTO DEPT VALUES('','','','') // DEPT 테이블에 데이터 4개를 insert 시킴
이 INSERT 문이 4개있고
그 다음은 
CREATE TABLE BONUS
CREATE TABLE SALGRADE
그리고 SALGRADE안에 데이터를 INSERT 하고 있다


SCOTT 계정 활성화 후 테이블 목록 확인
- DEPT EMP BONUS SALGRADE 4개의 테이블이 만들어져있다
ex) select * from dept; 하면 내부 데이터 보임

SCOTT 계정 활성화 이후

- 이젠 scott계정으로 sqlplus 해서 바로 접속 가능하다
- 현재 3개의 계정(SYS, SYSTEM, SCOTT) 으로 접속가능

파일 시스템 vs DB 서버

파일 시스템

- 파일 단위로 데이터를 관리
- 지금껏 개인들은 파일시스템을 써왔음
- 개인들은 파일로 관리함, 파일이 많아지면 폴더안에 저장함

 

DB 서버
- DB서버는 모든 유저가 사용해야하기때문에 기존 파일시스템을 쓰면 여러 문제가 발생함

- 데이터를 효율적으로 관리하기 위해서 사용함

 

파일 시스템의 문제

- 파일시스템은 1차적으로 중복문제가 발생함

ex) 자료실 기능 upload 폴더 안에 lay.jpg 가 저장되면 동일이름 파일 저장못하는 문제
- 데이터 무결성 문제도 발생, 보안성 문제도 발생

 

-> 데이터 안전관리 위해서 데이터베이스 관리 시스템 (DBMS) 이란걸 쓰게됨


DBMS(DataBase Management System)

- 데이터베이스 관리 시스템
- DBMS 쓰면데이터 효율적이고 안전하게 관리 가능하다

 

RDBMS

- 관계형 데이터베이스 관리 시스템 (Relational DataBase Management System)

- DBMS 중에 우리가 주로 쓰는 많은 DBMS는 RDBMS
- 가장 일반적인 형태의 DBMS  
- 표를 작성해서 데이터를 관리하는 데이터베이스 관리 시스템

- 대표적인 RDBMS 는 Oracle, Sybase, Infomix, MYSQL, Acess, SQL Server
- 우리가 알고있는 많은 데이터베이스들은 거의 관계형 데이터베이스로 되어있다
- 쉽게 작성,확장 가능하고 데이터 관리도 용의함
- RDBMS 는 스키마(표) 가 있고 형식에 맞는 정형데이터만 저장 가능

+ 그 외에도 계층형, 네트워크 형 등 있음

 

+ NOSQL
- 빅데이터 처리할때는 RDBMS 가 아닌 NOSQL을 쓴다 
- Not Only SQL , 빅데이터 저장하기 위한 저장소역할을 하는데 종류가 여러개있다
ex) 몽고DB. 카산드라 등 
+ RDBMS 는 스키마(표) 가 있고 형식에 맞는 정형데이터만 저장 가능
- 그에 비해 NOSQL은 정형이 아님 집어넣으면 다 들어감

 

RDBMS 특징
- 관계형 데이터베이스는 표를 작성한다
- 표제목 = 컬럼, 필드 란 용어를 씀
- 한개의 표는 표제목에 해당되는 컬럼이 있고, 로우(row)가 있다

 

ex) DEPT는 부서정보 가진 테이블

DEPTNO  DNAME LOC
10 ACCOUNTING NEWYORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON

- 3개의 컬럼과 4개의 로우로 구성되어있다
- 첫번째 컬럼은 부서번호 DEPTNO가 저장되어있음 
- 두번째 컬럼은 부서명 DNAME
- 세번째 컬럼은 부서위치지역LOC

테이블 목록 확인
- select * from tab; 하면 테이블 전체 목록, select * from DEPT 하면 DEPT 테이블 목록 확인 가능
- select문은 SQL 문임 데이터 검색,질의할때 사용, ;를 반드시 찍어야
- SQL문은 대소문자를 구분하지 않는다

SQL(Structured Query Language)
- 데이터베이스에 질의하는 명령어
- 여러 데이터를 검색, 조회, 입력, 수정하기위한 명령어를 SQL 이라고 함
- SQL은 기능에 따라 DML, DCL, DDL 등 나눠짐

- 지금은 자바와 연동하기위한 4,5개 SQL문만 공부할것



DDL SQL문
- 데이터 정의어 (Data Definition Language)
- CREATE, ALTER, DROP, RENAME, TRUNCATE 가 있다
- CREATE : 테이블을 생성하는 역할
+ 오라클은 전역 데이터 베이스 하나만 나눠서 쓰기때문에 따로 데이터베이스 안만들어도됨
+ mysql은 사용자별로 데이터베이스따로 만듬
+ 그때 CREATE는 데이터베이스 만드는것, 오라클인 여기선 그냥 테이블 생성
- ALTER : 테이블 구조 변경
- DROP : 테이블 삭제
- RENAME : 테이블 이름 변경
- TRUNCATE : 한번에 데이터 모두 삭제

 

DDL (데이터 정의어) 의 CREATE 명령어
- CREATE 명령어를 사용해서 테이블 한개 생성 가장 먼저 해보자

 

DML (데이터 조작어)
- DDL CREATE 로 테이블이 만들어지고 나면 생성된 테이블에 데이터 입력할땐 INSERT 명령어 써야, 수정은 UPDATE 삭제는 DELETE
- 데이터가 조작이 일어남 그래서 INSERT UPDATE DELETE 를 DML 이라 부림

 

SELECT 명령어

- SELECT 는 검색을 할떄 사용하는 것
- SELECT 는 아무리 써도 데이터 조작 일어나지 않음 (정처기에선 DML로 분류됨)

- 전체 SQL 문에서 50%이상이 SELECT 가 차지, 가장 복잡함

- 조건들을 만족하는 데이터 검색, 검색된 자료들 정렬, 데이터 전체검색, 테이블 나눠져있을땐 조인을 해야하고, 조건에 맞는 데이터를 10개씩 잘라 출력하기 등 가장 많은 기능가진게 SELECT 임

 

CRUD
- CREATE TABLE 같은건 콘솔창에서도 해도되고 그래픽프로그램에서도 해도되고 아무곳에서 해도 된다
- 하지만, DML SQL문들은 자바같은 프로그램가지고 직접 코딩을 해야함, 이런걸 CRUD(create read update delete) 작업이라고 함, CRUD SQL문들은 프로그램 상에서 직접 구동해야한다
- Select Insert Update Delete 는 프로그램 상에서 직접 적어서 구동해야

TCL / DCL
- 트랜지션에 관련된 TCL이나 권한에 관련된 데이터제어어 DCL 등도 있다


CREATE 명령어
- 테이블을 생성할때 사용되는 명령어

create table 생성할테이블명 (컬럼명 데이터타입, 컬럼명 데이터타입, ...);

 

- 데이터타입은 크게 3가지 (숫자,문자,날짜) 있다
+ 데이터타입은 데이터베이스 종류따라 다름
ex) 오라클은 숫자는 number 타입 , 문자는 varchar2 타입, mysql 은 숫자는 int 타입, 문자는 varchar 타입

 

테이블 생성

create table member01(
	id  varchar2(20), //20바이트만큼 공간할당하라, 즉 크기임
	name  varchar2(20), // 이름저장위한 varchar2에 20바이트 공간할당해라
	address varchar2(50), //주소저장위한 varchar2에 20바이트 공간 생성해라
	phone  varchar2(20));


- 하면 member01 테이블 만들어짐

+ 중간에 잘못입력하고 엔터쳤다면 방향키를 이용해 그거 수정하고 엔터치면 됨

 

오라클의 데이터 타입
- 숫자는 number 타입을 씀 문자는 varchar2 를 주로 쓰고, 문자는 date 나 timestamp 를 사용한다

 

테이블 목록 보기

select * from tab;

- member01 생성됨을 알수있다

 

테이블의 스키마(구조) 보기
- describe 명령 사용, 아래 둘 다 가능

describe member01
desc member01

- describe 명령을 사용해서 해당 테이블의 컬럼명들과 데이터 타입을 볼 수 있다

 

SCOTT 의 DEPT 테이블 구조를 보면서 컬럼 보기

- 컬럼 DEPTNO 에 NOT NULL 되어있고, 타입은 NUMBER(2) , 두 자리까지 저장가능하단 의미 즉 99까지 저장가능하다, 두자리 정수만 저장가능하단 의미
- 컬럼 DNAME는 VARCHAR2(14) , 14바이트까지 저장가능 문자라는 의미
- 컬럼 LOC 는 VARCHAR2(13), 13바이트까지 저장가능한 문자데이터다

 

오라클의 자료형
- 오라클에서 자료형은 크게 3가지 타입인 숫자, 문자 날짜 로 나뉜다
- 다른 RDBMS도 마찬가지지만 데이터베이스마다 자료형이 다름

oracle mysql
number int
varchar2 varchar


- DDL CREATE로 테이블(표) member01 을 만들어봤다

+ 강의에는 CREATE(데이터베이스 생성) 이라 되어있지만 오라클에선 테이블 생성임


DML

- 만들어진 표에대해 데이터 입력 INSERT, 수정 UPDATE, 삭제 DELETE, 검색 SELECT 을 해보자

- 실제로 데이터 조작함

- 데이터 입력 INSERT, 수정 UPDATE, 삭제 DELETE, 검색 SELECT 
- SELECT 는 아무리검색해도 데이터 조작 안일어나지만 DML에 포함

INSERT 명령어
- 데이터 입력시 사용되는 SQL 문, INSERT 는 형식이 2가지가 있다

INSERT SQL 문 형식 2가지
1. 컬럼명을 쓰는 형식, 원하는컬럼만 데이터를 입력할때 사용

insert into 테이블명(컬럼1, 컬럼2,..) values(데이터1, 데이터2,...);

- 컬럼개수와 데이터 개수가 일치해야함

- 컬럼1 자료형에 맞는 데이터1을 써야함
- 원하는 컬럼만 입력할때 쓰는 방식, 50개 컬럼이 있다면 그거 다 안쓰고 원하는 컬럼만 선택적으로 입력시 사용


2 컬럼명을 안쓰는 형식, 모든 컬럼에 데이터를 입력

insert into 테이블명 values(데이터1, 데이터2,...);

 

- 테이블에 맞는 컬럼 순대로 자료형에 맞는 값들을 모두 입력해야하는게 2번쨰 형식

DML SQL문 수행시 주의
- 문자데이터는 반드시 외따옴표(' ') 로 묶어줘야함

 

INSERT 명령어로 테이블에 데이터 삽입 (1번째 형식)

- 컬럼 순서가 바뀌어도 상관없지만 바뀐 값들 순서에 맞는 자료형으로 값을 써야함!
- 자료형이 모두 varchar2니까 데이터 삽입시 모든 데이터를 외따옴표로 값을 감싸야함
- 오라클에서 문자는 반드시 ' 외따옴표
- 영문(문자) 데이터는 대소문자 구분함
- 오라클은 대소문자 구분안하지만 유일하게 문자데이터는 대소문자 구분함! 즉 ' ' 안에 들어간건 대소문자 구분됨

 

SELECT 명령어로 테이블의 데이터 확인

- member01에 있는 모든 데이터를 검색하라는 의미이다

INSERT 명령어로 테이블에 데이터 삽입 (2번째 형식)
- 두번째 형식으로 INSERT 해보자

- 컬럼명을 안쓰지만 모든컬럼을 순서대로 맞는 자료형의 값을 써야함
- CREATE 할때 크기 설정을 20바이트로 했다면 20바이트 내의 데이터만 입력되고 20바이트가 넘는 데이터는 INSERT 되지 않는다

SELECT 명령어로 테이블의 데이터 확인

- 영문 데이터는 대소문자 구분, 문자 데이터는 ' ' 안에 !


UPDATE 명령어
- 데이터를 수정할때 사용되는 명령어

UPDATE SQL 문 형식

update 테이블명 set 컬럼1=수정할값1,
            	컬럼2=수정할값2,...
           	where 조건절;


- 수정하고 싶은 데이터만큼 늘려서 작성하면 된다

- 마지막 수정할값뒤에는 , 안쓰기

where 조건절
- 원하는 데이터만 수정하기위해서 where 조건절을 씀, 비교연산자로 조건절을 쓰게됨(> ,<, <=, >=)
- 조건절을 만족한 데이터만 수정가능하다
- where 조건절이 없으면 모든 데이터가 한꺼번에 수정됨

오라클에서의 비교연산자

= : 같다
<> , !=, ^= : 다르다

- 자바랑 다름을 주의
- 보통은 where 조건절에 비교연산자를 쓰는게 일반적

UPDATE 명령어로 데이터 수정
- 'toto'란 사람의  주소를 '인천시' 였는데 '제주도' 로 바꾸자

update member01 set Address = '제주시'

- 하면 모든 데이터가 '제주시'로 바뀌므로 where 조건절써서 id값이 'toto'인 회원만 이라는 조건달기

update member01 set Address = '제주시' where ID = 'toto';


SELECT 명령어로 조건에 맞는 데이터만 검색

- SELECT문도 WHERE조건절 써서 id값이 'toto'인 회원만 검색하기 가능
- WHERE 조건절은 INSERT 를 제외한 나머지 명령어에 쓸 수 있음 DELETE, UPDATE 시 사용 가능



DELETE 명령어
- 데이터를 삭제할때 사용되는 명령어

delete from 테이블명 where 조건절;


- DELETE FROM 테이블명 까지 쓰면 테이블 안의 모든 데이터를 삭제함
- DELETE 문에 WHERE써서 원하는 조건만 삭제

 

DELETE 명령어로 특정 데이터 지우기 1
- id값이 'toto'인 데이터를 지우자

+ 데이터가 삭제되었는지 SELECT 문으로 확인

DELETE 명령어로 특정 데이터 지우기 2

- id값이 'test'인 데이터도 지우자



자바 - 오라클 연동
- 이클립스를 사용해서 자바에서 오라클로 연동해보자
- 자바 - 오라클은 그냥 연동이 안됨 자바는 오라클을 모르므로 접속을 어떻게 할지 모른다

- 자바는 오라클에 대한 정보를 가지고있지 않으므로 오라클 사 에서 만든 드라이브를 자바에게 알려줘야함

- 자바 - 오라클 사이 중간에 드라이브가 필요하다

JDBC Driver

- 중간 연동을 위해서는 JDBC Driver 가 필요함, 이 드라이버가 있어야만 자바는 접속정보를 받을 수있음
- 이 드라이버는 데이터베이스 회사에서 제공함(Oracle사)
- Oracle용 JDBC Driver를 오라클 홈페이지에서 구하거나 설치시 제공되는걸 사용
- 이 JDBC Driver 이름이 ojdbc6.jar 이다, 오라클 설치될떄 JDBC Driver 인 ojdbc6.jar 도 같이 설치됐다
- 자바 연동 방법 : 이 드라이버 파일 ojdbc6 를 자바가 설치된곳에 저장한다, 그럼 이 드라이버가 이클립스 상에서 보임
+ 만약 mysql 과 연동할땐 mysql용 드라이버를 구해야함 (데이터베이스 만든회사에서 드라이버를 제공)

 

++
운영체제는 그래픽카드 모름, 그래픽카드 회사에서 드라이버를 만들어서 알려줌, 그거처럼 여기서도 마찬가지

자바 - 오라클 연동 방법
1. 가장 먼저 JDBC Driver를 구해야함
- 오라클이 설치된곳에 드라이버 여러개 있다. 그 중 현재 ojdbc6.jar 를 쓸 것

- c:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib 안에 ojdbc5, ojdbc6, ojdbc6_g 있음


2. 이 드라이버를 자바가 설치된곳 jre/lib/ext 폴더 아래에 드라이버 ojdbc6.jar 를 넣는다

- ojdbc6.jar를 복사해서 자바가 설치된 c:\Program Files\java\jre1.8.0_231\lib\ext 안에 넣는다

- lib 폴더 하위에 저장해야만 따로 클래스 path 를 잡아주지 않아도 이 드라이버 파일이 이클립스에서 보인다
- 다른곳에 넣으면 클래스 path를 따로 잡아줘야함
+ 현재 오라클용 JDBC Driver 는 클라우드 폴더에도 있고, 홈페이지에서도 구할수있고, 오라클 설치된곳에 가도 있다

 

3. 이클립스에서 JDBC Driver 인 ojdbc6.jar 가 보이는지 확인한다

- 이클립스에서 ojdbc6.jar가 보인다


4. 자바 - 오라클 연동 테스트 
- 자바 - 오라클 연동 테스트를 위한 두개의 테스트 파일 있다

- JDBC_Connect01.java 와 JDBC_Connect02.java
- 연동테스트를 성공해야만 나중에 SQL문으로 데이터를 처리 가능

 

자바 - 오라클 연동 테스트 : 예제 1
- JDBC 드라이버가 로딩이 되는가만 테스트하는 코드임
- JDBC_Connect01.java

package p2022_07_14;

import java.sql.*;

public class JDBC_Connect01 {

	public static void main(String[] args) {

		/** ORACLE JDBC Driver Test ***************************/
		String driver = "oracle.jdbc.driver.OracleDriver";
		/******************************************************/

		/** My-SQL JDBC Driver Test **************************/
		//	String driver ="com.mysql.jdbc.Driver";
		/*****************************************************/

		try {
			Class.forName(driver);	//JDBC Driver Loading
			System.out.println("JDBC Driver Loading 성공~!!");	

		} catch (Exception e) {
			System.out.println("JDBC Driver Loading 실패~!!");
			e.printStackTrace();
		}
	}
}

코드 하나씩 살펴보기 1

String driver = "oracle.jdbc.driver.OracleDriver";

- 오라클 JDBC Driver 경로를 변수 driver 에 저장

- oracle.jdbc.driver 까지가 패키지명, OracleDriver 가 클래스명

- 가져왔던 ojdbc6.jar 의 압축을 풀면 oracle.jdbc.driver 라는 패키지가 있고, 그 안에 클래스 OracleDriver.class 가 있다

 

코드 하나씩 살펴보기 2

Class.forName(driver);

- 클래스 이름이 Class 이다, java.lang 안의 Class 클래스
- forName() 은 정적메소드, 메소드 매개변수로 driver 변수로 저장되었던 JDBC Driver 를 로딩함
- JDBC Driver 가 로딩 안되면, 예외발생시 catch로 간다
- JDBC Driver 가 로딩 된다면, 성공 메세지 뿌림

- 자바 - 오라클 연동 코드에서 예외처리를 반드시 해야함, try-catch-finally를 써서 주로 예외처리를 한다
- Class.forName() 은 try안에 예외발생할 가능성있는 문장 

 

자바 - 오라클 연동 테스트 : 예제 2

- JDBC 드라이버 로딩 테스트만 했던 이전 예제와 달리, JDBC Driver 로딩도 하고 DB 접속도 한다
- JDBC_Connect02.java

package p2022_07_14;

import java.sql.*;

public class JDBC_Connect02 {

	public static void main(String[] args) {

		/** ORACLE JDBC Driver Test *****************************************/
		String driver = "oracle.jdbc.driver.OracleDriver";
		String url = "jdbc:oracle:thin:@localhost:1521:xe";
		/*******************************************************************/

		/** My-SQL JDBC Driver *********************************************/
		//	String driver ="com.mysql.jdbc.Driver";
		//	String url = "jdbc:mysql://localhost/academy";
		/*******************************************************************/

		Connection con = null;

		try {

			Class.forName(driver);

			/** ORACLE에서 Connection 객체 ***********************************/
			con = DriverManager.getConnection(url, "scott", "tiger");
			/*******************************************************************/

			/** My-SQL에서 Connection 객체 ***********************************/
			//	  con = DriverManager.getConnection(url, "totoro", "1234" );
			/*******************************************************************/

			System.out.println("데이터베이스 연결 성공~!!");

		} catch (Exception e) {
			System.out.println("데이터베이스 연결 실패~!!");
			e.printStackTrace();
		} finally {
			try {
				if (con != null)
					con.close();
			} catch (Exception e) {
				System.out.println(e.getMessage());
			}
		}
	}
}

 

코드 하나씩 살펴보기 1

		/** ORACLE JDBC Driver Test *****************************************/
		String driver = "oracle.jdbc.driver.OracleDriver";
		String url = "jdbc:oracle:thin:@localhost:1521:xe";

<driver 변수>

- String driver = "oracle.jdbc.driver.OracleDriver"; 그대로 수정안해도 된다

<url 변수>

1. localhost는 현재 자바와 오라클이 같은 ip를 가지고 있으므로 local로 접속하는것이다
- 만약, 오라클이 원격으로 떨어져있으면 오라클 설치된 컴의 ip주소 나 도메인명을 써야함

- 현재 localhost 자리에 타인의 컴 ip 주소를 쓰면 이클립스에서 자바 프로그램으로 타인의오라클 DB 에 접속 가능 (타인의 컴퓨터 방화벽이 풀어있어야함)

2. 1521 은 포트번호, 여기도 소켓통신하므로 IP주소와 포트번호를 가지고 찾아가서 해당 소켓을 연결함

- IP주소와 포트번호까지 일치되어야만 소켓을 연결해서 통신가능

3. 변수 url 에는 우리가 사용하게 될 데이터베이스의 정보를 설정한다

- xe 는 우리가 사용하게 될 오라클의 전역 데이터베이스 이름이다
- 지금 버전에 맞게, 맨 마지막의 orcl 대신 xe로 수정

오라클 버전 별 데이터베이스 이름
- XE 버전은 기본값이 xe, 전역 데이터베이스 이름이 xe 이다

 

코드 하나씩 살펴보기 2 (JDBC Driver 로딩)

			Class.forName(driver);

- Class.forName() 메소드로 오라클용 JDBC 드라이버를 메모리상으로 로딩, 이 로딩을 가장 먼저 해야한다

-  예외처리 필수인 코드, 안하면 오류 발생 (db연동과 입출력은 예외처리 필수)

- 클래스명이 Class, 정적메소드인 forName()

+ try-catch-finally 반드시 예외처리 해야하는 형식임

 

코드 하나씩 살펴보기 3 (Connection 객체 생성)

con = DriverManager.getConnection(url, "scott", "tiger");

- DB 접속 코드
- java.sql 의 클래스인 DriverManager 클래스를 통해서 getConnection() 정적메소드를 호출함
- 이 메소드는 메소드 오버로딩되어있고, 지금은 매개변수 3개짜리 쓰고있다

java.sql.DriverManger 클래스

- 드라이버를 관리하는 클래스임

- getConnection() 메소드 메소드 오버로딩 되어있는거 볼수있다
- 그 중 static Connection getConnection(String url, String user, String passward) 사용

1) 첫번째 매개변수 url 은 데이터베이스 url 정보, 오라클에선 xe 전역 데이터베이스를 쓰므로 xe 만 작성

2) 두번째 매개변수 "scott" 는 전역 데이터 들어가기위한 유저계정, 현재 scott 계정 사용

3) 세번째 매개변수 "tiger" 즉 그 계정의 패스워드

- 이 세가지 매개변수 정보가 일치하면 Connection 객체가 생성된다


DB 연동시 공통적으로 들어갈 기본적인 내용

1. JDBC Driver 로딩

2. Connection 객체 생성

- 이 두 내용은 DB 연동시 반드시 공통적으로 들어간다

 

- 현재 JDBC_Connect02.java 실행해서 성공나오면 기본적인 연동을위한 준비가 다 된것
- DB 연동하는 방법은 순서와 기본형식틀이 정해져있다

- 지금 예제에선 연결하는 것만 했음
- 접속이 되면 우리가 배웠던 SQL 을 try문 써서 수행한다

 

 catch 와 finally 에 들어갈 내용
1. 위 예제의 catch문 에서 오류출력하는 3가지 중 한가지인 e.printStarctTrace() 를 사용
2. 위 예제의 finallly문에서 생성된 객체를 닫고있다, 이때 finally에서 그냥 끊으면 예외발생하므로 그냥 끊으면 안됨
- 이 finally문 안에서 또 try 써서 Connection 객체가 null 값이 아니라면, 즉 Connection 객체가 생성되었다면 con.close()로 데이터베이스와의 연결을 끊게됨

- DB접속하기위한 기본적인 테스트 끝났다
- JDBC 드라이버 로딩, Connection 객체 생성 이 두개를 반드시 성공해야 나머지 sql 문 수행가능



자바연동 예제

- 예1 폴더
- 생성할 테이블 customer

create table customer( no number(4)  primary key, 
       name varchar2(20),
       email varchar2(20),
       tel varchar2(20)  );

 

- DDL인 이 작업을 가장 먼저 해야한다

- DDL SQL 문은 여러 곳에서 사용가능. 콘솔창에서 해도되고 , 다른 툴로 해도되고, 이클립스에서 해도됨

- no 컬럼 : 4자리 정수 저장하는 정수형, primary key 이므로 반드시 값을 입력해야하고 중복된 값을 저장할 수 없다

- primary key : 중복된값 저장불가, 값 입력하지 않은 null 값을 허용 안함
+ 이런걸 제약조건이라고 한다, no 컬럼에 아무값이나 입력하지 못하도록함

- varchar2(20)인 name,email,tel 컬럼 생성

 

+ 제약조건
- primary key, not null, unique key, foreign key 등을 제약조건이라고 함

- 제약조건 위반된 값을 못 넣게함

- 제약조건은 컬럼 단위로 제약조건 설정하는것임

- 이후 데이터 입력/검색/수정/삭제 하기 위한 java 파일들이 있다. 각 파일에서 4가지의 SQL문을 수행하고있음

 

테이블 생성
- customer 테이블을 이클립스에서 DB연동 해서 DDL create로 테이블 만들어보자

이클립스로 DB 연동하는 방법

- Window-> Show View -> Other -> Data Management 폴더 하위 Data Source Explorer 선택 후 Open 버튼누르기

- 그럼 Data Source Explorer 창이 나타남

- 거기서 Database Connections 폴더 선택 -> 오른마우스해서 new선택 

- mysql orcle sql server 등등 여러 데이터베이스와 이클립스를 연결시킬수있다

- 이 중에서 Oracle을 선택후 아래쪽에 Connection 이름명을 New Oracle(scott) 이라고 계정명을 붙여서 써주자

- 나중에 커넥션많아지면 어떤 계정으로 커넥션 연결됐는지 구분힘드므로 계정명 설정

- Next

- 우측 New Driver Definition 메뉴 클릭시 탭이 3개인 창 새로운창이 뜬다
- 3개의 탭에서 일일히 설정해야함

1. 첫번째 탭은 용하게될 데이터베이스 네임값과 타입을 선택함, 여기서 데이터베이스 종류를 선택함
- 우리가 설치한 오라클 버전으로 Oracle Thin Driver 선택, 시스템버전은11

2. 두번째 탭 JAR List에서 이전 jar파일 clear All하고 Add JAR/Zip.. 눌러서 오라클용 JDBC 드라이버 가져오기
- ojdbc6.jar 는 오라클 설치된곳또는 자바 설치된곳에 있으므로 거기 찾아가서 ojdbc6.jar 가져오기


- 한번 경로 설정해두면 SQL문 결과를바로확인하는등 아주 편하게 쓸 수 있음

 


3, 세번째 탭 Properties란 탭 들어가서 DB 관련 내용을 수정해야함
- Connection URL 부분은 jdbc:oracle:thin:@localhost:1521:xe 로 수정
- Database Name 부분은 xe로 수정
- passward 는 tiger
- UserID는 scott

- 다음으로 OK 버튼 눌러서 넘어가면 그 다음 Save password 체크

- Test Connection 버튼 눌렀을떄 Ping succeeded 메세지 나와야 연결 설정 잘 된것
-> Finish

 

- Finsh 후에 Data Source Exploer에 xe가 뜬다

- 만약 뭐 수정하고싶으면 New Oracle(scott) 에 오른마우스 -> Properties하면 아까 설정했던 그 화면이 나타남

- 좌측 하단에 현재 접속이되었는지 상태 나타남
- (Connected) 는 현재 접속된 상태
- 연결 끊고싶으면 현재 커넥션인 New Oracle(scott)에 오른마우스 - Disconnect 누르면 됨

- 다시 연결할땐 커넥션 더블클릭 또는 오른마우스 - Connect

이클립스에서 DB 접속해서 SQL문 사용하는 방법
1. .sql 파일 생성

- src 폴더 하위에 SQL이란 폴더를 만들고 그 하위에 myOracle.sql 파일을 추가하자
확장자가 sql 인 파일 만드는 방법
- 폴더누르고 오른버튼 -> new에 Other 눌러서 -> SQL Development 폴더 안의 SQL File 누르기
- 이렇게해야 확장자가 sql인 파일 만들어줌


-  파일명은 MyOracle 로 했다

2 MyOracle.sql 에서 Connection profile을 선택

- 첫번째는 타입, 우리가 사용하는 데이터베이스 종류 Oracle_11선택 
- 두번째는 커넥션 이름 선택, New Oracle(scott) 선택한다
- 세번쨰로 데이터베이스 이름은 xe 선택
- 여기까지 하고 좌측 상단 디스켓모양 눌러서 저장

- 이클립스에서 오라클로 연결 완료, 여기서 작업을 다 할 수 있다
- '--' 가 주석이다

 

SQL 문 실행하는 방법 2가지

1. 블럭을 잡아서 오른버튼눌러서 실행하는 명령인 Execute Selected Text 클릭
2. 블럭잡고 Alt+ X 단축키 누르기

 

3. SQL문 실행 : 테이블 목록 확인

select * from tab; -- 테이블 목록(현재 계정 소유의 테이블 목록을 보여달라는 것)

- 으로 해당 계정의 테이블 목록 확인 가능
- 실행시 아래쪽에 검색된 내용 보여줌
- Result1 탭에 scott 계정 테이블 소유 목록을 보여줌



4. SQL문 실행 : 테이블 생성

이클립스에서 DB 접속해서 자바 - 오라클 연결하는 예제
- 네이버 클라우더의 '예1' 폴더 안의 테이블 구조를 가져오자

create table customer( no number(4)  primary key, 
       name varchar2(20),
       email varchar2(20),
       tel varchar2(20)  );

- 위 create 문을 MyOracle.sql 로 가져와서, 블럭잡고 Alt + X 단축키로 실행
- 그 후 select * from tab; 으로 보면 customer 테이블이 보임
+ 명령프롬프트에서 desc 로 테이블 구조 확인 가능

desc customer


- MyOracle.sql 전체 코드

select * from tab; -- 테이블 목록
select * from member01;

--예1.
-- primary key(기본키) : 반드시 중복되지 않는 값을 저장 해야한다는 의미
create table customer( no number(4)  primary key, 
       name varchar2(20),
       email varchar2(20),
       tel varchar2(20)  );

 

- 데이터 원하는 형태로 쉽게 제어하기위해서 테이블 만들때 primary key 로 설정된 컬럼이 한개 필요함

- DB 작업 끝났다
- 나머지는 자바 프로그램으로 insert, select 등 해서 수정, 삭제, 삽입 등 자바에서 처리
- 내일은 예1 폴더의 파일들을 가져와서 연동시킬거 JDBC_Delete, JDBC_Update 등의 파일을 살펴볼 것

 과제
2022.07.20 / Hw2

사원테이블(EMP)에서 MGR컬럼의 값이 null 인 데이터의

MGR의 값을  CEO 로  출력하는 SQL문을 작성 하세요?

 

 

의도

SELECT문 활용

타입 변환 TO_CHAR 사용

NVL 사용

 

 

깃허브

https://github.com/kindacool/Hw/blob/main/HW20220720/2022_07_20_hw2.sql

 

GitHub - kindacool/Hw

Contribute to kindacool/Hw development by creating an account on GitHub.

github.com

 

 

코드

-- 과제2. 사원테이블(EMP)에서 MGR컬럼의 값이 null인 데이터의 MGR의 값을 CEO 로 출력하는 SQL문을 작성 하세요?
select empno, ename, job, nvl(TO_CHAR(mgr), 'CEO') as "MANAGER", sal, comm, deptno from emp;

 

 

출력

 

강사님 코드

-- Q2. 사원테이블(EMP)에서 MGR컬럼의  값이  null 인 데이터의 MGR컬럼의 값을  CEO 로  출력하는 SQL문을 작성 하세요?     
     select ename, nvl(to_char(mgr,'9999'), 'CEO') 
       as MANAGER from emp where mgr is null;

 

 

과제
2022.07.20 / Hw1

사원테이블(EMP)에서 입사일(HIREDATE)을 4자리 연도로

 출력 되도록 SQL문을 작성하세요? (ex. 1980/01/01)

 

 

의도

SELECT문 활용

포맷 출력 TO_CHAR 사용

 

 

깃허브

https://github.com/kindacool/Hw/blob/main/HW20220720/2022_07_20_hw1.sql

 

GitHub - kindacool/Hw

Contribute to kindacool/Hw development by creating an account on GitHub.

github.com

 

 

코드

-- 과제1. 사원테이블(EMP)에서 입사일(HIREDATE)을 4자리 연도로 출력 되도록 SQL문을 작성하세요? (ex. 1980/01/01)
select empno, ename, job, mgr, TO_CHAR(hiredate,'YYYY/MM/DD'), sal, comm, deptno from emp;

 

 

출력

 

 

강사님 코드

-- Q1. 사원테이블(EMP)에서 입사일(HIREDATE)을 4자리 연도로 출력되도록 SQL문을 작성하세요? (ex. 1980/01/01)
     select  to_char(hiredate, 'YYYY/MM/DD') from emp;

사용자가 키보드로 입력한 연도가 윤년인지 평년인지 판별하는 프로그램

package p2022_07_20;

import java.util.Scanner;

public class Test1 {

	public static void main(String[] args) {

		// 년도 입력
		Scanner sc = new Scanner(System.in);
		int y = sc.nextInt();

		if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0)
			System.out.println("윤년");
		else
			System.out.println("평년");
	}
}

 

제네릭을 이용하여 String값을 Key로 하고, Integer를 Value로 저장하는 HashMap을 생성하는 코드

HashMap<String, Integer> hm = new HashMap<String, Integer>();


String 클래스를 이용하여 ‘your’ 가 출력되도록 하기

public class Test {
    public static void main(String[] args){
        String str = "Do your best";
        System.out.println(str.substring(3, 7));
    }
}

 

접근 제어자 중 default로 지정한 멤버의 사용 범위

default 접근제어자를 쓰면
같은 클래스 내에서 접근 가능하다
같은 패키지 내에서 접근 가능하다
다른 패키지에서 접근 불가능하다

 

60과 24의 최대 공약수를 구하는 프로그램

package p2022_07_20;

public class Test2 {
	public static void main(String[] args) {
//		60과 24의 최대 공약수를 구하는 프로그램을 작성 하시오?

		int result = program(60, 24);
		System.out.println("최대공약수 : " + result);

	}

	public static int program(int n1, int n2) {
		int max = n1 >= n2 ? n1 : n2;
		int min = n1 <= n2 ? n1 : n2;
		int i = -1;

		for (i = min; i >= 1; i--) {
			if (max % i == 0 && min % i == 0)
				break;
		}
		return i;
	}
}

 

1~45사이의 숫자를 6개 중복없이 추출 하는 프로그램을 작성 하시오?

package p2022_07_20;

import java.util.Random;
import java.util.TreeSet;

public class Test3 {

	public static void main(String[] args) {

//		1~45사이의 숫자를 6개 추출 하는 프로그램을 작성 하시오? (단, 중복된 숫자는 1번만 출력 되도록 한다.)
		
		Random r = new Random();
		TreeSet ts = new TreeSet();

		while (ts.size() < 6) {
			ts.add(r.nextInt(45) + 1);
		}

		System.out.println("로또 번호 : " + ts);

	}

}

 

 

점수

100 / 100

문제

이렇게 출력하기

 


깃허브
https://github.com/kindacool/etc

 

GitHub - kindacool/etc

Contribute to kindacool/etc development by creating an account on GitHub.

github.com

 

 

코드

package p2022_07_14;

public class PrintAlphabet {

	public static void main(String[] args) {

//		A
//		C   B
//		D   E   F
//		J   I   H   G
//		K   L   M   N   O

		final int len = 5;
		char startA = 'A';
		char[][] c = new char[5][5];

		for (int i = 0; i < len; i++) {
			if (i % 2 == 0) { // o
				for (int j = 0; j <= i; j++) {

					c[i][j] = startA++;

				}
			} else if (i % 2 == 1) {
				for (int j = i; j >= 0; j--) {

					c[i][j] = startA++;

				}
			}
		}

		// 출력
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				System.out.print(c[i][j] + " ");
			}
			System.out.println();
		}

	}

}

 

 

출력

 

문제

1   2   3   4   5
5   1   2   3   4
4   5   1   2   3
3   4   5   1   2
2   3   4   5   1

 

2차원 배열을 이용해서 이렇게 출력하기

코드를 좀 더 깔끔하게 적었으면 좋았을텐데 라는 생각이 든다.나중에 수정해서 한번 더 올려야겠다

 

 

깃허브

https://github.com/kindacool/etc/blob/main/PrintSquare2.java

 

GitHub - kindacool/etc

Contribute to kindacool/etc development by creating an account on GitHub.

github.com

 

 

코드

package p2022_07_13;

public class PrintSquare2 {

	public static void main(String[] args) {

//		   1  2  3  4  5
//		   5  1  2  3  4
//		   4  5  1  2  3
//		   3  4  5  1  2
//		   2  3  4  5  1

		final int len = 5;
		int[][] num = new int[5][5];

		for (int i = 0; i < len; i++) {

			for (int j = 0; j < len; j++) {

				if (j + 1 - i <= 0) {
					num[i][j] = (j + 1) - i + 5;
				} else {
					num[i][j] = (j + 1) - i;
				}

			}

		}

		// 출력
		for (int i = 0; i < 5; i++) {

			for (int j = 0; j < 5; j++) {
				System.out.print(num[i][j] + " ");
			}
			System.out.println();
		}
	}
}

 

 

출력

문제

1  2  3  4  5 
2  3  4  5  1 
3  4  5  1  2 
4  5  1  2  3 
5  1  2  3  4 

 

1차원 배열을 이용해서 이렇게 출력하기

 

깃허브

https://github.com/kindacool/etc/blob/main/PrintSquare.java

 

GitHub - kindacool/etc

Contribute to kindacool/etc development by creating an account on GitHub.

github.com

 

 

코드

package p2022_07_13;

public class PrintSquare {
//	1 2 3 4 5 
//	2 3 4 5 1 
//	3 4 5 1 2 
//	4 5 1 2 3 
//	5 1 2 3 4 
	public static void main(String[] args) {

		final int len = 5;
		int[] num = { 1, 2, 3, 4, 5 };
		int start = 0;
		for (int k = 0; k < len; k++) {
			{
				for (int i = start; i < len + start; i++) {

					if (i < 5)
						System.out.print(num[i] + " ");
					else
						System.out.print(num[i - len] + " ");

				}
				System.out.println();
				start++;
			}
		}
	}
}

 

 

출력

 과제
2022.07.13 / Hw1

      File 클래스를 이용해서 C 드라이브의  test 폴더에  파일들이 
      들어있는 경우에  test폴더를 삭제하는 프로그램을 작성하세요

 

 

의도

File 클래스 사용

File 클래스 delete() 메소드 사용

File 클래스 listFiles() 메소드 사용

 

 

깃허브

https://github.com/kindacool/Hw/blob/main/HW20220713/FileTestHw.java

 

GitHub - kindacool/Hw

Contribute to kindacool/Hw development by creating an account on GitHub.

github.com

 

 

코드

package p2022_07_13;

import java.io.*;

public class FileTestHw {

	public static void main(String[] args) {
		try {
			File tempFileHw = new File("testhw");
			System.out.println("create directory state : " + tempFileHw.mkdirs());
			
			// 2. 비어있지 않는 디렉토리 삭제(과제)
			File[] fileList = tempFileHw.listFiles();
			for (int i = 0; i < fileList.length; i++) {
				fileList[i].delete();
			}
			tempFileHw.delete();
			
		} catch (Exception e) {
		}
	}
}

 

과제 풀이
https://laker99.tistory.com/23?category=1065834

 

		System.out.printf("%.2f", l);

- 소숫점 둘째자리까지(%.2) 출력하고 실수형태(%f) 로 출력

 

		DecimalFormat df = new DecimalFormat("0.00"); //내 코드
		DecimalFormat df = new DecimalFormat("###.00"); //강사님 코드

- 0과 #은 의미가 다르다. 
- ###을 넣으면 두자리여도 두자리만 표시하고 세자리면 세자리로 표시한다.
- 000을 넣으면 0은 무조건 자리를 채워넣는 형식, 31.42인 값이 031.42 로 표시된다.


상속을 쓰는 이유
- 중복코드를 줄이기 위해서
- 통일성있는 클래스를 설계하기 위해서
- 그래픽프로그램에서 상속을 많이 사용한다
- 나중에 JSP model2 = MVC 패턴개발 를 할때 클래스가 많을때 사용한다

자바에서 그래픽 프로그램
- CUI(Console User Interface)
- GUI(Graphic User Interface)

그래픽 프로그램 관련 패키지
- java.awt.*
- javax.swing.*
- javafx.*
- 여기 그래픽 프로그램 만들기 위한 클래스들이 모여있다
- 그래픽 프로그램에서 상속을 많이 사용함
- 캔버스, 체크박스, 프레임, 스크롤바, 메뉴, 텍스트필드 등 만들 수 있다

상속관련 용어 정리
- 부모클래스 = 상위클래스 = 슈퍼클래스
- 자식클래스 = 하위클래스 = 서브클래스 = 파생클래스

단일상속
- 자바는 단일상속만 가능
- 두개이상의 클래스로부터 상속받을수없다(C++, Python은 가능)

+ 부모클래스로 객체를 만드는게 의미없다(상속)
+ 자식클래스로 객체를 만드는게 의미있다(부모클래스의 필드와 메소드도 받았으므로)

패키지와 파일
- 한개 파일에 클래스 여러개 들어가도된다
- 나중에 컴파일될때 바이트코드는 클래스별로 따로따로 만들어짐
- 패키지는 폴더를 의미한다

 

상속 예제1
- SuperSub01.java 
- 자식클래스명 옆에 extends 옆에 부모클래스명을 쓰자

package p2022_07_05;

class Parent {
	public void parentPrn() {	//부모 클래스
		System.out.println("슈퍼 클래스 메서드는 상속된다.");
	}
}

//Parent를 슈퍼 클래스로 하는 서브 클래스 Child 정의 
class Child extends Parent {	//자식 클래스
	public void childPrn() {
		System.out.println("서브 클래스 메서드는 슈퍼가 사용 못한다.");
	}
}

//Parent를 슈퍼 클래스로 하는 서브 클래스 Child 정의
//Parent클래스의 parentPrn() 메소드는 자식 클래스에 상속된다.
class SuperSub01 {
	public static void main(String[] args) {
		Child c = new Child(); // 서브 클래스로 객체를 생성
		c.parentPrn(); // 슈퍼 클래스에서 상속 받은 메서드 호출
		c.childPrn(); // 서브 클래스 자기 자신의 메서드 호출
		System.out.println("-------------------------------------->> ");
		Parent p = new Parent(); // 슈퍼 클래스로 객체 생성
		p.parentPrn(); // 슈퍼 클래스 자기 자신의 메서드 호출
		// p.childPrn( ); //서브 클래스 메서드는 가져다 사용 못함
	}
}

- 상속은 부모가 자식에게 일방적으로 주는것만 가능하다
- 부모클래스는 자식클래스의 멤버(필드나 메소드) 사용불가!

 

상속 예제2
- SuperSub04.java

package p2022_07_05;

class Point2D { // 부모 클래스
	protected int x = 10; // private int x=10;
	protected int y = 20; // private int y=20;
}

// 부모 클래스의 필드의 접근제어자가 private이면 자식이 접근할 수 없다.(상속 불가), 여기선 오류 발생
class Point3D extends Point2D { // 자식 클래스
	protected int z = 30;

	public void print() {
		System.out.println(x + ", " + y + ", " + z);
	}
}

class SuperSub04 {
	public static void main(String[] args) {
		Point3D pt = new Point3D();
		pt.print();
	}
}

- Point2D클래스가 부모클래스, 안의 필드 x, y 의 접근제한자가 protected
- Point3D클래스가 Point2D 클래스를 상속받음
- Point3D의 필드 protected int z, 메소드 print();
- 메인메소드가 있는 클래스 SuperSub04
- 메인메소드에서 Point3D 클래스로 객체를 생성하고 pt.print()로 메소드 호출
- 그럼 이 print()에서 x,y는 자기 클래스의 멤버는 아니지만 부모 클래스의 멤버이므로
자기거인것처럼 출력하는 것임

 

- 이때 접근 제어자, Point2D의 접근제어자를 private으로 두면? 오류발생, 자식 클래스에 상속 안된다!
- 부모클래스의 필드/메소드가 private이면 자식클래스라도 외부클래스이므로 접근불가, 상속을 못함
- private만 아니면 다 됨, default, public, protected는 다 상속 된다

 

접근제어자 protected
- 상속에선 나중에 접근제어자를 protected를 많이 씀
- 심지어 패키지가 달라져도 상속관계에 있을때는 자식이 접근 가능하다

패키지가 달라져도 접근가능한 경우
1. public인 경우
2. protected이고 상속관계인 경우 자식이 부모클래스 필드/메소드 접근

* 자바의 접근 제어자


1. 상속 관계가 있는 경우에 2개의 클래스(부모,자식 클래스)가 같은 패키지 안에 들어 있을때는 부모의 접근제어자가 default, protected, public 접근제어자인 경우에 자식클래스에서 접근 할수 있다. (단, private접근 제어자만 자식 클래스에서 접근 할 수 없음)

2. 상속 관계가 있는 경우에 2개의 클래스(부모,자식 클래스)가 다른 패키지 안에 들어 있을때는부모의 접근제어자가 protected, public 접근제어자인 경우에 자식클래스에서 접근 할수 있다. 

3. 상속 관계가 없는 경우에 2개의 클래스가 서로 다른 패키지 않에 들어 있을때는 public 접근제어자로 되어 있어야만 다른 클래스에서 접근 할 수 있다.

+ 메소드 오버라이딩
- 상속에서 가장 중요한 개념
- 반드시 상속이 전제되어야만 쓸 수 있다.
- 메소드는 상속이 되지만, 부모로 부터 상속받은 메소드를 이름과 형식은 같게 하지만 안의 내용을 다르게 하는것
- 나중에 자세히 공부할것

 

상속 예제 3-1 (필드)
- SuperTest02.java

package p2022_07_05;

//부모 클래스 안에 있는 필드는 자식 클래스에게 상속된다.
class Point2D2 {	//부모 클래스
	protected int x = 10;
	protected int y = 20;
}

class Point3D2 extends Point2D2 {	//자식 클래스
	protected int z = 30;

	public void print() {
		System.out.println(x + ", " + y + ", " + z); // x와 y는 상속 받아 사용하는 멤버변수
	}
}

class SuperTest02 {
	public static void main(String[] args) {
		Point3D2 pt = new Point3D2();
		pt.print();
	}
}

+ protected이므로 상속 가능
- 이 예제는 필드 중복 그거 아니고 다음 예제이다
- 위 예제는 그냥 부모 클래스 안에 있는 필드는 자식 클래스에게 상속된다는걸 보여주는 예제

- 그럼 부모클래스에 있는 필드 x, y 를 상속받은 자식 클래스에서 똑같은 이름 x, y으로 필드를 정의해보자
- 자식클래스로 객체 만들어서 필드값출력할떄 어느값을 출력하는가?
-> 새로정의한 x, y값만 출력됨.
- 다음 예제에서 설명

 

상속 예제 3-2 (필드의 상속)
- SuperTest03.java

package p2022_07_05;
//부모 클래스에 있는 필드를 자식 클래스에서 재정의(동일한 이름의 변수)하면,
//자식 클래스에서 재 정의한 필드만 사용 가능하다.
class Point2D3 {	//부모 클래스
	protected int x = 10; // Point3D에서 다시 한번 정의되므로 은닉 변수가 됨
	protected int y = 20; // 은닉 변수는 쉐도우 변수라고도 함
}

class Point3D3 extends Point2D3 {	//자식 클래스
	protected int x = 40; // 슈퍼 클래스에 존재하는 멤버변수를
	protected int y = 50; // 서브 클래스에 다시 한 번 정의함

	protected int z = 30;

	public void print() {
		System.out.println(x + ", " + y + ", " + z); // x와 y는 재 정의된 Point3D 클래스 소속
	}
}

class SuperTest03 {
	public static void main(String[] args) {
		Point3D3 pt = new Point3D3();
		pt.print();
	}
}
40, 50, 30

- x, y가 중첩되고 있다
- 결론은 새로정의한 x, y값만 출력됨, 즉 10, 20 대신 40, 50 이 출력됨
- 기존에 상속해준 부모 클래스의 x, y 필드는 더이상 사용이 되지않음, 은닉이된다
-> 이 변수를 은닉 변수 = 쉐도우 변수 라고 함
- 이 은닉 변수들에 굳이 접근하고 싶으면 super. 을 사용해서 접근한다!

필드의 상속 정리
- 부모 클래스에 있는 필드를 자식 클래스에서 재정의(동일한 이름의 변수)하면, 자식 클래스에서 재정의한 필드만 사용 가능하다.

은닉 변수에 접근
- super.x, super.y 하면 은닉변수에 접근가능하다
- 쓸 일이 많지 않다

은닉 변수에 접근 예시
- 은닉변수에 굳이 접근하려면 super. 해서 접근
- 부모 클래스에 접근해서 값을 구해오라는 의미
- SuperTest04.java

package p2022_07_05;

//super : 부모 클래스를 의미함
//super.x 는 부모 클래스의 은닉된 필드를 호출할 때 사용된다.
//super.x 는 "자식클래스"의 "메소드 안"에서만 사용할 수 있다. (주의)
//그 외의 장소에서 System.out.println(super.x); //오류 발생

class Point2D4 { // 부모 클래스
	protected int x = 10; // 은닉 변수
	protected int y = 20; // 혹은 쉐도우 변수
}

class Point3D4 extends Point2D4 { // 자식 클래스
	protected int x = 40; // 슈퍼 클래스에 존재하는 멤버변수를
	protected int y = 50; // 서브 클래스에 다시 한 번 정의함

	protected int z = 30;
	// System.out.println(super.x); 메소드 내부가 아니므로 오류

	public void print() {
		System.out.println(x + ", " + y + ", " + z); // x와 y는 재 정의된 Point3D 클래스 소속
	}

	public void print02() {
		System.out.println(super.x + ", " + super.y + ", " + z); // Point2D 클래스 소속 멤버변수로 접근
	}
}

class SuperTest04 {
	public static void main(String[] args) {
		Point3D4 pt = new Point3D4();
		pt.print(); // 40, 50, 30 // Point3D의 x, y
		pt.print02(); // 10, 20, 30 // Point2D의 x, y

		System.out.println(pt.x); // 40
	}
}
40, 50, 30
10, 20, 30
40

 

은닉 변수에 접근 정리
- super : 부모 클래스를 의미함
- super.x 는 부모 클래스의 은닉된 필드를 호출할 때 사용된다.
- super.x 는 "자식클래스"의 "메소드 안"에서만 사용할 수 있다. (주의)
- 그 외의 장소에서 System.out.println(super.x); //오류 발생

super 와 this
- super : 부모 클래스를 의미하는 일종의 레퍼런스 변수
- this : 자기 클래스를 의미하는 일종의 레퍼런스 변수

* this와 super
this. : 생성자와 메소드에서 매개변수와 멤버변수 이름이 동일한 경우에 사용

this() : 같은 클래스내에 있는 다른 생성자를 호출(다른 클래스 내의 생성자는 이걸로 호출하지않음)
super. : 부모 클래스에 있는 은닉된 멤버변수와  메소드를 호출  할때 사용, 반드시 자식 클래스의 메소드 내에 써야만 사용가능하다. 자식 클래스의 메소드 밖이나 다른 클래스 내에서 사용불가
super() : 부모 클래스의 매개변수를 가진 생성자를 호출 할 때 사용

메소드로의 적용 (메소드 오버라이딩)
- 필드에서 재정의된 필드가 사용되는 것 처럼 메소드도 마찬가지이다.
- 메소드는 메소드 오버라이딩이라고 하지만 필드는 이런거 따로 부르는 이름이 없다
- 결론적으론 메소드도 새로 정의된 메소드 오버라이딩된 메소드만 호출됨

- 부모 클래스의 메소드는 은닉 메소드가 됨, 굳이 호출하고 싶으면 super.메소드() 로 호출하면된다
- 필드때처럼 부모의 메소드와 똑같은 이름 + 똑같은 형식 으로 메소드를 만들어야함
- 메소드 오버라이딩(Method Overriding), 동일이름 동일형식 다른내용 상속전제 필수

메소드 오버라이딩 예제

- SuperSub05.java 

package p2022_07_05;

// 메소드 오버라이딩(Method Overriding)
// : 부모 클래스로부터 상속받은 메소드를 자식 클래스에서 재정의 해서 사용하는 것.
// 1. 부모 클래스로부터 상속받은 메소드를 자식 클래스에서 메소드 오버라이딩을 하면
//  메소드 오버라이딩 된 메소드만 호출되고, 부모 클래스의 메소드는 은닉이 되어서
//  자식클래스에 상속되지 않는다.
// 2. 부모 클래스에 은닉된 메소드를 호출할 때는 자식클래스의 메소드 안에서
//  super.parentPrn() 형식으로 호출해야 된다.

class Parent05 {	//부모 클래스
	public void parentPrn() {	//은닉 메소드가 된다
		System.out.println("슈퍼 클래스 : ParentPrn 메서드");
	}
}

//Parent05를 슈퍼 클래스로 하는 서브 클래스 Child05 정의 
class Child05 extends Parent05 {	//자식 클래스
//	super.parentPrn(); //오류 발생, 자식클래스의 메소드 내부여야함
	
	// 슈퍼 클래스에 있는 ParentPrn 메서드를 오버라이딩하면
	// Child05로 선언된 객체는 슈퍼 클래스의 메서드가 은닉되어 상속 받지 못하게 된다.
	public void parentPrn() {	// 메소드 오버라이딩(Method Overriding), 동일이름 동일형식 다른내용 상속전제 필수
		System.out.println("서브 클래스 : ParentPrn 메서드");
	}

	public void childPrn() {	// 자식 클래스만 있는 메소드
		super.parentPrn();	//부모 클래스의 은닉 메소드 호출
		System.out.println("서브 클래스 : ChildPrn 메서드");
	}
}

class SuperSub05 {
	public static void main(String[] args) {
		Child05 c = new Child05(); // 서브 클래스로 객체를 생성
		c.parentPrn(); // 오버라이딩된 서브 클래스의 메서드 호출(새로 정의된, 오버라이딩된 메소드만 호출됨)
		c.childPrn(); // 서브 클래스 자기 자신의 메서드 호출
		System.out.println("-------------------------------------------->> ");
		Parent05 p = new Parent05(); // 슈퍼 클래스로 객체를 생성
		p.parentPrn(); // 슈퍼 클래스(자기 자신)의 메서드 호출
	}
}
서브 클래스 : ParentPrn 메서드
슈퍼 클래스 : ParentPrn 메서드
서브 클래스 : ChildPrn 메서드
-------------------------------------------->>
슈퍼 클래스 : ParentPrn 메서드

- 은닉된 메소드도 호출할때는 super.메소드() 로 호출하면 호출된다!
- super.메소드() 를 쓰는 위치는 필드랑 동일하게 자식 클래스의 메소드 안에서 사용해야함 (주의)
ex) super.parentPrn();을 자식 클래스의 메소드 밖에서 쓰면 오류 발생함

 

- 메소드 오버라이딩을 하면 오버라이딩된 메소드만 호출된다.
- 부모클래스로부터 상속된 메소드는 사용이 더이상되지않고 은닉메소드가 된다
- 은닉메소드를 굳이 호출될때는 자식 클래스의 메소드 내에서 super.메소드() 로 호출

 

메소드 오버라이딩(Method Overriding) 정리
- 부모 클래스로부터 상속받은 메소드를 자식 클래스에서 재정의 해서 사용하는 것.
- 부모 클래스로부터 상속받은 메소드를 자식 클래스에서 메소드 오버라이딩을 하면 메소드 오버라이딩 된 메소드만 호출되고, 부모 클래스의 메소드는 은닉이 되어서 자식클래스에 상속되지 않는다.
- 부모 클래스에 은닉된 메소드를 호출할 때는 자식클래스의 메소드 안에서 super.parentPrn() 형식으로 호출해야 된다.

* 메소드 오버라이딩(Method Overriding)
- 부모 클래스로 부터 상속받은 메소드를 자식 클래스에서 재정의 해서 사용하는것

- Spring , JSP 할 때도 계속 따라가는 개념이므로 잘 익혀둬야 한다.

 

은닉 정리
- 결과적으로 자식 클래스에서 재정의 시 부모클래스안의 상속이 되는 필드, 메소드는 상속이 되지 않는다
- 은닉이 됨. 사용하려면 자식클래스의 메소드 안에서 super.필드명, super.메소드명() 으로 호출가능하다

+ 메소드 오버라이딩을 해도 되고 안해도 되지만 곧 배울 추상클래스, 인터페이스의 경우에는 반드시 메소드 오버라이딩을 해야하는 경우가 있다, 하지 않으면 오류 발생
+ 상속에서는 메소드와, 메소드 오버라이딩이 제일 중요하다

생성자와 상속
- 기본적으로 생성자는 상속되지 않는다, 어떻게 쓸까?
- 자식 클래스의 객체를 생성할때, 자식 클래스의 생성자가 호출되면 부모 클래스의 기본 생성자를 연쇄적으로 호출해줌
- 자식 클래스의 생성자는 기본생성자 여도 되고 매개변수를 가진 생성자여도 상관없음
- 이때 부모 클래스의 생성자는 "기본 생성자"만 호출되어 실행이됨

 

생성자와 상속 예제
- SuperTest05.java

package p2022_07_05;

class Point2D05 {	//부모 클래스
	protected int x = 10;	//필드
	protected int y = 20;

	public Point2D05() {	//부모클래스의 기본 생성자
		System.out.println("슈퍼 클래스인 Point2D 생성자 호출");
	}
}

class Point3D05 extends Point2D05 {	//자식 클래스
	protected int z = 30;

	public void print() {
		System.out.println(x + ", " + y + ", " + z);
	}

	public Point3D05() {	//자식클래스의 기본 생성자
		System.out.println("서브 클래스인 Point3D 생성자 호출");
	}
}

class SuperTest05 {
	public static void main(String[] args) {
		Point3D05 pt = new Point3D05();	//자식클래스의 기본생성자 호출
		pt.print();
슈퍼 클래스인 Point2D 생성자 호출
서브 클래스인 Point3D 생성자 호출
10, 20, 30

- 즉, main메소드에서 자식클래스의 생성자가 먼저 호출되었지만 실행 결과는 부모클래스의 기본 생성자의 출력문이 먼저 출력됨
- Point3D05 클래스의 기본 생성자가 호출되면 부모 클래스인 Point2D05 클래스의 기본 생성자를 호출함
- 그러므로 "슈퍼 클래스인 Point2D 생성자 호출" 출력 다음 "서브 클래스인 Point3D 생성자 호출" 메세지를 출력한다
- 부모 클래스의 기본생성자 만들어놓지 않으면 컴파일러가 자동으로 만듬
- 지금처럼 기본생성자 만들어뒀을때는 객체 생성할때 부모 클래스의 기본 생성자를 호출함

생성자와 상속 정리
* 상속에서의 생성자
1. 생성자는 기본적으로 상속이 되지 않는다
2. 자식클래스를 이용해서 객체를 생성할때 자식클래스의 생성자(기본생성자,매개변수 있는 생성자 모두 가능)가 호출되면, 부모클래스의 기본생성자가 자동으로 호출된다.
3. 매개변수가 있는 생성자가 있는 경우에는 더이상 컴파일러가 기본 생성자를 자동으로 생성해 주지 않는다.
4. 부모 클래스의 매개변수가 있는 생성자를 자식 클래스에서 호출 할때는 super()를 이용해서 호출할 수 있다. 단, super()는 자식 클래스의 생성자 안에서만 사용 가능함.

부모클래스의 기본생성자 호출
- 심지어 부모 클래스 쪽에 기본생성자가 없어도 된다.
- 자식생성자가 부모 클래스의 기본생성자를 만들어서 호출해줌
- 또한 자식 클래스 쪽에 기본생성자가 없어도 된다, 컴파일러가 자동으로 기본클래스를 생성 후 부모 클래스의 기본 생성자 호출
- 만약 부모 클래스의 기본생성자가 아닌 매개변수가 있는 생성자를 호출하고 싶다면, super()로 명시적으로 호출해줘야지만 부모클래스의 매개변수가 있는 생성자를 호출 할 수 있다

 

- 자식클래스는 매개변수 있는 상속자여도 된다

	public Point3D05(int a) {	//자식클래스의 기본 생성자
		System.out.println("서브 클래스인 Point3D 생성자 호출");
	}
// main
	Point3D05 pt = new Point3D05(30);	//자식클래스의 기본생성자 호출

- 이어도 문제 없고 부모클래스의 기본생성자를 호출함 또한

	public Point3D05() {	//자식클래스의 기본 생성자
		System.out.println("서브 클래스인 Point3D 생성자 호출");
	}

- 이 코드(자식클래스의 기본생성자) 를 주석으로 막아도 컴파일러가 자동으로 기본클래스를 생성
- 또한 연쇄적으로 부모클래스의 기본 생성자도 호출됨

 

부모클래스의 기본생성자 호출 정리
- 자식클래스는 기본생성자여도 되고 매개변수가 있는 생성자여도 됨
- 부모클래스는 기본생성자만 연쇄적으로 자동적으로 호출해주게 되고, 매개변수가 있는 생성자는 우리가 super()로 명시해서 직접 호출해 줘야함

 

부모클래스에 기본생성자가 없다면
- 부모클래스에서 이미 매개변수가 있는 생성자가 있는경우 기본생성자가 자동으로 만들어지지 않는다
- 그래서 기본생성자를 내가 명시해서 만들어주지 않으면 자식클래스의 생성자에도 오류가 생김

부모클래스에 기본생성자가 없다면 예제/super() 통해서 호출하는 예제
- SuperTest06.java
- 이 예제에선 부모클래스에서 이미 매개변수가 있는 생성자가 있으므로 기본생성자가 만들어지지 않는다
-> 그래서 기본생성자를 내가 명시해서 만들어주지 않으면 자식클래스의 생성자에도 오류가 생김

	public Point2D06( ){ System.out.println("슈퍼 클래스인 Point2D 생성자 호출"); }

- 부모 클래스의 기본 생성자 주석을 풀어야만 자식클래스에서 오류가 생기지 않음
- 부모의 기본생성자를 자식 객체 생성될때 연쇄호출됨
- 부모 클래스에서 매개변수가 있는 생성자는 자식 클래스의 생성자에서 호출해주지 않는다, super() 로 호출해야함
- 그리고 부모 클래스에서 매개변수가 있는 생성자가 있고 기본 생성자가 적혀져있지 않으면 기본생성자는 자동으로 만들어지지 않는다
- 이런 경우에는 기본생성자를 명시해주지 않으면 자식 생성자쪽에서 오류가 남.

+ 매개변수가 있는 생성자가 있을때는 예외적으로 컴파일러가 기본생성자를 생성해주지 않는다.

- 물론 자식 클래스에서 호출하지 않을때는 안만들어도 되지만 자식 클래스 쪽에서 호출을 할떄는 부모클래스의 기본생성자가 필요하고, 부모 클래스의 기본생성자 없으면 오류남
- 지금은 자식 클래스의 생성자가 호출되므로 부모 클래스의 기본 생성자도 호출되기때문에 부모클래스의 기본 생성자가 필요하다

 

부모클래스의 매개변수가 있는 생성자 호출하는 방법
- 자식클래스에서 super() 형태로 호출해야함
- super()는 자식클래스의 생성자 내부 첫번째 라인에 써야함! 위치가 정해져있다

package p2022_07_05;

//super()
//1. super()는 부모 클래스의 매개변수를 가진 생성자를 호출할 때 사용한다.
//2. super()는 자식 클래스의 생성자 안에서 첫번째 라인에 사용해야 한다.
//3. super()를 이용해서 부모 클래스의 매개변수를 가진 생성자를 호출하면,
//더이상 부모클래스의 기본생성자를 호출해주지 않는다.


class Point2D06 { // 부모 클래스
	protected int x = 10; // 필드
	protected int y = 20;
	
	// 매개변수가 있는 생성자가 있을때는 예외적으로 컴파일러가 기본생성자를 생성해주지 않는다.
	public Point2D06() { //기본 생성자
		System.out.println("슈퍼 클래스인 Point2D 생성자 호출"); 
	}

	public Point2D06(int xx, int yy) {
		x = xx;
		y = yy;
	}
}

class Point3D06 extends Point2D06 {	//자식 클래스
	protected int z = 30;

	public void print() {
		System.out.println(x + ", " + y + ", " + z);	//상속받은 필드 x, y
	}

	public Point3D06() {	//자식 클래스의 기본 생성자
		super(50,60);	// 부모 클래스의 매개변수가 있는 생성자 호출
		System.out.println("서브 클래스인 Point3D 생성자 호출");
	}
}

class SuperTest06 {
	public static void main(String[] args) {
		Point3D06 pt = new Point3D06();	//자식 클래스의 생성자 호출
		pt.print();
	}
}
서브 클래스인 Point3D 생성자 호출
50, 60, 30

- 부모클래스의 매개변수 2개인 생성자가 호출되면서 x값이 50, y값이 60이 되는 것이다.

 

위 예제 처리과정
1. 메인메소드에서 먼저 Point3D06이란 자식클래스의 생성자를 호출한다
2. 자식클래스의 생성자가 호출됨, 내부 코드를 실행함
3. 원래는 자식클래스의 생성자가 호출되면 연쇄적으로 부모클래스의 기본 생성자를 호출함
4. 근데 여기선 super()를 썼으므로 super()가 우선이 됨 
- super()를 통해 호출된 부모클래스의 매개변수있는 생성자가 호출되면 부모클래스의 기본생성자는 호출되지 않음
5. 그래서 "슈퍼 클래스인 Point2D 생성자 호출" 은 출력되지 않았고 값은 50, 60으로 변경됨
- 즉 매개변수를 가진생성자만 호출되었다는 의미


Point2D06 (부모)클래스의 매개변수 2개인 생성자를 호출하고 싶다면? (위 예제 부분1)

	public Point2D06(int xx, int yy) {
		x = xx;
		y = yy;
	}

- 이걸 호출하고 싶으면 자식클래스의 생성자 내부

	public Point3D06() {	//자식 클래스의 기본 생성자
		super(50,60);
		System.out.println("서브 클래스인 Point3D 생성자 호출");
	}

- 에서 super()를 통해서 부모 클래스의 매개변수가 2개인 생성자를 호출한다
- 부모 클래스의 기본생성자 주석으로 막아도 오류 안생김

 

super() 유의사항
- super()는 자식클래스의 생성자 안에서만 사용가능하다
- 생성자 내부의 첫번째 라인만 가능하다! 다른 장소에 들어가면 오류 발생한다
- 자식 생성자가 호출되면 부모의 기본생성자가 호출되지만 자식 생성자 내에서 super()를 써서 매개변수 있는 생성자 호출할떄는
부모의 기본생성자는 호출되지 않는다.
- super()가 우선순위 높다, super()쓰면 기본생성자 호출안해줌 
- 동시에 2개(기본 생성자, 매개변수가 있는 생성자) 호출해주지 않는다
- super()는 메소드 안에 못쓴다.
- super()가 우선순위 높다, super()쓰면 기본생성자 호출안해줌 

super() 정리
1. super()는 부모 클래스의 매개변수를 가진 생성자를 호출할 때 사용한다.
2. super()는 자식 클래스의 생성자 안에서 첫번째 라인에 사용해야 한다.
3. super()를 이용해서 부모 클래스의 매개변수를 가진 생성자를 호출하면, 더이상 부모클래스의 기본생성자를 호출해주지 않는다.

super. 와 super()의 차이
- super. : 메소드 오버라이딩 되었을때 부모클래스 안의 필드, 메소드를 호출할 때 사용, 잘 안 쓴다
- super() : 자식클래스에서 부모 클래스의 매개변수를 가진 생성자를 호출할 때 사용, 잘 쓴다

+ super() 는 그래픽 프로그램 예제 다룰 때 썼었다
- FrameTestEx extends Frame 클래스의 생성자  첫번째 라인에서 super("Frame Test"); 라고 썼다. 
- 자기 부모의 매개변수가 있는 생성자를 호출하라는 의미로서 부모인 Frame클래스의 매개변수가 String인 생성자를 호출하고 있다

 

this. 예제
- DMBCellPhone.java

package p2022_07_05;
// p290 ~ 292

class CellPhone{							// 부모 클래스
	String model;							// 필드
	String color;
	
	void powerOn() {						// 메소드
		System.out.println("전원을 켭니다.");
	}
	void powerOff() {
		System.out.println("전원을 끕니다.");
	}
	void bell() {
		System.out.println("벨이 울립니다.");
	}
	void sendVoice(String message) {
		System.out.println("자기:"+message);
	}
	void receiveVoice(String message) {
		System.out.println("상대방:"+message);
	}
	void hangUp() {
		System.out.println("전화를 끊습니다.");
	}	
}

// 부모 클래스의 필드와 메소드는 상속된다.
class DMBCellPhone extends CellPhone{	// 자식 클래스
	int channel;

	public DMBCellPhone(String model, String color, int channel) {
		this.model = model;				// 자바폰
		this.color = color;				// 검정
		this.channel = channel;			// 10
	}
	
	void turnOnDmb() {
		System.out.println("채널:"+channel+"전 DMB방송 수신을 시작 합니다.");
	}
	void changeChannelDmb(int channel) {
		this.channel = channel;
		System.out.println("채널"+channel+"번으로 바꿉니다.");
	}
	void turnOffDmb() {
		System.out.println("DMB방송 수신을 멈춥니다.");
	}	
}

public class DMBCellPhoneEx {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		DMBCellPhone dmb = new DMBCellPhone("자바폰", "검정", 10);
		
		// model, color 필드는 부모 클래스로 부터 상속 받아서 사용
		System.out.println("모델:"+dmb.model);
		System.out.println("색상:"+dmb.color);
		System.out.println("채널:"+dmb.channel);

		// 부모 클래스로 부터 상속 받아서 사용되는 메소드
		dmb.powerOn();
		dmb.bell();
		dmb.sendVoice("여보세요");		
		dmb.receiveVoice("안녕 하세요! 저는 홍길동 입니다.");		
		dmb.sendVoice("아~ 예 반갑습니다.");		

		dmb.turnOnDmb();
		dmb.changeChannelDmb(12);
		dmb.turnOffDmb();		
	}

}

 

위 예제 부분 1

		DMBCellPhone dmb = new DMBCellPhone("자바폰", "검정", 10);

위 예제 부분 2

	public DMBCellPhone(String model, String color, int channel) {
		this.model = model;				// 자바폰
		this.color = color;				// 검정
		this.channel = channel;			// 10
	}

- DmbCellPhone 클래스의 생성자에서 초기화할때 상속받은 필드들도 다 초기화하고 있다
- this. 써서 가능 model과 color는 상속을 받아 쓰는것

 

위 예제 부분 3

	void changeChannelDmb(int channel) {
		this.channel = channel;
		System.out.println("채널"+channel+"번으로 바꿉니다.");
	}

- DmbCellPhone 클래스의 메소드인 changeChannelDmb()에서 매개변수와 필드가 이름이 같기때문에 여기서도 this. 를 쓴다

 

위 예제 부분 4

		// 부모 클래스로 부터 상속 받아서 사용되는 메소드
		dmb.powerOn();
		dmb.bell();
		dmb.sendVoice("여보세요");		
		dmb.receiveVoice("안녕 하세요! 저는 홍길동 입니다.");		
		dmb.sendVoice("아~ 예 반갑습니다.");

- 상속받은 메소드를 자기것처럼 씀

+ Ctrl키 누르고 메소드명 클릭하면 그게 정의되어있는 곳으로 감! 파일 달라도 거기로 찾아감

 

메소드 오버라라이딩 예제
- ComputerEx.java

package p2022_07_05;
// p296 ~ 297
// 메소드 오버라이딩(Method Overriding)
// : 부모 클래스로 상속받은 메소드를 자식 클래스에서 재정의 해서 사용하는 것

class Calculator{						// 부모 클래스
	double areaCircle(double r) {
		System.out.println("Calculator 객체의 areaCircle() 실행");
		return 3.14159 * r * r;
	}
}

class Computer extends Calculator{		// 자식 클래스	

	@Override
	double areaCircle(double r) {		// 메소드 오버라이딩
//		super.areaCircle(r);
		System.out.println("Computer 객체의 areaCircle() 실행");
		// TODO Auto-generated method stub
		return Math.PI * r * r;
	}		
	
}

public class ComputerEx {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		int r = 10;
		Calculator cal = new Calculator();
		System.out.println("원의 면적:"+ cal.areaCircle(r));
		
		// 자식클래스에서 메소드 오버라이딩 된 메소드만 호출된다.
		Computer comp = new Computer();
		System.out.println("원의 면적:"+ comp.areaCircle(r));
	}

}

- 부모클래스로부터 상속받은 Computer 클래스는 메소드 오버라이딩을 수행한다.
- 이때, 부모클래스의 이름과 형식 (매개변수, 리턴형) 그대로 해야한다
- 만약 부모클래스의 메소드를 호출하고 싶다면 return super.areCircle(r)로 super. 를 쓰면 된다.

- 클래스를 상속받을땐 메소드 오버라이딩을 해도 되고 안해도 됨.
- 상속을 하더라도 메소드 오버라이딩 안해도 됨
- 이게 끝나면 추상클래스라는걸공부하는데 추상클래스가 extends뒤에 오게되면 반드시 메소드 오버라이딩을 해야함 

+ 인터페이스는 클래스처럼 extends로 상속받는게 아니라 implements 키워드로 상속을 받음
+ 직접 내가 클래스를 만들때 상속을 하려면 ex까지 쓰고 ctrl+ space하면 자동으로 입력됨

 

이클립스 메소드 오버라이딩 생성
- 이때 이클립스를 이용하면 메소드 오버라이딩 자동으로 만들어주는 기능 있다
- 주석으로 막고 이클립스로 메소드 오버라이딩 해보자

오른쪽 마우스 -> Source -> Override/Implement Methods
- 부모클래스, 조상클래스(Object등)가 보이고 그 안의 오버라이딩 할 메소드 선택 가능
- 원하는 메소드만 클릭해서 오버라이딩 하면 된다

- 그럼 이게 생성된다

	@Override
	double areaCircle(double r) {
		// TODO Auto-generated method stub
		return super.areaCircle(r);
	}

 

오버라이드 어노테이션

@Override

- 컴파일러가 이 어노테이션 만나면 아래쪽에 메서드가 오버라이딩 잘 되었는지 체크한다
- 이런역할을 어노테이션이 해줌
- 없어도 실행에 지장은 없다.

 

메소드 오버라이딩 정리
- 오버라이딩 하면 부모클래스의 메소드가 아닌 자식클래스에서 메소드 오버라이딩 된 메소드만 호출된다.
- 은닉된 메소드를 굳이 호출할떄는 자식 클래스의 메소드에서 super. 으로 호출한다
- 이 내용이 그 다음의 추상클래스, 인터페이스와 연결됨 거기선 반드시 메소드 오버라이딩을 해야함 

final 키워드
- 상속을 배우기 전 간단히 설명 했었다
- final 필드 : 수정 불가 필드 = 상수
- final 메소드 : 자식 클래스에서의 이 메소드 오버라이딩을 허용하지 않음 (마지막 메소드)
- final 클래스 : 상속을 허용하지 않는 클래스 (마지막 클래스)
- 여기서 final 메소드와 final 클래스를 볼 것

final 메소드
- 상속이 되더라도 메소드 오버라이딩 불가능 메소드 오버라이딩 하려하면 오류 발생시킴

final 클래스
- 해당 클래스를 상속 하려고 하면 오류 발생시킴

상속에서의 접근제어자
* 자바의 접근 제어자


1. 상속 관계가 있는 경우
1-1. 2개의 클래스(부모,자식 클래스)가 같은 패키지 안에 들어 있을때
- 부모의 접근제어자가 default, protected, public 접근제어자인 경우에 자식클래스에서 접근 할수 있다. 
- (단, private 접근제어자만 자식 클래스에서 접근 할 수 없음)

1-2. 2개의 클래스(부모,자식 클래스)가 다른 패키지 안에 들어 있을때
- 부모의 접근제어자가  protected, public 접근제어자인 경우에 자식클래스에서 접근 할수 있다. 

2. 상속 관계가 없는 경우
- 2개의 클래스가 서로 다른 패키지 안에 들어 있을때는 public 접근제어자로 되어 있어야만 다른 클래스에서 접근 할 수 있다.

import 기준
- 패키지가 달라질때 -> 반드시 import

패키지가 다를때 접근하는법
1. 접근제어자가 public 이면 다 됨
2. 두 클래스 상속관계 && 접근제어자 protected

+ 그래서 이 protected 접근제어자는 상속에서 많이 씀

상속과 접근제어자
1. 같은 패키지 안의 클래스 2개가 부모-자식 상속관계 -> private 빼고 다 접근가능하다
- public은 다 되고, default 는 원래부터 같은 패키지면 접근가능하고
- protected는 원래부터 같은 패키지면 접근 가능했고 또 상속관계면 다 접근 가능하기떄문에 접근 가능

2. 다른 패키지 안의 부모-자식 상속관계 -> protected, public 둘 중 하나여야만 함
- default 는 다른패키지는 접근 불가
- protected는 패키지가 달라져도 상속관계면 접근 가능함
- private은 자식 클래스라도 외부클래스이므로 접근 불가
+ private은 딱 자기 클래스만 접근 가능
- 다른 패키지더라도 상속관계이고 protected면 접근 가능하다

상속과 접근제어자 예제
- 예제 중에서 부모클래스는 src - packTest - packOne -  AccessTest.java(부모클래스)
- 자식클래스 패키지 없기때문에 복사를 해서 바로 scr에 집어넣기, SubOne.java
- 제3의 클래스 SuperSubA.java

- 부모클래스 AccessTest.java는 scr의 packTest.packOne 패키지를 만들어서 넣기
- 자식 클래스는 default package안에 들어가게됨
- 부모클래스에는 4개의 변수가 있는데 접근제어자가 다 다르다
- 원래는 public 일떄만 다른 패키지 접근 가능하지만
- 상속관계에 있고 protected 면 접근 가능하다
- 즉 부모와 자식이 서로 다른 패키지 안에 들어가있을때 4가지 접근제어자 중 어떤 접근제어자가 접근가능하게하는지 알아보는 예제임

정리
- 부모클래스 (AccessTest) -> 여기 필드값에 다양한 접근제어자가 있다
- 자식 클래스(SubOne)는 다른 패키지 안에 있을떄 protected, public이 가능함
- 제3의 클래스(SuperSubA)는 public 클래스만 접근 가능

 

// 부모 클래스
package packTest.packOne;

public class  AccessTest {  //다른 패키지에서 가져다 사용할 것임으로 pubic으로 
  private int    a=10;   //[1] private           
  int            b=20;  //[2] 기본 접근 지정자
  protected  int c=30;  //[3] protected        
  public     int d=40;  //[4] public       

  public void print( ){
    System.out.println("AccessTest의 print");
    System.out.println(a);
    System.out.println(b);
    System.out.println(c);
    System.out.println(d);
  }
}
// 자식 클래스
import  packTest.packOne.AccessTest;

//AccessTest의 서브 클래스로 SubOne을 설계
class SubOne extends AccessTest {
  void subPrn( ){
    System.out.println(a); //[1. Sub] private -X 에러
    System.out.println(b); //[2. Sub] 기본 접근 지정자-X 에러
    System.out.println(c); //[3. Sub] protected -O
    System.out.println(d); //[4. Sub] public -0
  }
}
// 제 3의 클래스
//AccessTest랑 상속관계가 없는 클래스 
class SuperSubA{
  public static void main(String[] args){
    AccessTest at=new AccessTest( );
    at.print( );
    System.out.println("main");
    System.out.println(at.a); //[1. main] private -X 에러
    System.out.println(at.b); //[2. main] 기본 접근 지정자-X 에러
    System.out.println(at.c); //[3. main] protected -X 에러
    System.out.println(at.d); //[4. main] public -O
  }
}

 

1. 상속 관계 있는 자식클래스 SubOne 에선 부모 클래스와 자식 클래스가 서로 다른 패키지에 있을때
- 이때 private 접근제어자로 되어있는 a는 자식이더라도 상속이 안됨(접근이 안됨)
- 이때 default 접근제어자로 되어있는 b는 자식이더라도 상속이 안됨(접근이 안됨)
- 이때 protected 접근제어자로 되어있는 c는 자식이라서 상속이 됨(접근 가능)
- 이때 public 접근제어자로 되어있는 d는 public이니까 상속이 됨(접근 가능)

2. 상속 관계 없는 제3의 클래스 SuperSubA 에선 제3의 클래스인데 서로 다른 패키지에 있을때
- 기존 내용처럼 public 접근제어자로 되어있는 필드만 접근 가능\

강사님 정리
src - packTest - packOne -  AccessTest.java(부모클래스)

SubOne.java(자식클래스) : protected, public만 접근가능
SuperSubA.java(제3의 클래스) : public만 접근가능    

- 필드의 접근제어자를 주로 protected를 많이 씀
- 두 패키지가 상속관계 && 서로다른 패키지 -> public, protected 접근 가능
- public > protected > default > private

레퍼런스 형변환
- 추상클래스, 인터페이스까지 공부 후 공부

자바 3가지 자료형변환
1. 기본자료형 변환
2. Wrapper클래스로 주로 String <-> int 형 변환
3. 레퍼런스 형변환(반드시 두 클래스 사이 상속관계 있어야만 가능함)

추상클래스 개념 1 (개념과 특징)
- 이름만 있고 내용이 없는 클래스
- 자체적으로 객체를 생성할 수 없는 클래스
- 여태껏 한개의 클래스로 무한개 객체만들어냈지만 추상클래스는 객체 생성 불가

추상클래스 개념 2 (형식과 구성)
- 추상클래스는 일반 클래스와 구분하기 위해서 클래스 앞에 abstract를 붙임
- 추상메소드 앞에도 반드시 abstract 붙이고 맨뒤 세미콜론 ex) abstract void Method01();
- 추상클래스에 들어가는 멤버 : 일반 멤버변수, 추상 메소드, 일반 메소드 등 있다. 
- 일반 클래스와 가장 큰 차이는 추상메소드를 가질 수 있다는 점
- 추상메소드를 가질 수 있다는게 가장 큰 특징
+ 추상메소드는 이름만있고 내용이 없는 메소드

추상클래스 개념 3 (생성과 사용)
- 추상클래스 상속 받을때는 클래스기떄문에 자식들은 일반 클래스 상속처럼 extends로 상속
- 그리고 부모 추상 클래스 나머지 안에 있는 추상메소드들을 반드시 메소드 오버라이딩 해야함
- 자체적으로 new연산자로 객체 생성 불가능한게 추상클래스 특징
- 부모 추상 메소드 : 공통적인 내용들을 넣어야함
ex) 새 클래스, 곤충 클래스, 물고기 클래스 -> 공통특징 추출해서 부모클래스 만듬 -> 부모클래스는 동물클래스
+ 나중에는 부모클래스 만들때 일반클래스보다 추상클래스를 부모클래스로 많이 만듬

추상클래스 개념 4 (상속)
- 자체적으로 객체 생성 안되므로 추상 클래스를 일반 클래스가 상속받아서 쓰는거다.
- 추상클래스를 상속받은 일반 클래스는 추상클래스 안에 들어있는 추상 클래스를 반드시 Method Overriding을해야한다
- 부모클래스의 이름, 형식 그대로 따라서 내용을 다르게 써내려가면 된다
- 메소드 오버라이딩 안하면 오류발생
- 추상클래스도 단일상속만 가능하다,2개이상의 추상클래스 상속 불가
- 자바는 일반클래스든 추상클래스든 다중상속 허용안하기 때문임

인터페이스
+ 추상클래스의 기능 있음 (추상메소드 가질수있음)
+ 인터페이스는 다중상속까지 허용함

+ 나중엔 추상클래스는 거의 안쓰고 인터페이스를 쓴다
+ 인터페이스 쓰기위해서 추상클래스 이해하는것임
+ 보통 추상클래스를 부모로 만드는게 아니라 인터페이스를 부모로 만듬

 과제
2022.07.12 / Hw1

       키보드로 입력한 문장을 파일(result.txt)로 저장하는 
       프로그램을 작성하세요

 

 

의도

BufferedReader 로 키보드 입력받기

FileWriter 로 파일 출력하기

 

 

깃허브

https://github.com/kindacool/Hw/blob/main/HW20220712/FileHw.java

 

GitHub - kindacool/Hw

Contribute to kindacool/Hw development by creating an account on GitHub.

github.com

 

 

코드

package p2022_07_12;

import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.InputStreamReader;

public class FileHw {

	public static void main(String[] args) {

		String inputMessage = null;
		FileWriter fw = null;
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		// 입력
		System.out.print("입력 > ");
		try {
			inputMessage = br.readLine();
		} catch (Exception e) {
			System.out.println(e.toString());
		}

		// 출력
		try {
			fw = new FileWriter("result.txt");
			fw.write(inputMessage);

		} catch (Exception e) {
			System.out.println(e.toString());
		} finally {
			try {
				if (fw != null) {
					fw.close();
				}
				br.close();
			} catch (Exception e) {

			}
		}
	}
}

 

 

결과

입력(키보드,콘솔)
출력(result.txt)

 

 

강사님 코드

package p2022_07_13;

import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.InputStreamReader;

public class FileWriterEx {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

// 키보드로 입력한 문장을 파일(result.txt)로 저장하는 프로그램을 작성하세요?
// 키보드 입력 : BufferedReader
// 파일 출력 : FileWriter

		System.out.println("문장을 입력하세요?");

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		try {
			String input = br.readLine();

			FileWriter fw = new FileWriter("result.txt");
			fw.write(input);

			fw.close();
			System.out.println("저장 성공~!!");
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

+ Recent posts