배열은 클래스급 → new / 주소 번지-간접 참조 방식 / 전역 변수 scope, 지역변수 scope 구분 / 초기화
변수
같은 타입만 담을 수 있다
한 번에 하나의 값만 담을 수 있다
배열
같은 타입만 담을 수 있다
사이즈(길이)가 정해져있다(바꿀수없다)
한 번에 여러 값 담을 수 있다
객체 배열
배열과 같지만, 서로 다른 타입도 담을 수 있다.
도트 연산자(.) 뒤는 전역 변수
전역 변수만 인스턴스변수(소유주).변수명 형태로 호출할 수 있다
package dev_java.week3;
public class Main {
int i = 1;
public static void main(String[] args) {
Sub sub = new Sub(); // 디폴트 생성자 호출
System.out.println(sub.j); // j는 전역변수 2
sub.methodA(); // sub methodA 호출
}
}
package dev_java.week3;
public class Sub {
int j = 2;
void methodA() {
System.out.println("sub methodA 호출");
}
}
package dev_java.week3;
public class Main_1 {
int i = 1;
boolean isOk[] = new boolean[3]; // false, false, false
}
package dev_java.week3;
public class Sub_1 {
public static void main(String[] args) {
Main_1 m1 = new Main_1();
for (int i = 0; i < m1.isOk.length; i++) {
System.out.println(m1.isOk[i]); // false, false, false
}
System.out.println("==========");
for (boolean isOk : m1.isOk) { // 개선된 for문
System.out.println(isOk); // false, false, false
}
}
}
package dev_java.week3;
public class Main_2 {
int i = 1;
boolean isOk[] = null; // 선언
// 디폴트 생성자는 생략이 가능하다
// 그러나 지금은 isOk배열의 생성을 위해서 getisOk()를 경유하도록해야
// NullPointerException을 피할 수 있다
public Main_2() {
System.out.println("Main_2 디폴트 생성자 호출 성공");
getisOK(); // 디폴트생성자에 getisOk 넣음
}
// 선언과 동시에 인스턴스화를 하지 않는 경우를 게으른 인스턴스화라고 한다.
// 선언과 생성을 동시에 하지 않고 메소드를 통해서 객체 주입을 받을 수 있다.
// 이럴 경우 메소드 안에서 if문을 통해 null체크를 할 수 있어 싱글톤 패턴으로 객체를
// 주입받을 수 있기에 현업에서 선호하는 객체 주입 방법 중 하나이다.
boolean[] getisOK() {
if (isOk == null) {
isOk = new boolean[] { true, false, true }; // 생성, 초기화
}
return isOk;
}
}
package dev_java.week3;
public class Sub_2 {
public static void main(String[] args) {
Main_2 m2 = new Main_2(); // 인스턴스화, Main_2의 디폴트 생성자에 getisOk를 넣었기에 null이 아닌 값이 나옴!
for (int i = 0; i < m2.isOk.length; i++) {
System.out.println(m2.isOk[i]);
}
System.out.println("==========");
for (boolean isOk : m2.isOk) {
System.out.println(isOk);
}
}
}
// Main_2 디폴트 생성자 호출 성공
// true
// false
// true
// ==========
// true
// false
// true
인터페이스
단독 인스턴스화 x → 추상메소드만 가지고 있기에 반드시 구현체 클래스 있어야 함(implements)
인터페이스 중심 코딩은 재사용성 높이고 결합도 낮춘다.(추상메소드 오버 라이딩)
ActionListener(인터페이스) → 구현체 클래스(이벤트 핸들러 클래스)가 필요함 →메소드 오버라이드를 해야 함(actionPerformed)
추상메소드 선언();
추상메소드 선언은 인터페이스 안에서 일어난다.(인터페이스의 메소드는 추상메소드이다)
추상메소드는 호출이 아니라 선언이라도 세미콜론(;)으로 끝난다.
정의할 수 없다(장치가 결정되지 않음) → 재정의해야 한다 (메소드 오버 라이딩)
메소드 오버라이드는 선언부를 절대로 수정할 수 없다
@annotation
사전적 의미는 주석
메타데이터의 일종(컴파일, 실행 과정에서 코드를 어떻게 처리해야 하는지 알려주기 위한 추가 정보)
@Override →선언한 메서드가 오버라이드 되었다는 걸 나타냄
package dev_java.week3;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class JTextAreaUI implements ActionListener {
// 선언부
JTextAreaUILogic jtaUILogic = new JTextAreaUILogic(this);
// 인터페이스는 반드시 구현체 클래스가 있어야 한다.
// 단독으로 인스턴스화할 수 없다.
// ActionListener al = new ActionListener(); //단독으로 인스턴스화 불가!
// 선언부와 생성부의 타입이 다르다. 그렇기에 다형성이 가능함(폴리모피즘)재사용성을 높이고 결합도는 낮춘다.
// ActionListener al = new JTextAreaUI(); //이렇게는 가능!
JFrame jf = new JFrame();
JTextArea jta = new JTextArea(10, 20);
JTextField jtf = new JTextField(10);
// 디폴트 생성자는 생략이 가능하다. -> JVM이 대신 생성해줌
// 생성자도 메소드처럼 호출이 가능하다. 하지만 메소드와 다르게 리턴타입이 없다
// 인스턴스화(호출) 될 때 생성된다.
public JTextAreaUI() { // 디폴트 생성자 선언
initDisplay();
}
public void initDisplay() { // UI를 그린다(이벤트처리)
// 이벤트 소스와 이벤트 핸들러 클래스 매핑(매칭)하기
jtf.addActionListener(this); // this는 나 자신, 이벤트 핸들러 클래스의 주소번지
// 멀티라인 작성 가능한 컴포넌트의 배경색 설정
jta.setBackground(Color.cyan);
// JFrame은 디폴트 레이아웃이 BorderLayout이라서 동, 서, 남, 북, 중앙 배치 가능
jf.add("Center", jta); // JTextArea는 중앙에 배치
jf.add("South", jtf); // JTextField는 남쪽에 배치
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 윈도우창 x버튼 클릭 시 자원회수
jf.setSize(400, 300); // 윈도우창 가로 세로 크기 설정
jf.setVisible(true); // 화면을 출력함
}
public static void main(String[] args) { // 가장먼저 호출됨-entry point
new JTextAreaUI(); // 생성자가 호출되고 그 안에서 화면그리는 메소드 호출
}
// annotation-문법제약을 갖고있다-선언부가 일치해야한다.
@Override
public void actionPerformed(ActionEvent e) { // callback 추상메소드, 이벤트가 감지됐을 때 호출됨
// 추상메소드의 파라미터를 통해서 감지된 컴포넌트의 주소번지를 얻어오는
// getSource메소드의 소유주(ActionEvent클래스)
Object obj = e.getSource();
if (jtf == obj) { // JTextField에 엔터를 쳤는가?
// JTextField에 입력한 문자열받기
String input = jtf.getText();
jta.append("JTextAreaUI원본: " + input + "\n"); // 원본에서 찍히는지 확인
jtaUILogic.account(input); //Logic에서 가져온 값
jtf.setText("");
}
}
}
package dev_java.week3;
public class JTextAreaUILogic {
// 여기서 직접 인스턴스화하면 복제본이 만들어짐-복제본에 출력된다
// 메모리 StackOverFlow발생-서버가 중지됨
// JTextArea jta = new JTextArea(10, 20); // 복제본이 생성되서 원본작동x + 서버부담
JTextAreaUI jtaUI = null;
public JTextAreaUILogic(JTextAreaUI u1) {
// 생성자 안에서 JTextAreaUI의 JTextArea원본과 전역변수를 초기화해줘야함
this.jtaUI = u1;
}
public void account(String input) {
// JTextAreaUI클래스에 정의된 주소번지(원본)를 사용
jtaUI.jta.append("UILogic: " + input + "\n");
}
}
뷰와 핸들러 분리 예제
package dev_java.week3;
import javax.swing.JButton;
import javax.swing.JFrame;
public class JButtonUI {
// 선언부
JFrame jf = new JFrame();
JButton jbtn_south = new JButton("전송");
JButtonUIEvent jButtonEvent = new JButtonUIEvent(this);
// 생성자
public JButtonUI() {
initDisplay();
}
// 화면처리부
public void initDisplay() {
// 이벤트 소스와 이벤트 핸들러 매핑시 this를 쓸 수 있는 건
// 오직 내 안에 actionPerformed가 구현되어 있을때 뿐이다.
jbtn_south.addActionListener(jButtonEvent); // 이벤트 핸들러 분리
// 윈도우 x버튼 클릭시 자원반납(어플 정상 종료)
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add("South", jbtn_south);
jf.setSize(300, 250);
jf.setVisible(true);
}
public static void main(String[] args) {
new JButtonUI();
}
}
package dev_java.week3;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class JButtonUIEvent implements ActionListener {
JButtonUI jbUI = null;
public JButtonUIEvent(JButtonUI jButtonUI) {
this.jbUI = jButtonUI;
}
@Override
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if (obj == jbUI.jbtn_south) {
System.out.println(jbUI.jbtn_south.getText() + "버튼 클릭");
}
}
}
이벤트 핸들러 분리버전(뷰/로직/이벤트 핸들러)
package dev_java.week3;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class JTextAreaUI {
// 선언부
JTextAreaUILogic jtaUILogic = new JTextAreaUILogic(this); // 로직 분리
JTextAreaUIEvent jTextAreaUIEvent = new JTextAreaUIEvent(this); // 이벤트핸들러 분리
// 인터페이스는 반드시 구현체 클래스가 있어야 한다.
// 단독으로 인스턴스화할 수 없다.
// ActionListener al = new ActionListener(); //단독으로 인스턴스화 불가!
// 선언부와 생성부의 타입이 다르다. 그렇기에 다형성이 가능함(폴리모피즘)재사용성을 높이고 결합도는 낮춘다.
// ActionListener al = new JTextAreaUI(); //이렇게는 가능!
JFrame jf = new JFrame();
JTextArea jta = new JTextArea(10, 20);
JTextField jtf = new JTextField(10);
// 디폴트 생성자는 생략이 가능하다. -> JVM이 대신 생성해줌
// 생성자도 메소드처럼 호출이 가능하다. 하지만 메소드와 다르게 리턴타입이 없다
// 인스턴스화(호출) 될 때 생성된다.
public JTextAreaUI() { // 디폴트 생성자 선언
initDisplay();
}
public void initDisplay() { // UI를 그린다(이벤트처리)
// 이벤트 소스와 이벤트 핸들러 클래스 매핑(매칭)하기
jtf.addActionListener(jTextAreaUIEvent); // ()에 이벤트핸들러를 가리키는 인스턴스변수명이 와야함
// 멀티라인 작성 가능한 컴포넌트의 배경색 설정
jta.setBackground(Color.cyan);
// JFrame은 디폴트 레이아웃이 BorderLayout이라서 동, 서, 남, 북, 중앙 배치 가능
jf.add("Center", jta); // JTextArea는 중앙에 배치
jf.add("South", jtf); // JTextField는 남쪽에 배치
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 윈도우창 x버튼 클릭 시 자원회수
jf.setSize(400, 300); // 윈도우창 가로 세로 크기 설정
jf.setVisible(true); // 화면을 출력함
}
public static void main(String[] args) { // 가장먼저 호출됨-entry point
new JTextAreaUI(); // 생성자가 호출되고 그 안에서 화면그리는 메소드 호출
}
}
package dev_java.week3;
public class JTextAreaUILogic {
// 여기서 직접 인스턴스화하면 복제본이 만들어짐-복제본에 출력된다
// 메모리 StackOverFlow발생-서버가 중지됨
// JTextArea jta = new JTextArea(10, 20); // 복제본이 생성되서 원본작동x + 서버부담
JTextAreaUI jtaUI = null;
public JTextAreaUILogic(JTextAreaUI u1) {
// 생성자 안에서 JTextAreaUI의 JTextArea원본과 전역변수를 초기화해줘야함
this.jtaUI = u1;
}
public void account(String input) {
// JTextAreaUI클래스에 정의된 주소번지(원본)를 사용
jtaUI.jta.append("UILogic: " + input + "\n");
}
}
package dev_java.week3;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class JTextAreaUIEvent implements ActionListener {
JTextAreaUI jtaUI = null;
public JTextAreaUIEvent(JTextAreaUI u1) {
// 생성자 안에서 JTextAreaUI의 JTextArea원본과 전역변수를 초기화해줘야함
this.jtaUI = u1;
}
// annotation-문법제약을 갖고있다-선언부가 일치해야한다.
@Override
public void actionPerformed(ActionEvent e) { // callback 추상메소드, 이벤트가 감지됐을 때 호출됨
// 추상메소드의 파라미터를 통해서 감지된 컴포넌트의 주소번지를 얻어오는
// getSource메소드의 소유주(ActionEvent클래스)
Object obj = e.getSource();
if (jtaUI.jtf == obj) { // JTextField에 엔터를 쳤는가?
// JTextField에 입력한 문자열받기
String input = jtaUI.jtf.getText();
jtaUI.jta.append("JTextAreaUI원본: " + input + "\n"); // 원본에서 찍히는지 확인
jtaUI.jtaUILogic.account(input); // Logic에서 가져온 값
jtaUI.jtf.setText("");
}
}
}
또 다른 분리 예제(뷰/로직/이벤트 핸들러)
package dev_java.week3;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class JTextAreaUI2 {
// 선언부
JTextAreaUILogic2 jLogic2 = new JTextAreaUILogic2(this);
JTextAreaUIEvent2 jEvent2 = new JTextAreaUIEvent2(this);
JFrame jf = new JFrame();
JTextArea jta = null;
JScrollPane jsp = null;
JTextField jtf = new JTextField(10);
public JTextAreaUI2() {
getTextArea();
initDisplay();
}
public JTextArea getTextArea() {
if (jta == null) {
jta = new JTextArea(10, 20);
jsp = new JScrollPane(jta, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
}
return jta;
}
public void initDisplay() {
jtf.addActionListener(jEvent2);
jta.setBackground(Color.cyan);
jf.add("Center", jsp); // jta가 아니라 jsp를 붙여줌(가장 밑에 있는 것)
jf.add("South", jtf);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setSize(400, 300);
jf.setVisible(true);
}
public static void main(String[] args) {
new JTextAreaUI2();
}
}
package dev_java.week3;
public class JTextAreaUILogic2 {
JTextAreaUI2 jUI2 = null;
public JTextAreaUILogic2(JTextAreaUI2 jUI2) {
this.jUI2 = jUI2;
}
public void account(String input) {
jUI2.jta.append("UILogic: " + input + "\n");
}
}
package dev_java.week3;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class JTextAreaUIEvent2 implements ActionListener {
JTextAreaUI2 jUI2 = null;
public JTextAreaUIEvent2(JTextAreaUI2 jUI2) {
this.jUI2 = jUI2;
}
@Override
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if (jUI2.jtf == obj) {
String input = jUI2.jtf.getText();
jUI2.getTextArea().append("JTextAreaUI원본: " + input + "\n");
jUI2.jLogic2.account(input);
jUI2.jtf.setText("");
}
}
}
'국비학원 > 수업기록' 카테고리의 다른 글
국비 지원 개발자 과정_Day13 (0) | 2022.12.14 |
---|---|
국비 지원 개발자 과정_Day12 (0) | 2022.12.13 |
국비 지원 개발자 과정_Day10 (1) | 2022.12.09 |
국비 지원 개발자 과정_Day9 (1) | 2022.12.08 |
국비 지원 개발자 과정_Day8 (3) | 2022.12.07 |
댓글