(23)-23.10.25[JAVA]

DANA·2023년 10월 25일

KDT-구디아카데미

목록 보기
23/56

인스턴스(instance)

  • 클래스는 객체의 속성을 정의하고 기능을 구현하여 만들어 놓은 코드 상태
  • 실제 클래스 기반으로 생성된 객체(인스턴스)는 각각 다른 멤버 변수 값을 가지게 됨
  • 예를 들어 학생의 클래스에서 생성된 각각의 인스턴스는 각각 다른 이름, 학번, 학년 등의 값을 가지게 됨
  • new 키워드를 사용하여 인스턴스 생성

힙메모리

  • 생성된 인스턴스는 동적메모리(heap memory)에 할당됨
  • 자바에서 Gabage Collector가 주기적으로 사용하지 않는 메모리를 수거함
  • 하나의 클래스로 부터 여러 개의 인스턴스가 생성되고 각각 다른 메모리 주소를 가지게 됨

객체 지향 프로그램은 어떻게 구현하는가?
객체를 정의하고, 각 객체 제공하는 기능들을 구현하고, 각 객체가 제공하는 기능들 간의 소통(메시지 전달)을 통하여 객체간의 협력을 구현함

함수란(function)

  • 하나의 기능을 수행하는 일련의 코드
  • 구현된 함수는 호출하여 사용하고 호출된 함수는 기능이 끝나면 제어가 반환됨
  • 함수로 구현된 하나의 기능은 여러 곳에서 동일한 방식으로 호출되어 사용될 수 있음

함수 정의하기

  • 함수는 이름, 매개변수, 반환값, 함수 몸체로 구성됨
  • 함수호출과 스택 메모리
    - 스택 : 함수가 호출될 때 지역변수들이 사용하는 메모리
    함수의 수행이 끝나면 자동으로 반환되는 메모리

메소드

  • 객체의 기능을 구현하기 위해 클래스 내부에 구현되는 함수(멤버함수 라고도 함)
  • 메소드를 구현함으로써 객체의 기능이 구현됨

용어 정리

  • 객체 : 객체 지향 프로그램의 대상, 생성된 인스턴스
  • 클래스 : 객체를 프로그래밍 하기 위해 코드로 정의해 놓은 상태
  • 인스턴스 : new 키워드를 사용하여 클래스를 메모리에 생성한 상태
  • 멤버변수 : 클래스의 속성, 특성
  • 메소드 : 멤버변수를 이용하여 클래스의 기능을 구현한 함수
  • 참조변수 : 메모리에 생성된 인스턴스를 가리키는 변수
  • 참조값 : 생성된 인스턴스의 메모리 주소값

생성자

  • 객체를 생성할 때 new 키워드와 함께 사용 - new Student();
  • 생성자는 일반함수처럼 기능을 호출하는 것이 아니고 객체를 생성하기 위해 new와 함께 호출됨
  • 객체가 생성될 때 변수나 상수를 초기화 하거나 다른 초기화 기능을 수행하는 메소드를 호출함
  • 생성자는 반환값이 없고 클래스의 이름과 동일
  • 대부분의 생성자는 외부에서 접근 가능하지만, 필요에 의해 private으로 선언되는 경우도 있음

기본 생성자(default constructor)

  • 클래스에는 반드시 적어도 하나 이상의 생성자 존재
  • 클래스에 생성자를 구현하지 않아도 new로 생성자 호출할 수 있음
  • 클래스에 생성자가 하나도 없으면 컴파일러가 생성자 코드를 넣어줌
  • 매개변수가 없음, 구현부가 없음

생성자 만들기
컴파일러가 제공해주는 기본 생성자 외에 필요에 의해 생성자를 직접 구현할 수 있음

생성자 정의하기

  • 생성자를 구현해서 사용할 수 있음
  • 클래스에 생성자를 따로 구현하면 기본 생성자는 제공되지 않음
  • 생성자를 호출하는 코드에서 여러 생성자 중 필요에 따라 호출해서 사용할 수 있음

A

package bclass.step1;

public class A {
	int i; // 인스턴스 변수(전역변수) i 선언
    
	public A() { // 기본 생성자
		System.out.println("A()호출");
		i = 10; // i 변수를 10으로 초기화
	}
    
	public A(int i) { // 매개변수를 가지는 생성자
    	// 생성자 내용 없음
        // this예약어로 디폴트 생성자 호출 가능
        // this();
	}
    
	void methodA() { // 매개변수가 없는 메서드
		// 현재는 아무 작업도 하지 않음
	}
    
		// 만약 외부에서 유지되기를 원하면 전변으로 치환하든가, 리턴타입을 활용
    
	void methodA(int i) { // 매개변수가 있는 메서드
    	// 메소드 오버로딩 - 파라미터 투입 - 스택메모리에 있는 지변이다
		// 인스턴스화를 할 때마다 새로운 객체 생성 - 주소번지가 달라짐
		A a = new A();
		a.i = 20;
		System.out.println(a.i); // 20
	}
    
	public static void main(String[] args) {
    	// A 클래스의 새 객체 a를 생성
        // 매개변수를 0으로 전달하여 생성자 호출
		A a = new A(0);
        // a 객체의 i 변수 값을 출력 
        // 10 출력, 생성자에서 초기화
		System.out.println(a.i); 
	}
}

BoardView

<자유게시판 구현에 대한 클래스 설계>

package bclass.board;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
// BoardView -> BoardController -> BoardDao

public class BoardView extends JFrame implements ActionListener {
	// BoardController 객체를 저장할 참조 변수 선언
    // 나는 내 타입도 몰라요. 왜냐면 초기화를 null로 했으니까
	BoardController boardController = null;
    
    // "조회" 레이블을 가진 JButton 선언
	JButton  jbtn_sel = new JButton("조회");
    
	public BoardView() {
    	// 생성자에서 initDisplay 메서드 호출하여 화면 초기화
		initDisplay();
	}
    
	public void initDisplay() {
    
		jbtn_sel.addActionListener(null);//this는 현재 메모리에 로딩(활성화)되어 있는 자신 - BoardView - actionPerformed - 메소드 오버라이딩 - 추상메소드 - 인터페이스 - ActionListener - 정의가 안되어있다 - 미정이다. - 단말기가 결정되지 않음 
		this.add("North", jbtn_sel);
		this.setSize(500, 400);
		this.setVisible(true);
		
	}
	//현재 상태에서 단위테스트 가능한가요?
	//힌트  - actionPerformed는 콜백메소드야 - 내가 호출하지 못해
	//파라미터 자리에 클래스(참조형) 타입도 올 수 있다.
	//콜백메소드의 파라미터자리는 개발자가 아닌 JVM에서 주입받는다.
	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("actionPerformed");
		Object obj = e.getSource();//절대로 NullPointerException이 발생하지 않음
		//너 조회버튼 누른거야? 네
		if(obj == jbtn_sel) {
			boardController = new BoardController();
			boardController.getBoardList();
		}
	}

	public static void main(String[] args) {
		BoardView bview = null;
		bview = new BoardView();
	}
}

BoardVO

package bclass.board;

public class BoardVO {
	private int      fb_no      		=0;//글번호 
	private String fb_title   		="";// 글제목
	private String fb_writer  	="";//작성자 
	private String fb_content 	="";//글내용 
	private int 	   fb_hit     		=0;//조회수 
	private int       fb_group   	=0;//글그룹번호 
	private int       fb_step    	=0;//글순번 
	private String fb_date    	="";//작성일자 
	//1이면 입력|수정|삭제 성공, 0이면 입력|수정|삭제
	private int result = -1;

	public int getResult() {
		return result;
	}

	public void setResult(int result) {//1 또는 0
		boolean isValid = false;
		//public으로 변수를 선언하여 직접 사용할 때 보다 메소드를 통해서 값을 사용하므로
		//입력값에 대한 유효성 체크를 할 수 있다는 장점이 있다.
		if(result == 0 | result == 1) {//입력값에 대한 유효성 체크를 동반할 수도 있다.
			isValid = true;
		}
		else {
			isValid = false;
		}
		this.result = result;
	}

	public int getFb_no() {
		return fb_no;
	}

	public void setFb_no(int fb_no) {
		this.fb_no = fb_no;
	}

	public String getFb_title() {
		return fb_title;
	}

	public void setFb_title(String fb_title) {
		this.fb_title = fb_title;
	}

	public String getFb_writer() {
		return fb_writer;
	}

	public void setFb_writer(String fb_writer) {
		this.fb_writer = fb_writer;
	}

	public String getFb_content() {
		return fb_content;
	}

	public void setFb_content(String fb_content) {
		this.fb_content = fb_content;
	}

	public int getFb_hit() {
		return fb_hit;
	}

	public void setFb_hit(int fb_hit) {
		this.fb_hit = fb_hit;
	}

	public int getFb_group() {
		return fb_group;
	}

	public void setFb_group(int fb_group) {
		this.fb_group = fb_group;
	}

	public int getFb_step() {
		return fb_step;
	}

	public void setFb_step(int fb_step) {
		this.fb_step = fb_step;
	}

	public String getFb_date() {
		return fb_date;
	}

	public void setFb_date(String fb_date) {
		this.fb_date = fb_date;
	}
}

BoardController

package bclass.board;

import java.util.List;
import java.util.Map;

//화면과 로직(모델계층-데이터계층과 업무 프로세스 처리)을 분리하자
//화면과 로직을 연결해주는 클래스 설계함
//로직(입력, 수정, 삭제, 전체조회 상세조회 업무내용 - 메소드 5개 설계함)
//입력인 경우 - 성공이면 1을 반환하고 실패이면 0을 반환 - 누가반환하지 - 오라클 서버
//5가지의 메소드의 리턴타입과 파라미터 타입을 결정해야 함
//공통점 찾아내서 하나의 메소드로 합칠 수 있는 것인지 아니면 메소드를 모두 다 분리해야 하는지 결정
public class BoardController {
	BoardDao bDao = new BoardDao(this);//전역변수
	public List<Map<String,Object>> getBoardList(){
		System.out.println("getBoardList호출 성공");
		return null;
	}
}

BoardDao

package bclass.board;
//DAO(Data Access Object) - 영속성을 제공하는 오라클 서버와 연계하는 역할만 전담
//클래스 사이의 결합도를 낮춰야 한다. - 재사용성을 높여야 한다. - 칼퇴
public class BoardDao {
	BoardController boardController  = null;//주소번지 안찍힘 - 타입이 결정되지 않음 - 모른다
	public BoardDao(BoardController boardController) {
		this.boardController = boardController;
	}

}

CMain

package bclass.step1;
class C1{
	int i;
}
class C2{
	
}
public class CMain {
	//c1은 C1타입이고 아직 생성되지 않았다. 선언만 함. 아직 인스턴스화 안함
	C1 c1 = null;//타입이 결정된것도 아니었다 - 경험치
	public static void main(String[] args) {
		CMain cm = new CMain();
		cm.c1 = new C1();//생성
		System.out.println(cm.c1);//null
		System.out.println(cm.c1 instanceof C1);
		System.out.println(cm.c1.i);//NullPointerException발동됨
		System.out.println(cm.c1.i+2);//2
		System.out.println("main");
	}
}/////// end of CMain

DMain

package bclass.step1;
class D1{
	//DMain에서 선언된 변수를 굳이 methodA에서 사용하고 싶다.
	//어떡하지? - 파라미터를 이용하면 된다(call by value, call by reference)
	int methodA(int i, int j) {
		System.out.println(i+", "+j);
		return i+j;
	}
}
public class DMain {

	public static void main(String[] args) {
		D1 d1 = new D1();
		int i = 1;
		int j = 2;
		int hap = d1.methodA(i, j);
		System.out.println(hap);
	}

}

EMain

package bclass.step1;

import javax.swing.JButton;

public class EMain extends Object {
	@Override
	public String toString() {
		return "null";
	}
	public static void main(String[] args) {
		EMain em = new EMain();
		JButton jbtn = new JButton("조회");
		System.out.println(em);
		System.out.println(em.toString());
		System.out.println(jbtn);
	}

}

Student

package bclass.step1;
//샘플데이터 - 0054307 | 나신입 | 3
public class Student {
	private int s_no;//학번이다. - 0
	private String s_name;//학생이름 - null
	private int grade;//학년 - 0
	public Student() {}
	public Student(int s_no) {}
	public Student(int s_no, String s_name) {};
	public Student(int s_no, String s_name, int grade) {
		this.s_no = s_no;
		this.s_name = s_name;
		this.grade = grade;
	}
	public int getS_no() {
		return s_no;
	}
	public void setS_no(int s_no) {
		this.s_no = s_no;
	}
	public String getS_name() {
		return s_name;
	}
	public void setS_name(String s_name) {
		this.s_name = s_name;
	}
	public int getGrade() {
		return grade;
	}
	public void setGrade(int grade) {
		this.grade = grade;
	};
}

StudentTest

package bclass.step1;

public class StudentTest {

	public static void main(String[] args) {
		Student me = new Student();
		System.out.println("학번 : "+me.getS_no());
		System.out.println("학생이름 : "+me.getS_name());
		System.out.println("학년 : "+me.getGrade());		
		me = new Student(9563409, "나신입", 3);
		System.out.println("학번 : "+me.getS_no());
		System.out.println("학생이름 : "+me.getS_name());
		System.out.println("학년 : "+me.getGrade());				
	}

}

FMain

package bclass.step1;
//메소드를 선언할 수  있다는 건 리턴타입과 파라미터를 결정할 수 있어야 한다.
import java.util.ArrayList;
import java.util.List;

import bclass.board.BoardVO;

//입력 수정 삭제 조회 상세보기
//입력,수정,삭제 - return int로 한다. 파라미터는 BoardVO로 한다
//전체 조회 - List<BoardVO>, List<Map>
//반복되는 코드를 줄이기 위한 방법으로 공통분모 생각해 본다.
//반복되는 코드를 모두 모아서 한 눈에 보이게 펼치고 리턴타입과 파라미터에 대한 선택- 첫번째 시도로
//추출한 데이터를 가지고 연산처리를 할 경우 타입체크가 필수 이므로 이런 경우는 VO제네릭 으로 한다.
//Map<String, Object> Object-> int Object -> double ClassCastingException
// 설계단계 - 화면정의서, 요구사항 정의서, 클래스 다이어그램(클래스설계:클래스관계), 유스케이스 다이어그램(업무담당자의 요구사항을 그림- 절차)
//BoardDao.java설계하여 처리하시오.
//왜 오라클서버 연동하는 클래스를 추가로 설계하였나?
//JDBC API(반복되는 코드가 늘어남-업무에대한 규칙이 바뀌면 코드를 수정해야 함) ->
//반복되는 코드를 줄여주는 그러나 쿼리문은 남아있는 myBatis(라이브러리-main가 없는 클래스)사용하여 처리함
//전체적인 클래스 설계가 변한다(야근)|변하지 않는다.(5일)
//클래스를 독립적으로 나누어 관리한다.
//클래스가 분리가 되면 인스턴스화를 잘 해야 한다. - 생성자의 파라미터를 잘 선택한다.
public class FMain {
	//입력 처리
	/*************************************************************
	 * INSERT INTO 테이블명(컬럼명1, 컬럼명2,...) VALUES(?,?,?,?,?,?,?,?)
	 * 쿼리문을 자바코드에 왜 적었나? - 파라미터 자리를 결정할 수  있다. 갯수, 타입, 컬럼명, 컬럼타입
	 * @param BoardVO
	 *************************************************************/
	//public int boardInsert(Map<String,Object> pmap) {
	public int boardInsert(BoardVO bVO) {	
		int result = -1;
		//커밋해야 된다면서요???? - 디폴트값이 autocommit으로 설정됨
		//con.setAutocommit(false);
		//con.commit();
		return result;
	}
	//수정 처리 - 있는 걸 바꾼다 - PK는 수정할 수 없다. - 7개만 수정이 가능하다.
	/*************************************************************
	 * update dept set dname =:dname, loc =:loc where deptno=:deptno;
	 * 쿼리문을 자바코드에 왜 적었나? - 파라미터 자리를 결정할 수  있다. 갯수, 타입, 컬럼명, 컬럼타입
	 * @param BoardVO
	 *************************************************************/
	public int boardUpdate(BoardVO bVO) {	
		int result = -1;
		return result;
	}
	//삭제 처리
	/*************************************************************
	 * DELETE FROM freebard where fb_no=?;
	 * 쿼리문을 자바코드에 왜 적었나? - 파라미터 자리를 결정할 수  있다. 갯수, 타입, 컬럼명, 컬럼타입
	 * @param BoardVO
	 *************************************************************/
	public int boardDelete(int fb_no) {	
		int result = -1;
		return result;
	}
	//전체 조회 처리
	/*************************************************************
	 * SELECT fb_no, fb_title, fb_writer, fb_hit, fb_group, fb_step, fb_date FROM freeboard
	 *  WHERE fb_title LIKE ?||'%'
	 *   AND (OR) fb_date LIKE ?
	 *   AND (OR) fb_writer LIkE ?
	 * 쿼리문을 자바코드에 왜 적었나? - 파라미터 자리를 결정할 수  있다. 갯수, 타입, 컬럼명, 컬럼타입
	 * @param BoardVO
	 *************************************************************/
	//public List<BoardVO> boardList(Map<String,Object> pmap) {	
	public List<BoardVO> boardList(BoardVO pbVO) {		
		List<BoardVO> bList = new ArrayList<>();
		return bList;
	}	
	//상세보기 처리
	public BoardVO boardDetail() {
	//public Map<String,Object> boardDetail() {	
		BoardVO rbVO = null;
		return rbVO;
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}
/*
 * 클래스
 * 1) 기능처리 위한 클래스
 * 2) 데이터셋을 위한 클래스 - 복습 - 단단히 할것
 * 3) 서블릿<- JSP학습 - Web기반 서비스 - URL이용 - 네트워크 프로그래밍(소켓) - main메소드는 없다.
 * 3-1) 모바일(앱) -> 3+3-1 -> 하이브리드 앱개발 - 함수형프로그래밍 언어(람다식,  화살표함수)
 * 
 */

GMain

package bclass.step1;
class G{
	int i = 1;
	static int j = 10;
	G(){
		j++;
		i = j;
	}
}
public class GMain {
//여러개의 인스턴스가 하나의 전변을 공유하고 싶다면 static한다
	public static void main(String[] args) {
		G g = new G();
		System.out.println(g);
		System.out.println(g.i);
		System.out.println(G.j+1);
		g = new G();
		System.out.println(g);
		System.out.println(g.i);
		System.out.println(G.j+1);
		g = new G();
		System.out.println(g);
		System.out.println(g.i);
		System.out.println(G.j+1);
	}
}

Car

package bclass.step1;

public class Car {
	private int carNum;
	public Car() {//디폴트 생성자 - 리턴타입이 없고 , 구현없음, 생략가능, 생략했을 경우 컴파일 될때 JVM주입해줌
		int x = CarFactory.serialNum++;
		System.out.println("x: "+x);
		carNum = CarFactory.serialNum;
	}
	public int getCarNum() {
		return carNum;
	}

	public void setCarNum(int carNum) {
		this.carNum = carNum;
	}
}

CarFactory

package bclass.step1;

public class CarFactory {
	public static int serialNum = 1000;
	public static Car getInstance() {
		Car myCar = null;
		if(myCar == null) {//myCar 변수를 null체크하여 null인 경우에만 인스턴스화함
			myCar = new Car();
		}
		return myCar;
	}///////////end of getInstance
}

CarTest

package bclass.step1;

public class CarTest {

	public static void main(String[] args) {
		Car yourCar = CarFactory.getInstance();
		//Car himCar = CarFactory.getInstance();
		//Car herCar = CarFactory.getInstance();
		//insert here
		System.out.println(yourCar.getCarNum());
		//System.out.println(himCar.getCarNum());
		//System.out.println(herCar.getCarNum());
	}

}

HMain

package bclass.step1;
class H{
	int i;
	private static H h = new H();//이른 인스턴스화
	private H(){
		System.out.println("H()");
	}
	static H getInstance() {
		return h;
	}
}
public class HMain {

	public static void main(String[] args) {
		H h = H.getInstance();
		H h2 = H.getInstance();
		System.out.println(h+", "+h2);
	}

}

0개의 댓글