1. 그리는 위치

- JPanel : 그림 그릴 수 있는 화면 갖고 있고, 동시에 컨테이너 역할도 함

class MyPanel extends JPanel {
    ...
}

public class MyFrame extends JFrame {
    public MyFrame() {
        MyPanel panel = new MyPanel();
        add(panel);
    }
}

 

2. paintComponent()

- 컴포넌트가 가지고 있는 메소드
- 모든 컴포넌트가 가지고 있으며, 이 메소드를 재정의함으로써 그림을 그림
- 컴포넌트를 다시 그릴 필요가 있을 때마다 자바 시스템에 의해 호출됨 (ex. 프레임이 가려졌다가 다시 나타나는 경우)
- super.paintComponent(g) 호출
- 전체 구성요소를 전부 그리는 것이 아닌 경우 호출

class MyPanel extends JPanel {
    public void paintComponent(Graphics g) {
        super.paintComponent(g);                 
        // 그림그리는 코드
    }
}

 

3. repaint()

- 사용자가 직접 paintComponent()를 호출할 수 없음. 반드시 자동으로 호출되어야 함
- 사용자가 화면을 다시 그리고 싶은 경우 repaint() 호출
-> repaint()가 적절한 시기에 paintComponent() 호출

4. 색상 변경

Color c = Color.BLUE;  
Color c = new Color(255, 0, 255);

- setBackground(c) : 컴포넌트 객체 배경색 설정
- setColor(c) : 전경색 설정
- Color getColor() : 현재 전경색 반환

5. 폰트 객체 생성

- Font(폰트 이름(Alias, Serif, Gothic ...) , 스타일(Font.PLAIN, BOLD, ITALIC ...), 크기(10, 30, ...))

Font font = new Font("Courier", Font.PLAIN, 10);

public void paint(Graphics g) {
    g.setFont(font);
    ...
}

JLabel lbl = new JLabel("Hello");
lbl.setFont(new Font("Gothic", Font.BOLD, 30));

 

6. Graphics 클래스

- 텍스트 문자열 : drawString();

g.drawString("Hello World!", x, y);   // x, y : 위치 설정


- 기초 도형들
- draw---(); : 선으로 그리기
- fill---(); : 채워서 그리기

drawLine(int x1, int y1, int x2, int y2);  // (x1, y1)에서 (x2, y2)까지 직선
drawRect(int x, int y, int width, int height);  // (x, y)에서 폭 width, 높이 height인 직사각형
drawOval(int x, int y, int width, int height);  
// (x, y)에서 폭 width, 높이 height인 직사각형에 내접하는 타원
drawArc(int x, int y, int width, int height, int startAngle, int arcAngle);
// 좌측 상단 좌표가 (x, y)이며 폭 width, 높이 height인 사각형에 내접하는 타원에서
// startAngle을 시작 각도로 하여 arcAngle의 각도만큼 호를 그림
drawPolygon(int[] x, int y[], length);   // 배열 x[], y[]를 갖고 여러 개의 직선 (전부 이음)
drawPolyline(int[] x, int y[], length);  // 배열 x[], y[]를 갖고 여러 개의 직선 (처음과 끝 잇지 않음)


- 이미지 : drawImage();

ImageIcon icon = new ImageIcon("car.png");
img = icon.getImage();

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(img, x, y, null);
}

 

7. 그래픽 좌표계

 

8. 예제1) 화면 클릭하면 그 위치에 사각형 그리도록

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class MyFrame extends JFrame {
    int x, y;
    class MyPanel extends JPanel {
        public MyPanel() {
            addMouseListener(new MouseAdapter() {
                public void mousePressed(MouseEvent e) {
                    x = e.getX();
                    y = e.getY();
                    repaint();
                }
            });
        }
        
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.ORANGE);
            g.fillRect(x, y, 100, 100);
        }
    }    
   
    public MyFrame() {
        setSize(600, 200);
        add(new MyPanel());
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
   
    public static void main(String[] args) {
        new MyFrame();
    }
}

 

발전 버전) 드래그 한 크기의 사각형 그리고 패널 위에 저장하기

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class Rect {
    int x, y, w, h;
    public Rect(int x, int y, int w, int h) {
        this.x = x; this.y = y; this.w = w; this.h = h;
    }
}

public class GraphicTest extends JFrame {
    int x, y;
    int w = 100, h = 100;
    int x1, y1, x2, y2;
    Vector<Rect> list = new Vector<>();
    
    class MyPanel extends JPanel {
        public MyPanel() {
            addMouseListener(new mouseAdapter() {
                public void mousePressed(MouseEvent e) {   // 눌렀을 때 위치
                    x1 = e.getX();
                    y1 = e.getY(); 
                }
                
                public void mouseReleased(MouseEvent e) {    // 뗄 때 위치
                    x2 = e.getX();
                    y2 = e.getY();
                    x = Math.min(x1, x2);
                    y = Math.min(y1, y2);     // 사각형 시작점
                    w = Math.abs(x1-x2);
                    h = Math.abs(y1-y2);
                    
                    list.add(new Rect(x, y, w, h));    // 사각형 객체 모음
                    repaint();
                }
            });
        }
        
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.orange);
            g.fillRect(x, y, w, h);    // 드래그하는 동안 그려지는 사각형
            for(Rect r : list)
                g.drawRect(r.x, r.y, r.w, r.h);
        }
    }
    
    public GraphicTest() {
        add(new MyPanel());
        setSize(600, 400);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    
    public static void main(String[] args) {
        new GraphicTest();
    }
}

 

 

9. 예제2) 바운싱 볼 애니메이션

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class BounceBall extends JFrame implements ActionListener{
    static final int WIDTH = 600;
    static final int HEIGHT = 200;
    private static final int PERIOD = 10;
    
    class MyPanel extends JPanel {
        int x = 0, y = 0, xInc = 3, yInc = 3, diameter = 60;
        
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            if(x < 0 || x > (BounceBall.WIDTH - diameter))
                xInc = -xInc;
            if(y < 0 || y > (BounceBall.HEIGHT - diameter))
                yInc = -yInc;
            
            x += xInc;
            y += yInc;
            g.setColor(Color.RED);
            g.fillOval(x, y, diameter, diameter);
        }
    }
    
    public BounceBall() {
        MyPanel panel = new MyPanel();
        panel.setPreferredSize(new Dimension(WIDTH, HEIGHT));
        add(panel);
        pack();
        
        Timer timer = new Timer(PERIOD, this);
        timer.start();
        
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

	@Override
	public void actionPerformed(ActionEvent e) {
		repaint();
	}
    
    public static void main(String[] args) {
        new BounceBall();
    }
}

 

 

 

'Software > JAVA' 카테고리의 다른 글

[JAVA] Day13. 파일 입출력  (0) 2023.01.18
[JAVA] Day12. 제네릭과 컬렉션  (0) 2023.01.11
[JAVA] Day10. 스윙 컴포넌트  (0) 2023.01.09
[JAVA] Day9. 이벤트 처리  (2) 2023.01.08
[JAVA] Day8. 자바 GUI 기초  (2) 2023.01.08

[출처: 실무로 배우는 빅데이터 기술, 김강원 저]

 

1. 클라우데라 매니저(CM) 설치

- CM : 빅데이터 에코시스템을 쉽게 설치하고 관리해주는 빅데이터 시스템 자동화 도구

- 빅데이터 소프트웨어에 대한 프로비저닝, 매니지먼트, 모니터링 수행

  - 프로비저닝 : 하둡 에코시스템 편리하게 설치, 삭제, 수정 관리

  - 매니지먼트 : 설치한 에코시스템의 설정 변경 및 최적화 지원

  - 모니터링 : 하드웨어의 리소스 및 설치 컴포넌트의 상태 모니터링 / 대시보드

 

2. 가상머신 서버 설치

- 원래는 명령어를 이용하여 CM을 설치해야 하지만, 현재 CM 정책이 수정되어 책에 나와있는 명령어로 설치가 안됨

- 저자님의 깃허브에서 가상머신 2개 이미지 파일을 받을 수 있음

https://drive.google.com/file/d/1oLikMIC6bzt0jNV0n49YNOM0foNPXDZh/view?usp=sharing 

 

Pilot Project VM.zip

 

drive.google.com

 

- 기존에 설치했던 서버들을 지우고, 이 이미지 파일로 서버를 설치하면 됨

 

3. 파일럿 pc 운영체제 호스트 파일 수정

- 메모장 관리자 권한으로 실행

- [파일] - [열기] 에서 C:\Windows\System32\drivers\etc 로 이동 후 hosts 파일 열기

- 가상머신에 설치한 리눅스 서버의 IP/도메인명 정보 입력 후 저장 (server01, server02만 입력)

 

4. 크롬으로 CM 접속

http://server01.hadoop.com:7180 

- 기동하는데 시간이 조금 걸리기 때문에 접속이 바로 안되더라도 여러 번 새로고침

- 사용자 이름, 암호 모두 admin

 

- CM 첫화면

- 우선은 HDFS, YARN, ZooKeeper 만 설치

 

- CM 홈화면

- 각 서버의 리소스(CPU,  메모리, 디스크, I/O 등)와 설치된 SW 모니터링하며 현재 상태값 보여줌

- 각 소프트웨어가 불량으로 표시되어도, 정지 상태가 아니라면 진행에 문제 없음 -> 리소스 절약

 

5. HDFS 구성 변경

1) HDFS 복제 계수 설정

- 하둡에서 원본 파일을 저장하면 안정성을 위해 2개의 복제본 추가로 생성해 총 3개의 파일 만들어짐

- 파일럿 프로젝트에서는 2개로도 충분하기 때문에 2개로 변경

- 복제 계수를 늘리면 여러 데이터노드에 파일이 분산 저장되어 분석 작업시 성능 극대화 

 

 

2) HDFS 접근 권한 해제

- 하둡 파일시스템에 대한 접근 권한 해제

- 테스트 환경을 고려한 설정. 실제 플젝에서는 계정별로 접근 권한 분리하여 적용

 

3) HDFS 블록 크기 변경

- 128MB -> 64MB 

- 파일럿 프로젝트에서 수집/적재하는 파일의 최대 크기는 110MB

- 하둡은 기본 블록 크기보다 작은 파일 처리시 효율성 떨어짐

 

6. YARN 구성 변경

- YARN 스케줄러와 리소스매니저 메모리 크기 설정

- 1-> 1.5 GiB

 

2) YARN 스케줄러 변경

- 하둡에서 job이 실행될 때 YARN의 스케줄러가 분산 데이터노드의 리소스를 고려해 잡 스케줄링

- FairScheduler -> FIFOScheduler

- Fair가 더 개선된 스케줄이지만, 개인의 pc로 이용하기에는 리소스 경합이 발생해 병목 현상 발생

* 병목 현상: 두 구성 요소의 최대 성능의 차이로 인해 한 구성 요소가 다른 하드웨어의 잠재 성능을 제한하는 것

 

7. 클러스터 재시작

- 설정들 최종 반영하기 위해 클러스터 재시작

- 홈에서 [Cluster 1] - [작업] - [재시작]

 

8. HDFS 예제 실습

- 저자님 깃허브에서 예제소스 폴더 다운로드 (제가 올려도 되는건지 모르겠어서 링크는 생략하겠습니다)

 

1) Filezilla로 샘플 txt 파일 -> server02 /home/bigdata 로 전송

 

* HDFS 명령어

https://hadoop.apache.org/docs/r3.1.2/hadoop-project-dist/hadoop-common/FileSystemShell.html

 

Apache Hadoop 3.1.2 – Overview

<!--- Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or a

hadoop.apache.org

hdfs dfs [GENERIC_OPTIONS] [COMMAND_OPTIONS]
# cat : 파일 읽어서 보여줌 (리눅스 cat과 동일)
hdfs dfs -cat [경로]

# count : 폴더, 파일, 파일 사이즈
hdfs dfs -count [경로]

# ls : 디렉터리 내부 파일
hdfs dfs -ls [디렉터리]

# mkdir : 특정 path에 디렉터리 생성
hdfs dfs -mkdir (-p) [path]

# cp : 파일 복사
hdfs dfs -cp [소스 경로] [복사 경로]

 

2) 파일 저장 및 확인

cd /home/bigdata
hdfs dfs -put Sample.txt /tmp

- Sample.txt 파일이 HDFS의 /tmp 디렉터리로 저장됨

 

hdfs dfs -ls /tmp

- 파일 목록에 Sample.txt 존재

 

3) 파일 내용 보기

hdfs dfs -cat /tmp/Sample.txt

 

4) 저장한 파일 상태 확인

hdfs dfs -stat '%b %o %r %u %n' /tmp/Sample.txt

- 파일 크기, 파일 블록 크기, 복제 수, 소유자명, 파일명 정보 보여줌

 

5) 파일 이름 바꾸기

hdfs dfs -mv /tmp/Sample.txt /tmp/Sample2.txt

- Sample.txt -> Sample2.txt로 변경

 

6) 파일 시스템 상태 검사

hdfs fsck /

- 전체 크기, 디렉터리 수, 파일 수, 노트 수 등 파일 시스템의 전체 상태 보여줌

 

hdfs dfsadmin -report

- 하둡 파일시스템의 기본 정보 및 통계 보여줌

 

HDFS 파일의 비정상 상태

- HDFS 점검 명령을 실행할 때 파일 시스템에 문제가 발생할 경우 "CORRUPT FILES", "MISSING BLOCKS", "MISSING SIZE", "CORRUPT BLOCKS" 등의 항목에 숫자가 표기됨

- 이 같은 상태가 지속되면 하둡은 물론 HBase, 하이브 등에 부분적인 문제 발생 가능

- HDFS는 비정상적인 파일 블록 발견한 경우 다른 노드에 복구하려고 시도, 사용자가 직접 삭제/이동 명령 조치할 수 있음

# 강제로 안전모드 해제
hdfs dfsadmin -safemode leave

# 손상된 파일 강제로 삭제
hdfs fsck / -delete

# 손상된 파일을 /lost + found 디렉터리로 이동
hdfs fsck / -move

 

9. 주키퍼 클라이언트 명령을 이용한 설치 확인

1) zookeeper-client 실행

zookeeper-client

 

2) 주키퍼 z노드 등록/조회/삭제

create /pilot-pjt bigdata
ls /
get /pilot-pjt
delete /pilot-pjt

- bigdata를 담고 있는 pilot-pjt 라는 znode 생성, 조회, 삭제

 

** zookeeper와 znode

- zookeeper : 분산 어플리케이션을 구성하기 쉽게 도와주는 시스템 (znode로 구성된 분산 데이터 모델을 지원하는 시스템)

- z노드 : 클러스터를 구성하고 있는 각각의 서버

- 주키퍼는 데이터를 디렉터리 구조로 관리하며, key-value 스토리지처럼 key로 접근 가능

- 디렉터리 구조의 각 데이터 노드가 znode

 

# 참고 사이트

https://engkimbs.tistory.com/660

 

[주키퍼, Zookeeper] 아파치 주키퍼(Apache Zookeeper) 소개 및 아키텍처

| 대규모 분산 시스템과 코디네이션 시스템의 필요성? 과거에는 한 대의 컴퓨터에서 동작하는 단일 프로그램이 대다수였지만, 현재 빅데이터와 클라우드 환경에서 대규모의 시스템들이 동작하

engkimbs.tistory.com

 

10. 스마트카 로그 시뮬레이터 설치

1) server02에 작업 폴더 생성

cd /home
mkdir -p /home/pilot-pjt/working/car-batch-log
mkdir /home/pilot-pjt/working/driver-realtime-log
chmod 777 -R /home/pilot-pjt

 

2) 자바 컴파일, 실행 환경 변경 (1.7 -> 1.8)

rm /usr/bin/java
rm /usr/bin/javac
ln -s /usr/java/jdk1.8.0_181-cloudera/bin/javac /usr/bin/javac
ln -s /usr/java/jdk1.8.0_181-cloudera/bin/java /usr/bin/java
java -version

- 1.8.0_181 확인

 

3) 자바로 만들어진 스마트카 로그 시뮬레이터 프로그램 server02에 업로드

- 파일질라 이용

- bigdata.smartcar.loggen-1.0.jar 파일을 /home/pilot-pjt/working에 업로드

# 저 파일을 열어서 코드를 보고싶었는데 일단 찾은 방법들이 전부 맥으로는 실행이 안돼서 다음에 시도해보겠음 ,,

 

4) 스마트카 로그 시뮬레이터 실행

- bigdata.smartcar.loggen-1.0.jar 파일에 두 개의 메인 자바프로그램이 있음

- 1. 스마트카 운전자의 운행 정보를 실시간으로 발생시키는 DriverLogMain.java

- 2. 스마트카의 상태 정보를 주기적으로 발생시키는 CarLoginMain.java

 

- DriverLogMain.java 먼저 실행

cd /home/pilot-pjt/working
java -cp bigdata.smartcar.loggen-1.0.jar com.wikibook.bigdata.smartcar.loggen.DriverLogMain 20160101 10

* java -cp [경로] [클래스 이름]  (현재 열려 있는 명령 창에서만 유효)

- cp (classpath) : JVM이 프로그램을 실행할 때 클래스 파일을 찾는 데 기준이 되는 파일 경로, JVM의 매개 변수

- 자바에서 외부 라이브러리 파일이나 jar 파일 포함하여 컴파일하기 위해서는 classpath 이용

 

- bigdata.smartcar.loggen-1.0.jar : 포함하고자 하는 라이브러리나 jar 파일 (필요한 클래스 파일들)

- com.wikibook.bigdata.smartcar.loggen.DriverLogMain : 컴파일 할 파일

 

- 시뮬레이터 작동 확인

cd /home/pilot-pjt/working/driver-realtime-log
tail -f SmartCarDriverInfo.log

 

- 데이터 형식 정의

 

- CarLogMain.java 실행

cd /home/pilot-pjt/working
java -cp bigdata.smartcar.loggen-1.0.jar com.wikibook.bigdata.smartcar.loggen.CarLogMain 20160101 10

* 코드 설명

- 첫번째 매개 변수: 실행 날짜 

- 두번째 매개 변수: 스마트카 대 수

-> 2016년 1월 1일 기준으로 10대의 스마트카에 대한 로그 파일인 SmartCarStatusInfo_20160101.txt 생성됨

 

- 시뮬레이터 작동 확인

cd /home/pilot-pjt/working/SmartCar
tail -f SmartCarStatusInfo_20160101.txt

 

- 데이터 형식 정의

1. 스윙 컴포넌트

- 윈도우 기반 응용 프로그램을 만드는데 사용되는 JFC(Java Foundation Classes) 의 일부

- AWT와 달리 플랫폼 독립적이고 경량 컴포넌트 구조

- JButton, JTextField, JTextArea, JRadioButton, JCheckbox, JMenu, JColorChooser 등

 

2. JComponent 클래스

- 최상위 컨테이너를 제외하고는 거의 모든 컴포넌트가 JComponent를 상속받음

- ex) JPanel, JLabel, JComboBox 등

- 스윙 컴포넌트들이 공통적으로 가져야하는 속성과 메소드 포함

 

- JComponent 메소드

 

3. 예제

- 텍스트 필드로 사용자에게 정수 입력받은 뒤 제곱 반환

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class TextTest extends JFrame {
    private JButton button;
    private JTextField text, result;
    public TextTest() {
        setSize(300, 150);
        
        ButtonListener listener = new ButtonListener();
        JPanel panel = new JPanel();
        panel.add(new JLabel("숫자 입력: "));
        
        text = new JTextField(15);
        text.addActionListener(listener);
        panel.add(text);
        
        panel.add(new JLabel("제곱한 값: "));
        result = new JTextField(15);
        result.setEditable(false);    // 출력만 가능
        panel.add(result);
        
        button = new JButton("OK");
        button.addActionListener(listener);
        panel.add(button);
        add(panel);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    
    // 내부 클래스로서 텍스트 필드와 버튼의 액션 이벤트 처리
    private class ButtonListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            if(e.getSource() == button || e.getSource() == text) {
                String name = text.getText();
                int value = Integer.parseInt(name);
                resutl.setText("" + value * value);
                text.requestFocus();         // 텍스트창 선택됨
            }
        }
    }
    
    public static void main(String[] args) { 
        new TextTest();
    }
}

 

4. JTextArea

- 텍스트 필드는 한 줄만 들어갈 수 있는 반면, 텍스트 영역은 여러 줄의 텍스트 들어갈 수 있음

- textArea = new JTextArea(10, 30);     // 10행 30열의 텍스트 영역 생성

 

5. scroll pane 

- 컴포넌트에 스크롤 기능 제공

textArea = new JTextArea(6, 30);
JScrollPane scrollpane = new JScrollPane(textArea);
add(scrollpane, "Center");

 

6. check box

- 체크박스를 클릭하면 ItemEvent 발생

-> ItemListener 구현해야 함 - 익명 클래스 사용하는 것이 편함

JCheckBox check = new JChechBox("CheckBox", false);
check.addItemListener(new ItemListener() {
    public void itemStateChanged(ItemEvent e) {
        System.out.println("체크 상태: " + check.isSelected());
    }
});

 

- 예제

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class CheckBoxTest extends JFrame { 
    public CheckBoxTest() { 
        setLayout(new GridLayout(0, 1));
        JLabel label = new JLabel();
        JCheckBox cbPizza = new JCheckBox("피자");
        JCheckBox cbPasta = new JCheckBox("스파게티");
        add(cbPizza);
        add(cbPasta);
        add(label);
        
        cbPizza.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                label.setText("피자가 " + (e.getStateChange() == 1 ? "선택되었습니다." : "선택해제되었습니다."));
            }
        });
        
        cbPasta.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                label.setText("스파게티가 " + (e.getStateChange() == 1 ? "선택되었습니다." : "선택해제되었습니다."));
            }
        });
        
        setSize(300, 150);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    
    public static void main(String[] args) {
        new CheckBoxTest();
    }
}

 

7. 라디오 버튼

- 체크 박스와 비슷하지만, 라디오 버튼은 하나의 버튼 그룹 안에서는 한 개의 버튼만 선택할 수 있음

JRadioButton radio1 = new JRadioButton("Small Size");
JRadioButton radio2 = new JRadioButton("Medium Size");
JRadioButton radio3 = new JRadioButton("Large Size");

// button group 객체 생성
ButtonGroup group = new ButtonGroup();

// 그룹에 라디오 버튼 객체들 추가
group.add(radio1);
group.add(radio2);
group.add(radio3);

 

8. 콤보 박스

- 여러 항목 중에서 하나 선택

- 텍스트 필드와 리스트의 결합

- 텍스트 직접 입력, 리스트에서 선택 둘 다 가능

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class ComboBoxFrame extends JFrame implements ActionListener {
    JLabel lbl;
    
    public ComboBoxFrame() {
        setSize(400, 200);
        
        String[] ani = {"dog", "cat", "bird"};
        JComboBox aniList = new JComboBox(ani);
        aniList.setSelectedIndex(0);
        aniList.addActionListener(this);
        
        lbl = new JLabel();
        lbl.setHorizontalAlignment(JLabel.CENTER);
        changePicture(ani[aniList.getSelectedIndex()]);
        
        add(aniList, "North");
        add(lbl, "Center");
        setVisible(true)
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    
    public void actionPerformed(ActionEvent e) {
        JComboBox cb = (JComboBox) e.getSource();
        String name = (String) cb.getSelectedItem();
        changePicture(name);
    }
    
    protected void changePicture(String name) {
        ImageIcon icon = new ImageIcon(name + ".png");
        lbl.setIcon(icon);
        if(icon != null) 
            lbl.setText(null);
        else
            lbl.setText("이미지가 발견되지 않았습니다.");
    }
    
    public static void main(String[] args) {
        new ComboBoxFrame();
    }
}

 

9. 메뉴 붙이기

- 윈도우 상단에 위치한 메뉴바 생성

- 팝업 메뉴는 팝업이 가능한 컴포넌트 위에서 마우스 오른쪽 버튼을 누르면 그 위치에 등장

- 메뉴 항목은 이미지나 텍스트 가질 수 있음

 

- 메뉴 생성 절차 [메뉴바 - 메뉴 - 메뉴항목]

// 1. 메뉴바 관련 변수 설정
JMenuBar menuBar;
JMenu menu;
JMenuItem menuItem;

// 2. 메뉴바 생성
menuBar = new JMenuBar();

// 3. 메뉴 생성하여 메뉴바에 추가
menu = JMenu("메뉴 1");
menuBar.add(menu);

// 4. 메뉴 항목 생성하여 메뉴에 추가
menuItem = new JMenuItem("메뉴 항목1", KeyEvent.VK_T);
menu.add(menuItem);

// 5. 프레임에 메뉴바 설정
frame.setJMenuBar(mb);

 

- 메뉴 이벤트 처리

// 각각의 메뉴 항목에 대해 액션 이벤트 처리기 등록
menuItem.addActionListener(this);

 

10. 슬라이더

- 사용자가 특정한 범위 안에서 하나의 값을 선택할 수 있는 컴포넌트

- 슬라이더, 이벤트 처리

slider = new JSlider(0, 100, 50);

slider.setMajorTickSpacing(10);     // 큰 눈금 간격
slider.setMinorTickSpacing(1);      // 작은 눈금 간격
slider.setPaintTicks(true);         // 눈금 표시
slider.setPaintLabels(true);        // 값을 레이블로 표시

slider.addChangeListener(this);

public void stateChanged(ChangeEvent e) {
    JSlider source = (JSlider) e.getSource();
    if (!source.getValueIsAdjusting()) {
        int value = (int) source.getValue();
        button.setSize(value * 10, value * 10);
}

'Software > JAVA' 카테고리의 다른 글

[JAVA] Day12. 제네릭과 컬렉션  (0) 2023.01.11
[JAVA] Day11. 자바 그래픽  (5) 2023.01.10
[JAVA] Day9. 이벤트 처리  (2) 2023.01.08
[JAVA] Day8. 자바 GUI 기초  (2) 2023.01.08
[JAVA] Day7. 자바 API 패키지, 예외처리, 모듈  (0) 2023.01.02

1. 이벤트

- 사용자가 버튼을 클릭한다거나, 마우스를 움직이거나, 키를 누르면 발생

- 이벤트 리스너 : 발생된 이벤트 객체에 반응하여 이벤트를 처리하는 객체

 

2. 이벤트 처리 과정

1) 이벤트 리스너 작성

class MyListener implements ActionListener {
    public void actionPerformed (ActionEvent e) {
        // Action event 처리
        // 이벤트 객체가 발생하면 호출됨!
    }
}

 

2) 이벤트 리스너를 컴포넌트에 등록

public class MyFrame extends JFrame {
    JButton button;
    ...
    public MyFrame() {   // 생성자에서 컴포넌트 생성, 추가
        button = new JButton("동작");
        button.addActionListener(new MyListener());   // 이벤트 리스너 객체 생성, 등록
        ...
    }
}

 

3. 이벤트 객체

- 이벤트 객체는 발생된 이벤트에 대한 모든 정보를 리스너로 전달

- 이벤트 객체는 getSource() 액션 이벤트가 발생하면 호출됨

public void actionPerformed(ActionEvent e) {
    button = (JButton)e.getSource();
    ...
}

 

4. 이벤트 처리기 위치

1) 독립적인 클래스로 이벤트 처리기 작성

 

2) 내부 클래스로 이벤트 처리기 작성 

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class EventTest1 extends JFrame {
    private JButton button;
    private JLabel label;
    int counter = 0;
    
    class MyListener implements ActionListener {       // 리스너 클래스
        public void actionPerformed(ActionEvent e) {
            counter++;
            label.setText("현재 카운터값: " + counter);
        }
    }
    
    public EventTest1() {     // 생성자
        setSize(400, 150);
        setLayout(new FlowLayout());
        button = new JButton("증가");
        label = new JLabel("현재 카운터값: " + counter);
        
        button.addActionListener(new MyListener());  // 리스너 컴포넌트에 등록
        add(label);
        add(button);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    
    public static void main(String[] args) {
        new EventTest1();
    }
}

 

3) 프레임 클래스에 이벤트 추리 구현

- JFrame 상속받으면서 동시에 ActionListener 인터페이스 구현

- 리스너 클래스 없이 바로 함수가 나온 것

public class EventTest2 extends JFrame implements ActionListener {
    private JButton button;
    private JLabel label;
    int counter = 0;
    
    public void actionPerformed(ActionEvent e) {
        counter++;
        label.setText("현재 카운터값: " + counter);
    }
    
    public EventTest2() {
        this.setSize(400, 150);
        button = new JButton("증가");
        label = new JLabel("현재 카운터값: " + counter);
        
        button.addActionListener(this);
        add(label);
        add(button);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    
    public static void main(String[] args) {
        new EventTest2();
    }
}

 

4) 익명 클래스 사용

- 한 번만 사용할 때

- 클래스가 정의되면서 바로 사용

- 안드로이드 프로그래밍에서도 자주 사용됨

public class EventTest3 extends JFrame {
    private JButton button;
    private JLabel label;
    int counter = 0;
    
    public EventTest3() {
        this.setSize(400, 150);
        button = new JButton("증가");
        label = new JLabel("현재 카운터값: " + counter);
        
        button.addActionListener(new ActionListener() {      // 익명 클래스 - 바로 정의
            public void actionPerfomed(ActionEvent e) {
                counter++;
                label.setText("현재 카운터값: " + counter);
            }
        });
        
        add(label);
        add(button);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
}

 

- 일반 클래스와 익명 클래스 비교

익명 클래스 일반 클래스
ActionListener obj = new ActionListener() {
    ...
};
class MyListener implements ActionListener { 
    ...
}
MyListener obj = new MyListener();

 

5) 람다식 이용

- 람다식 : 이름이 없는 메소드 -> 간결함

(int a, int b)   ->    { return a + b; }
// 메소드 시그니처 람다연산자    메소드 구현
public class EventTest4 extends JFrame {
    private JButton button;
    private JLabel label;
    int counter = 0;
    
    public EventTest4() {
        this.setSize(400, 150);
        button = new JButton("증가");
        label = new JLabel("현재 카운터값: " + counter);
        
        button.addActionListener(e -> {            // 람다식
            counter++;
            label.setText("현재 카운터값: " + counter);
        });
        
        add(label);
        add(button);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
}

 

5. 스윙 컴포넌트의 이벤트

1) 저수준 이벤트 : 모든 컴포넌트가 공통적으로 지원

  - Mouse, MouseAction, Key, Component, Container, Focus, Window

 

2) 의미적 이벤트 : 일부 컴포넌트만 지원

  - Action, Adjustment, Document, Item, Text

 

6. 액션 이벤트

- 사용자가 버튼을 클릭하는 경우

- 사용자가 메뉴 항목을 선택하는 경우

- 사용자가 텍스트 필드에서 엔터키를 누르는 경우

 

예제 1) 패널 배경색 바꾸기

// 익명클래스

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class ChangeBackground extends JFrame {
    private JButton button1;
    private JButton button2;
    private JPanel panel;
    
    public ChangeBackground() {
        panel = new JPanel();
        button1 = new JButton("노란색");
        button2 = new JButton("분홍색");
        
        button1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                panel.setBackground(Color.yellow);
            }
        });
        
        button2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                panel.setBackground(Color.pink);
            }
        });
    
    	panel.add(button1);
        panel.add(button2);
    	add(panel);
        setSize(500, 400);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    
    
    
    public static void main(String[] args) {
        new ChangeBackground();
    }
}
// 내부클래스

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class ChangeBackground extends JFrame {
    private JButton button1;
    private JButton button2;
    private JPanel panel;
    MyListener listener = new MyListener();
    
    public ChangeBackground() {
        panel = new JPanel();
        button1 = new JButton("노란색");
        button2 = new JButton("분홍색");
 
        button1.addActionListener(listener);
        button2.addActionListener(listener);
    
    	panel.add(button1);
        panel.add(button2);
    	add(panel);
        setSize(500, 400);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    
    private class MyListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            if(e.getSource() == button1)
                panel.setBackground(Color.yellow);
            else if(e.getSource() == button2) 
                panel.setBackground(Color.pink);
        }
    }
    
    public static void main(String[] args) {
        new ChangeBackground();
    }
}

 

예제 2) 키패드 만들기

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class KeyPad extends JFrame implements ActionListener {
    private JTextField txt;
    private JPanel panel;
    
    public KeyPad() {
        txt = new JTextField(20);
        add(txt, "North");
        
        panel = new JPanel();
        panel.setLayout(new GridLayout(3,3));
        add(panel, "Center");
        
        for(int i = 1; i <= 9; i++) {
            JButton btn = new JButton("" + i);
            btn.addActionListener(this);
            btn.setPreferredSize(new Dimension(100, 30));
            panel.add(btn);
        }
        
        pack();
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    
    @Override
    public void actionPerformed(ActionEvent e) {
        String actionCommand = e.getActionCommand();
        txt.setText(txt.getText() + actionCommand);
    }
    
    public static void main(String[] args) {
        new KeyPad();
    }
}

 

예제 3) 가위바위보

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;

public class RockPaperScissor extends JFrame implements ActionListener { 
    final int SCISSOR = 0;
    final int ROCK = 1;
    final int PAPER = 2;
    private JPanel panel;
    private JLabel output, information;
    private JButton rock, paper, scissor;
    public RockPaperScissor() {
        setSize(400, 150);
        
        panel = new JPanel();
        panel.setLayout(new GridLayout(0, 3));
        
        information = new JLabel("아래의 버튼 중 하나를 선택하세요.");
        output = new JLabel("Good Luck!");
        
        scissor = new JButton("0: 가위");
        rock = new JButton("1: 바위");
        paper = new JButton("2: 보");
        
        scissor.addActionListener(this);
        rock.addActionListener(this);
        paper.addActionListener(this);
        
        panel.add(scissor);
        panel.add(rock);
        panel.add(paper);
        
        add(information, "North");
        add(panel, "Center");
        add(output, "South");
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    
    @Override
    public void actionPerformed(ActionEvent e) {
        JButton b = (JButton)e.getSource()    // 이벤트 발생 컴포넌트 추출
        int user = Integer.parseInt(""+b.getText().charAt(0)); // 첫번째 글자 추출
        Random random = new Random();
        int computer = random.nextInt(3);
        
        if(user == computer)
            output.setText("비겼음");
        else if(user == (computer + 1) % 3)     // 0은 1한테 진다
            output.setText("인간: " + user + " 컴퓨터: " + computer + " 인간 승리");
        else
            output.setText("인간: " + user + " 컴퓨터: " + computer + " 컴퓨터 승리");
    }
    
    public static void main(String[] args) {
        new RockPaperScissor();
    }
}

 

7. 키 이벤트

- 사용자가 키보드를 이용하여 입력하는 경우

- keyPressed : 키를 누르면 이벤트 발생

- keyReleased : 키에서 손을 떼면 이벤트 발생

- keyTyped : 입력된 유니코드 문자 전송됨

 

8. 포커스

- 컴포넌트가 키 이벤트를 받으려면 반드시 포커스(focus)를 가지고 있어야 함

- 포커스 : 키 입력을 받을 권리

- 일반적으로 오직 한 개의 컴포넌트만 포커스를 가지고 있어 키 입력을 독점하게 됨

panel.setFocusable(true);
panel.requestFocus();

 

9. KeyListener 인터페이스

public class MyListener implements KeyListener {
    public void keyPressed(KeyEvent e) {   }
    public void keyReleased(KeyEvent e) {   }
    public void keyTyped(KeyEvent e) {    }
}

 

10. KeyEvent 클래스

- int getKeyChar() : KeyEvent에 들어있는 글자 (유니코드) 반환

- int getKeyCode() : KeyEvent에 들어있는 keycode 반환 (글자가 아닌, 키보드 자판의 각각의 키를 가리키는 상수)

    - ex) Escape의 키코드 = VK_ESCAPE

- boolean isActionKey() : 이벤트를 발생시킨 키가 액션 키이면 true 반환

    - 액션 키 : Cut, Copy, Paste, Page Up, Caps Lock, 화살표, function 키

 

11. 자동차 움직이기 예제

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class MoveCar extends JFrame {
    int img_x = 150, img_y = 150;
    JButton button;
    
    public MoveCar() {
        setSize(600, 300);
        button = new Button("");       // 이미지 - 버튼으로 출력
        ImageIcon icon = new ImageIcon("car.png");   // 패키지 폴더에 있는 사진 
        button.setIcon(icon);
        
        JPanel panel = new JPanel();
        panel.setLayout(null);
        button.setLocation(img_x, img_y);
        button.setSize(200, 100);
        
        panel.add(button)
        panel.requestFocus();
        
        panel.setFocusable(true);
        panel.addKeyListener(new KeyListener() {
            public void keyPressed(KeyEvent e) {
                int keycode = e.getKeyCode();
                switch(keycode) {
                case KeyEvent.VK_UP: img_y -= 10; break;
                case KeyEvent.VK_DOWN: img_y += 10; break;
                case KeyEvent.VK_LEFT: img_x -= 10; break;
                case KeyEvent.VK_RIGHT: img_x += 10; break;
                }
                button.setLocation(img_x, img_y);
            }
            public void keyReleased(KeyEvent arg0) { }
            public void keyTyped(KeyEvent arg0) { }
        });
        add(panel);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    
    public static void main(String[] args) {
        new MoveCar();
    }
}

 

12. Mouse, MouseMotion 이벤트

1) MouseListener 인터페이스

public class MyListener implements MouseListener {
    public void mousePressed(MouseEvent e) {  }   // 사용자가 컴포넌트 클릭한 경우 
    public void mouseReleased(MouseEvent e) {  }  // 마우스가 컴포넌트에서 떼어진 경우
    public void mouseEntered(MouseEvent e) {  }   // 마우스 커서가 컴포넌트로 들어간 경우
    public void mouseExited(MouseEvent e) {  }    // 커서가 컴포넌트에서 나간 경우
    public void mouseClicked(MouseEvent e) {  }   // 마우스로 컴포넌트를 누른 경우
}

 

2) MouseMotionListener 인터페이스

public class MyClass implements MouseMotionListener {
    public void mouseDragged(MouseEvent e) {  } // 마우스를 드래그 한 경우
    public void mouseMoved(MouseEvent e) {  }   // 마우스를 클릭하지 않고 이동하는 경우
}


13. MouseEvent 객체

 

14. 어댑터 클래스

- 이벤트를 처리하기 위해서는 리스너 인터페이스에서 정의되어 있는 모든 메소드를 (사용하지 않더라도) 구현해야 함 -> 번거로움

- 어댑터 클래스를 이용하면 필요한 메소드만 재정의 가능

- 어댑터 클래스 : 인터페이스를 구현해놓은 클래스 -> 상속받기

public abstract class MouseAdapter implements MouseListener, MouseWheelListener, MouseMotionListener {
    public void mouseClicked(MouseEvent e) {}
    public void mousePressed(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mouseWheelMoved(MouseWheelEvent e) {}
    public void mouseDragged(MouseEvent e) {}
    public void mouseMoved(MouseEvent e) {}
}
class MyLister extends MouseAdapter {          // 리스너 클래스
    public void mouseCliked(MouseEvent e) {    // 필요한 메소드만 구현 
        if (e.getX > 300) { ... }
    }
}

1. 그래픽 사용자 인터페이스 (GUI)

- 컴포넌트들로 구성

Java AWT Java Swing
플랫폼에 의존적 플랫폼에 독립적
컴포넌트들이 용량이 큼 컴포넌트 용량이 가벼움
교체할 수 있는 룩앤필(look and feel) 지원 X 교체할 수 있는 룩앤필(look and feel) 지원 O
컴포넌트 개수 적음 컴포넌트 개수 많음

 

2. 스윙 패키지 

- java.awt : GUI 컴포넌트를 위한 부모 클래스들 제공 + color, point와 같은 유틸리티 타입의 클래스 포함

- java.awt.event : GUI 컴포넌트로부터 발생되는 이벤트를 처리하기 위한 클래스와 인터페이스 (버튼 클릭, 마우스 움직임 등)

- javax.swing : 버튼, 텍스트 필드, 프레임, 패널과 같은 GUI 컴포넌트들 포함

 

3. 컨테이너와 컴포넌트

- 기본 컴포넌트 : JButton, JLabel, JCheckBox, JChoice, JList, JMenu, JTextField, JScrollbar, JTextArea, JCanvas 등

- 컨테이너 컴포넌트 : 다른 컴포넌트들을 안에 포함할 수 있는 컴포넌트

   : JFrame, JDialog, JApplet, JPanel, JScrollPane 등

 

- 최상위 컨테이너 : 절대 다른 컨테이너 안에 포함될 수 없는 컨테이너 (JFrame, JDialog, JApplet 등)

- 일반 컨테이너 : 다른 컨테이너 안에 포함될 수 있는 컨테이너 (JPanel, JScrollPane 등)

 

4. GUI 작성 절차

- 컨테이너 생성 -> 컴포넌트 추가

 

5. 프레임 생성

#1
import javax.swing.*;

public class FrameTest {
    public static void main(String[] args) {
        JFrame f = new JFrame("Frame Test");
        f.setTitle("MyFrame");
        f.setSize(300, 200);
        f.setVisible(true);
        f.DefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
#2
import javax.swing.*;

public class MyFrame extends JFrame {
    pubic MyFrame() {
        setSize(300, 200);
        setTitle("My Frame");
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    
    public static void main(String[] args) {
        new MyFrame();
    }
}

 

6. 프레임에 버튼 추가

import javax.swing.*;
import java.awt.*;

public class MyFrame extends JFrame {
    public MyFrame() {
        setSize(300, 200);
        setTitle("My Frame");
        
        setLayout(new FlowLayout());
        JButton button = new JButton("버튼");
        add(button);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    public static void main(String[] args) {
        new MyFrame();
    }
}

 

7. 컨테이너 - JFrame

 

- 컨테이너는 컴포넌트들을 트리 형태로 저장

- 최상위 컨테이너는 이 트리의 루트 노드가 됨

- 최상위 컨테이너는 내부에 콘텐트 팬 보유 - 화면에 보이는 컴포넌트 저장

- 최상위 컨테이너에는 메뉴바 추가 가능

 

7-1) 중요 메소드

- add(component) : 프레임에 컴포넌트 추가

- setLocation(x, y), setSize(width, height) : 프레임의 위치와 크기 설정

- setIconImage(IconImage) : 윈도우 시스템에 타이틀 바, 태스크 스위처에 표시할 아이콘

- setTitle() : 타이틀바 제목 변경

- setResizable(boolean) : 사용자가 크기 조절 가능 여부

 

8. JPanel 클래스

- 패널 : 컴포넌트들을 부착할 수 있도록 설계된 컨테이너 중 하나 (최상위 컨테이너는 아님)

- 별도의 패널을 쓰는 것이 유지 보수 및 배치 관리에 유리한 경우가 많음

 

- add(aComponent) : 패널에 컴포넌트 추가

- remove(aComponent) : 패널에 컴포넌트 삭제

- setBackGround(Color c) : 패널의 배경색 변경

 

8-1) 예제

public class MyFrame extends JFrampe {
    public MyFrame() {
        JPanel panel = new JPanel();
        panel.setBackground(Color.orange);
        
        JButton b1 = new JButton("Button 1");
        b1.setBackground(Color.yellow);
        
        JButton b2 = new JButton("Button 2");
        b2.setBackground(Color.green);
        
        panel.add(b1);
        panel.add(b2);
        add(panel);
        
        setSize(300, 150);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    public static void main(String[] args) {
        new MyFrame();
    }
}

 

9. 배치 관리자 (layout manager)

- 컨테이너만 사용 가능

- 컨테이너 안의 각 컴포넌트의 위치와 크기를 결정하는 작업

 

 9-1) 배치관리자 종류

1) FlowLayout

- 컨테이너에 추가되는 순서대로 컴포넌트 배치

- 위에서 아래로, 왼쪽에서 오른쪽으로

- 패널의 기본 배치 관리자

 

2) BorderLayout

- 컨테이너의 영역을 동서남북, 중앙의 5개 영역으로 구분하여 배치

- 한 구역에 한 개의 컴포넌트만 배치 가능

- add(btn, "South");

- 프레임의 기본 배치관리자

 

3) GridLayout

- 컨테이너 공간을 동일한 크기의 격자로 나누고, 이 격자에 컴포넌트 배치

 

4) CardLayout

- 컨테이너에 컴포넌트를 카드처럼 겹치게 쌓아 배치

- 한 번에 하나의 컴포넌트만 볼 수있게 배치

 

9-2) 설정

- 생성자 이용 : JPanel panel = new JPanel(new BorderLayout());

- setLayout() 이용 : panel.setLayout(new FlowLayout());

 

10. 절대 위치로 배치

- 배치 관리자  null로 설정 : setLayout(null);

- add() 메소드로 컴포넌트를 컨테이너에 추가

- 컴포넌트위 위치와 크기 지정

   - setBounds(h, w, a, d);

[출처: 실무로 배우는 빅데이터 기술, 김강원 저]

 

1. 설치해야 할 응용프로그램

- JAVA (Java SE 8u-)

- 이클립스

- Oracle Virtual Box

- PuTTY (SSH 접속 프로그램)

- FileZilla (FTP 접속 프로그램)

- Chrome

 

2. 리눅스 가상머신 환경 구성

1) CentOS 설치

 

2) 첫번째 리눅스 가상머신 - Server01

- 메모리 2048MB

- 가상 하드 드라이브 동적 할당 30~40GB

- OS: CentOS

 

3) 고정 IP, 네트워크 설정

vi /etc/sysconfig/network-scripts/ifcfg-eth0

# vi: 문서 편집 환경
# " i " 를 눌러서 입력모드 -> 수정
# " : "를 눌러서 명령모드
# 명령모드 진입 후 wq 를 눌러서 저장 후 종료

 

- 노란색으로 칠한 두번째 줄은 Server01 가상머신의 MAC 주소로, 가상머신 - [설정] - [네트워크] - [어댑터 2]로 이동해서 나온 MAC 주소 값을 두글자씩 잘라서 " : "로 연결하여 입력하면 됨

* /etc/sysconfig/network-scripts 

  - IP에 대한 설정 스크립트 등 있음 

  - 안에 있는 ifcfg-* 파일 수정하여 IP 변경 (+ GATEWAY, NETMASK, DNS 등 관리)

  - /ifcfg-eth0 : 리눅스 이더넷 카드(네트워크 인터페이스 컨트롤러) 0번 설정 파일

 

* DEVICE : 네트워크 인터페이스의 종류

* HWADDR : MAC 주소

* ONBOOT : 부팅시 자동 활성 여부

* BOOTPROTO : ip 할당 방식

  - static : 아이피 지정

  - dhcp : 동적 아이피

* IPADDR : IP 주소

* NETMASK : 서브넷 마스크 주소

* GATEWAY : 게이트웨이 주소

* NETWORK : 네트워크 주소

 

# 리눅스 vi 편집기 명령어 모음 참고

https://velog.io/@zeesoo/Linux-vi-%ED%8E%B8%EC%A7%91%EA%B8%B0-%EC%82%AC%EC%9A%A9%EB%B2%95-%EB%B0%8F-%EB%AA%85%EB%A0%B9%EC%96%B4

 

vi /etc/udev/rules.d/70-persistent-net.rules

- CentOS 리눅스가 기본값으로 설정한 네트워크 룰 삭제하여 향후 발생할 수 있는 네트워크 충돌 방지

- 위의 파일로 들어가서 자동으로 입력되어 있는 값 전부 삭제 또는 주석 처리 (#)

- 이후 앞서 설정한 고정 IP인 '192.168.56.101'을 할당받기 위해 가상머신 재시작

 

4) 네트워크 서비스에 고정 IP 인식

service network restart

- restart 명령을 실행한 후, 특별한 오류가 발생하지 않으면 고정 IP 설정이 완료된 것

 

5) Server01 고정 IP 확인

ifconfig eth0

 

6) SSH 접속을 위한 패키지 설

* yum : 패키지 관리 명령어

* yum <옵션> <명령어> <패키지명>

* 패키지 설치, 업데이트, 삭제, 패키지 목록 확인 등

yum install openssh*        // OpenSSH 설치
service sshd restart
chkconfig sshd on
reboot

# reboot 완료 후
service network restart

 

3. 원격 SSH 접속 프로그램인 PuTTY로 Server01("192.168.56.101") 접속

 

4. Server01 호스트 정보 수정

vi /etc/hosts

# 수정 전

# 수정 후

- Server01 뿐만 아니라 앞으로 만들 Server02, Server03 IP 및 호스트 정보 설정

- 모두 소문자로 작성

 

- Server01 HOSTNAME 설정

vi /etc/sysconfig/network

* 리눅스 로그인 했을 때 [root@server01 ~]#

  - root는 사용자 계정

  - server01 이 현재 네트워크의 이름 (호스트명)

  - ~ 는 현재 사용자가 위치한 곳

 

- 서비스 명령으로 네트워크 설정 재시작

service network restart

 

5. Server01 방화벽 및 기타 커널 매개변수 설정

1) config 파일에서 SELINUX를 "SELINUX=disabled"로 수정

* config 파일 : 설정 파일

* SELinux :  관리자가 시스템 액세스 권한을 효과적으로 제어할 수 있게 하는 리눅스 시스템용 보안 아키텍처

  - 시스템 애플리케이션, 프로세스, 파일에 대한 액세스 제어 정의

  - 파일을 여는 프로세스와 같은 엑세스를 명시적으로 허용하는 SELinux 정책 규칙이 없으면 액세스 거부됨

vi /etc/selinux/config

 

2) iptables 중지 명령

* iptables : 리눅스에서 방화벽을 설정하는 도구 (패킷필터링 도구)

* 광범위한 프로토콜 상태 추적, 패킷 어플리케이션 계층검사, 속도 제한, 필터링 정책 명시 매커니즘 제공

service iptables stop

 

# iptables 중지 명령 오류 해결 참고 사이트 (첫번째 답변)

http://daplus.net/networking-centos-7%EC%97%90%EC%84%9C-iptables%EB%A5%BC-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%82%AC%EC%9A%A9%ED%95%A0-%EC%88%98-%EC%9E%88%EC%8A%B5%EB%8B%88%EA%B9%8C-%EB%8B%AB%EC%9D%80/

 

[networking] centos 7에서 iptables를 어떻게 사용할 수 있습니까? [닫은] - 리뷰나라

닫은. 이 질문은 스택 오버플로 지침을 충족하지 않습니다 . 현재 답변을받지 않습니다. 이 질문을 개선하고 싶습니까? 질문을 업데이트하여 스택 오버플로에 대한 주제 입니다. 작년에 문을 닫

daplus.net

 

3) iptables 자동 시작 중지 명령

chkconfig iptables off

 

4) ip6tables 자동 시작 중지 명령

* ip6tables : IPv6 체계에서 사용

 chkconfig ip6tables off

 

5) vm swappiness 사용 제어 설정

* sysctl : (시스템의 /proc/sys 디렉토리 밑에 있는) 커널 변수 값을 제어하여 시스템 최적화

* 일반적으로 커널 매개변수 변경: /proc 디렉토리 밑 항목 vi 편집기 이용하여 변경 / echo 명령 이용

* -w variable=value 옵션: 변수에 값 설정

sysctl -w vm.swappiness=100

 

6) sysctl.conf 파일에서 "vm.swappiness=100" 설정 추가

* vm.swappiness : 리눅스 커널 속성 중 하나로 스왑메모리 활용 수준 조절

* Swap 메모리 : 실제 메모리 램이 가득 찼지만 더 많은 메모리가 필요할 때, 디스크 공간을 이용하여 부족한 메모리를 대체할 수 있는 공간 (실제 디스크 공간을 메모리처럼 사용하는 개념 -> 가상 메모리라고 할 수 있음)

* 리눅스에서 Swap : 실제 메모리에 올라와 있는 메모리 블록들 중 당장 쓰이지 않는 것을 디스크에 저장하고, 이를 통해 가용 메모리 영역 늘림

vi /etc/sysctl.conf

 

7) rc.local 파일에서 아래 명령어 추가

* rc.local 파일 : 부팅시 자동실행 명령어 스크립트를 수행하며, 일반적으로 서버 부팅시마다 매번 자동 실행되기 ㄹ원하는 명령어를 넣음

# transparent_hugepage 설명

https://hoing.io/archives/809

vi /etc/rc.local

# 서비스 생성 및 등록 -> transparnet huge page 비활성화
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag

 

8) limits.conf 파일에서 아래의 파일 디스크립터 설정 추가

* limits.conf 파일 : 서버 리소스 관리 - 서버 다운 예방

  <domain> <type> <item> <value> 로 추가 입력

 

* <domain> : 제한할 대상 작성 (*, user명, 그룹명(@)) 

 

* <type>

  - soft : 새로운 프로그램을 생성하면 기본으로 적용되는 한도 (이 용량 넘으면 경고 메시지)

  - hard : 최대로 늘릴 수 있는 한도 (어떠한 일이 있어도 이 용량을 넘을 수 없음)

  - 통상적으로 soft와 hard 1:1로 맞추어 설정

 

* <item>

  - nproc (number of processes) : 최대 프로세스 개수 (KB)

  - nofile (number of open files) : 한 번에 열 수 있는 최대 파일 수 

  - 리눅스에서는 모든 개체를 파일로 보기에 nproc을 높이면 nofile도 같이 올려줄 것

 

* <value> : 제한하고자 하는 설정값

 

vi /etc/security/limits.conf

root soft nofile 65536
root hard nofile 65536
*    soft nofile 65536
*    hard nofile 65536
root soft nproc 32768
root hard nproc 32768
*    soft nproc 32768
*    hard nproc 32768

# 서버 리부팅
reboot

 

- 5번 과정 명령어 모음

 

6. 가상머신 복제

1) 복제 대상인 Server01 전원 끄고, 복제 작업이 완료될 때까지 시작하지 않음

 

2) Server01 우클릭하여 "복제" 클릭

 

3) 이름은 "Server02"로, "모든 네트워크 카드의 MAC 주소 초기화" 체크

 

7. Server02 설정 수정

1) MAC 주소, 고정 IP 수정

vi /etc/sysconfig/network-scripts/ifcfg-eth0

- 노란색으로 칠해져 있는 부분 (MAC 주소, IP 주소) 수정

 

2) 리눅스가 자동으로 설정한 Server01 네트워크 룰 삭제

vi /etc/udev/rules.d/70-persistent-net.rules

- 쓰여있는 내용 전부 주석 처리 / 삭제

 

3) Server02 종료 후 다시 시작 -> 새로운 네트워크 정보 할당

 

4) Server02 호스트 정보 수정

vi /etc/hosts

 

5) Server02 호스트명 수정

vi /etc/sysconfig/network

 

6) 네트워크 설정 정보 재시작 및 운영체제 리부트

service network restart
reboot

 

7) 네트워크 설정 반영 확인

ifconfig eth0
hostname

 

8. Server03 복제 (고사양 파일럿 아키텍처)

- Server02 복제와 같은 순서로 진행

 

9. 가상머신 CPU와 메모리 리소스 설정 최적화

- 고사양 파일럿 아키텍처 (CPU: i5 이상, 메모리: 16GB)

- Server01, Server02: 5120MB, Server03: 3072MB

 

10. 고정 IP 주소로 PuTTY 접속환경 구성

- Host name과 Saved Sessions을 적고 Save로 저장해둠

 

 

1. 패키지

- 관련 있는 클래스들을 하나로 묶은 것

- 내장 패키지 & 사용자 정의 패키지

- '이름 공간' - 동일한 이름의 클래스가 각 다른 패키지에 속할 수 있어 이름 충돌을 방지할 수 있음

- 세밀한 접근 제어 구현 가능 

- 파일의 맨 처음에 package 이름;

 

2. 패키지 사용

- 완전한 이름으로 참조하기 (패키지 이름이 클래스 앞에 붙음)

graphics.Rectangle myRect = new graphics.Rectangle();

 - 패키지 안에서 원하는 클래스만 포함하기

import graphics.Rectangle;

Rectangle myRect = new Rectangle();

 

- 패키지 안의 모든 클래스 포함하기

import graphics.*;

Rectangle myRect = new Rectangle();

 

 

3. 계층 구조의 패키지 

- ex) java - awt - font 구조의 패키지들이 있을 때,

java.awt.*를 포함시키면 java.awt.font 패키지는 자동으로 포함되지 않음!

별도로 포함시키기

import java.awt.*;
import java.awt.font.*;

 

4. 클래스 파일 로드

- 자바 소스 파일이 컴파일되면 .class 확장자를 가지는 클래스 파일로 변환되고 파일 시스템에 저장됨

- 클래스 파일은 JVM에 의해 로드됨

 

5. JVM이 클래스를 찾는 순서와 방법

- 부트스트랩 클래스

    - 자바 플랫폼을 구성하는 핵심적인 클래스

    - 디렉터리 jre/lib에 있는 여러 jar 파일들

 

- 확장 클래스

    - 자바 확장 메커니즘 사용하는 클래스

    - 확장 디렉터리에 있는 jar 파일들

 

- 사용자

    - 확장 메커니즘을 활용하지 않는 개발자 및 타사에서 정의한 클래스

 

- 방법

    - 현재 디렉터리 찾음

    - 일반적으로는 환경 변수인 CLASSPATH에 설정된 디렉터리에서 찾음

 

6. 자바 API 패키지

 

7. Object 클래스

- java.lang 패키지에 들어있음

- 자바 클래스 계층 구조에서 맨 위에 위치하는 클래스

- 메소드

 

- getClass() : 객체가 어떤 클래스로 생성되었는지에 대한 정보 반환

class Circle {  }
public class CircleTest {
    public static void main(String[] args) {
        Circle obj = new Circle();
        System.out.println("obj is of type " + obj.getClass().getName());
        System.out.println("obj의 해쉬코드=" + obj.hashCode());
    }
}

// obj is of type test.Circle
// obj의 해쉬코드=1554547125

 

- toString() : 객체의 문자열 표현 반환

- equals() : == 연산자 사용해서 객체의 주소가 동일한지 검사

 

8. Wrapper 클래스

- 정수와 같은 기초 자료형을 객체로 포장하고 싶은 경우 사용

int i = 100;
Integer obj = new Integer(i);

 

- 메소드

- 문자열 "100" -> 정수 100 : Integer.parseInt()

- 정수 100 -> 문자열 "100" : Integer.toString()

 

9. 오토박싱

- intValue() 대신

- 랩퍼 객체와 기초 자료형 사이의 변환을 자동으로 해주는 기능

Integer obj;

obj = 10;                      // 정수 -> Integer 객체
System.out.println(obj + 1);   // Integer 객체 -> 정수

 

10. String 클래스

- 메소드

 

 

11. String 클래스의 문자열 기초 연산

- length() : 문자열 길이 반환

- charAt() : String 객체 안에 들어있는 문자 추출 (문자 번호는 0부터 시작)

String s = "Hello World!"
char c = s.charAt(0);         // 'H' 반환

- 2개의 문자열 붙이는 방법

    - concat()

    - + 연산자   (** 더 편함!)

 

- indexOf() : 문자열 안에서 단어 찾기

String s = "The cat is on the table";
int index = s.indexOf("table");

if(index == -1)
    System.out.println("table은 없습니다.");
else
    System.out.println("table의 위치: " + index);

// table의 위치: 18

    - 같은 단어가 여러 번 있는 경우 가장 처음에 나오는 단어의 인덱스 반환

    - 모두 찾고 싶은 경우 반복문 이용!

 

- split() : 문자열을 단어로 분리

String[] tokens = "I am a boy.".split(" ");
for (String token : tokens)
    System.out.println(token);

/**
I
am
a
boy
**/

 

- boolean contains(charSequence s) : s에 지정된 문자들을 포함하고 있으면 true 리턴

- String replace(Charsequence target, Charsequence replacement) : target이 지정하는 일련의 문자들을 replacement가 지정하는 문자들로 변경한 문자열 객체 리턴

- String subString(int beginIndex) : beginIndex 인덱스부터 시작하는 부분 문자열 반환

- String subString(int beginIndex, int endIndex) : beginIndex부터 endIndex(포함x)까지의 부분 문자열 반환

- String trim() : 문자열 앞뒤의 공백 문자들을 제거한 문자열 객체 반환

 

12. StringBuffer 클래스

- String 클래스의 경우 빈번하게 문자열을 변경할 때 비효율적

∵ 새로운 String 객체를 생성하고 기존의 내용을 복사해야 하기 때문

 

 

- 메소드

    - append()

    - insert()

    - 어떤 타입의 데이터도 받을 수 있도록 중복 정의 되어있음

StringBuffer sb = new StringBuffer("Hello");   // 16바이트 공간 할당
int length = sb.length();        // 5
int capacity = sb.capacity();    // 21

StringBuffer sb = new StringBuffer("10+20=");
sb.append(10+20);
sb.insert(0, "수식 ");
// sb = "수식 10+20=30"

 

13. Math 클래스

- 지수, 로그, 제곱근, 삼각함수와 같은 기본적인 수치 연산을 위한 메소드 제공

 

14. Random 클래스

- 난수 발생

import java.util.*;
public class RandomTest {
    public static void main(String[] args) {
        Random random = new Random();
        for (int i = 0; i < 10; i++) 
            System.out.print(random.nextInt(100) + ", ");
    }
}

// 12, 48, 9, 3, 44, 84, 60, 4, 34, 50,

 

15. Array 클래스

import java.util.*;

public class ArraysTest {
    public static void main(String[] args) {
        int[] array = {9, 4, 5, 6, 2, 1};
        Arrays.sort(array);               // 정렬
        printArray(array);
        System.out.println(Arrays.binarySearch(array, 9));     // 9 탐색
        Arrays.fill(array,8);       // 배열 8로 채움
        printArray(array);
    }
    
    private static void printArray(int[] array) {
        System.out.print("[");
        for(int i = 0; i < array.length; i++)
            System.out.print(array[i] + " ");
        System.out.println("]");
    }
}

/**
[1 2 4 5 6 9 ]
5
[8 8 8 8 8 8 ]

 

16. Calender 클래스

- 추상 클래스, 날짜와 시간에 대한 정보

- 특정 시각을 연도, 월, 일 등으로 변환하는 메소드

 

17. 예외처리

- 오류가 발생했을 때 오류를 사용자에게 알려주고, 모든 데이터를 저장하게 한 후에 사용자가 프로그램을 종료할 수 있도록 하는 것이 바람직!

- 예외: 잘못된 코드, 부정확한 데이터, 예외적인 상황에 의해 발생하는 오류

- ex) 0으로 나누는 연산, 배열의 인덱스가 한계를 넘는 경우, 디스크에서 하드웨어 오류 발생 등

 

public class DivideByZero {
    public static void main(String[] args) {
        int result = 10 / 0;
        System.out.println("나눗셈 결과: " + result);
    }
}

// 오류

 

18. try-catch 블록

try {
    // 예외가 발생할 수 있는 코드
} catch (예외 클래스 변수) {
    // 예외를 처리하는 코드
}
// 아래 구문은 생략 가능
} finally {
    // 여기 있는 코드는 try 블록이 끝나면 무조건 실행됨
}

-ex)

import java.util.Scanner;

public class DivideByZeroOk {
    public static void main(String[] args) {
        try {
            int retult = 10 / 0;   // 예외 발생
        } catch (ArithmeticException e) {
            System.out.println("0으로 나눌 수 없습니다.");
        }
        System.out.println("프로그램은 계속 진행됩니다.");
    }
}

// 0으로 나눌 수 없습니다.
// 프로그램은 계속 진행됩니다.

 

19. 예외의 종류

- Error : 너무 심각해서 할 수 있는 방법이 없음 -> 통과

- RuntimeException : 프로그래밍 버그이므로 스스로 고쳐야 함 -> 통과

- Error나 RuntimeException이 아닌 예외 : 반드시 처리해야 함!! -> 검사

 

 

// 배열 인덱스 예외 처리

public class ArrayError {
    public static void main(String[] args) {
        int [] array = { 1, 2, 3, 4, 5 };
        int i = 0;
        
        try  {
            for (i = 0; i <= array.length; i++)
                System.out.print(array[i] + " ");
        } catch ArrayIndexOutOfBoundsException e) {
            System.out.pritnln("인덱스 " + i + "는 사용할 수 없네요!");
        }
    }
}

// 1 2 3 4 5 인덱스 5는 사용할 수 없네요!
// 입력 예외 처리

public class ExceptionTest3 {
    public static void main(String[] args) {
        try { 
            int num = Integer.parseInt("ABC");
            System.out.println(num);
        } catch (NumberFormatException e) {
            System.out.println("NumberFormat 예외 발생");
        }
    }
}

 

20. try - with - resources 문장

- 문장의 끝에서 리소스들이 자동으로 닫혀지게 함

import java.io.*;

public class TryTest {
    public static void main(String[] args) {
        try (FileReader fr = new FileReader("test.txt")) {
            char[] a = new char[50];
            fr.read(a);
            for (char c : a)
                System.out.print(c);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

21. 예외 떠넘기기

- 가끔 메소드가 발생되는 예외를 그 자리에서 처리하지 않고, 자신을 호출한 상위 메소드로 전달하는 편이 더 적절할 수 있음

import java.io.*;

pulbic class ExceptionTest {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("test.txt");
        char[] a = new char[50];
        fr.read(a);
        for (char c : a)
            System.out.print(c);
    }
}

 

'Software > JAVA' 카테고리의 다른 글

[JAVA] Day9. 이벤트 처리  (2) 2023.01.08
[JAVA] Day8. 자바 GUI 기초  (2) 2023.01.08
[JAVA] Day6. 추상클래스, 인터페이스, 중첩클래스  (0) 2022.12.29
[JAVA] Day5. 상속  (0) 2022.12.29
[JAVA] Day 3-4. 클래스와 객체  (2) 2022.12.29

1. 추상 클래스 (abstract class)

- 추상 메소드를 가지고 있는 클래스

- 추상 메소드: 메소드의 선언부(헤드)만 있는 메소드 (= 구현이 되지 않은 클래스)

- ex) void print(int n);

 

- 메소드가 미완성이므로 추상 클래스로는 객체 생성 불가능

- 주로 상속 계층에서 추상적인 개념을 나타내기 위한 용도로 사용

 

- 정의: 앞에 abstract 붙임

public abstract class Animal {
    public abstract void move();
}

public class Lion extends Animal {
    public void move() {
        System.out.println("사자의 move() 메소드");
    }
}

- 추상 클래스를 상속 받으면 추상 메소드를 구현해야 함!!

 

- ex) 도형 클래스

- 각 도형은 위치, 회전 각도, 선 색상, 채우는 색 등의 속성은 모든 도형이 공유

- 기준점을 이동하는 메소드 translate()도 모든 도형에서 동일

-> Shape에서 구체적으로 정의됨

- But) draw() 메소드는 도형마다 그리는 방법이 모두 다르기 때문에 구체적으로 정의될 수 없음

- 메소드의 이름과 매개 변수는 정의될 수 있음 -> 추상 메소드 사용

- draw()의 몸체는 각 자식 클래스에서 정의됨

 

abstract class Shape {
    int x, y;
    public void translate(int x, int y) {
        this.x = x;
        this.y = y;
    }
    
    pulic abstract void draw();
}

class Rectangle extends Shape {
    int width, height;
    @Override
    public void draw() { System.out.println("Rectangle draw"); }
}

class Circle extends Shape {
    int radius;
    @Override
    public void draw() { System.out.println("Circle draw"); }
}

public class AbstractTest {
    public static void main(String[] args) {
        // Shape s1 = new Shape();  -> 추상 클래스로 객체 생성 불가능
        Shape s2 = new Circle();    // 업캐스팅
        s2.draw();
    }
}

// Circle draw

 

 

-  추상 메소드로 정의되면 자식 클래스에서 반드시 오버라이드 해야함!

 

2. 하드웨어 인터페이스

- 컴퓨터 하드웨어에서 인터페이스는 서로 다른 장치들이 연결되어 상호 데이터를 주고받는 규격을 의미

- 각자의 클래스를 다른 사람의 클래스와 연결하려면 클래스 간의 상호작용을 기술하는 규격 필요 -> 인터페이스로 정의

 

3. 인터페이스의 용도

- 상속 관계가 아닌, 클래스 간의 유사성을 인코딩하는 데 사용됨 

- ex) 사람과 자동차는 둘 다 달릴 수 있지만, 부모 클래스로 Runner로 정의하고 사람과 차를 Runner의 자식 클래스로 나타내는건 이상함

-> Runnable 인터페이스를 만들고 이 인터페이스를 양쪽 클래스가 구현하도록

 

public interface RemoteControl {
    // 추상 메소드 정의
    public void turnOn();
    public void turnOff();
}

- 인터페이스는 추상 메소드들과 디폴트 메소드들로 이루어짐

- 인터페이스 내에 필드 선언될 수 없음!

- 상수는 정의 가능

 

4. 인터페이스 구현과 사용

class Television implements RemoteControl {
    boolean On;
    public void turnOn() {
        on = true;
        System.out.println("TV ON");
    }
    
    public void turnOff() {
        on = false;
        System.out.println("TV OFF");
    }
}

- 인터페이스는 다른 클래스들에 의해 구현될 수 있음

= 인터페이스에 정의된 추상 메소드의 몸체 정의한다는 의미

 

Television t = new Television();
t.turnOn();
t.turnOff();

 

5. 인터페이스 vs 추상 클래스

- 추상 클래스 사용 권장

    - 관련된 클래스들 사이에서 코드 공유하고 싶은 경우

    - 공통적인 필드나 메소드의 수가 많은 경우

    - public 이외의 접근 지정자를 사용해야 하는 경우

    - 일반 멤버 필드를 선언하기 원하는 경우

 

- 인터페이스 사용 권장

    - 관련 없는 클래스들이 동일한 동작을 구현하기 원할 때 (ex. Comparable, Cloneable)

    - 특정한 자료형의 동작을 지정하고 싶지만, 누가 구현하든지 신경 쓸 필요가 없을 때

    - 다중 상속이 필요할 때

 

6. 인터페이스와 타입

- 인터페이스를 정의하는 것 = 새로운 자료형을 정의하는 것!

// Television 객체이지만 RemoteControl 인터페이스 구현
// -> RemoteControl 타입의 변수로 가리킬 수 있음
RemoteControl obj = new Television();

// obj를 통해서는 RemoteControl 인터페이스에 정의된 메소드만 호출 가능
obj.turnOn();
obj.turnOff();

 

- default 함수 오버라이드 가능

interface RemoteControl {
    ...
    public default void printBrand() { System.out.println("Remote Control 가능 TV"); }
}

class Television implements RemoteControl {
    ...
    @Override
    public void printBrand() { System.out.println("Power JAVA TV"); }
}

public class TestInterface {
    public static void main(String[] args) {
        RemoteControl obj = new Television();
        obj.printBrand();
    }
}

// Power JAVA TV

 

7. 인터페이스 상속

- 인터페이스도 다른 인터페이스 상속받을 수 있음!

 

8. 인터페이스를 이용한 다중 상속

- 다중 상속: 하나의 클래스가 여러 개의 부모 클래스를 갖는 것

 

- 동시에 여러 인터페이스 구현

interface Drivable {
    void drive();
}

interface Flyable {
    void fly();
}

public class FlyingCar1 implements Drivable, Flyable {
    public void drive() { System.out.println("I'm driving"); }
    public void fly() { System.out.println("I'm flying"); }
    
    public static void main(String[] args) {
        FlyingCar1 obj = new FlyingCar1();
        obj.drive();
        obj.fly();
    }
}

// I'm driving
// I'm flying

 

- 하나의 클래스 상속받고 또 하나의 인터페이스 구현

interface Flyable { void fly(); }

class Car {
    int speed;
    void setSpeed(int speed) { this.speed = speed; }
}

public class FlyingCar2 extends Car implements Flyable {
    public void fly() { System.out.println("I'm flying!"); }
    
    public static void main(String[] args) {
        FlyingCar2 obj = new FlyingCar2();
        obj.setSpeed(300);
        obj.fly();
    }
}

// I'm flying!

 

9. 인터페이스에서의 상수 정의

- 인터페이스에서 정의된 변수는 자동적으로 public static final이 되어서 상수가 됨!

 

10. 디폴트 메소드와 정적 메소드

- 디폴트 메소드: 인터페이스 개발자가 메소드의 디폴트 구현을 제공할 수 있는 기능

 

11. 자율 주행 자동차 예시

public interface OperateCar {
    void start();
    void stop();
    void setSpeed(int speed);
    void turn(int degree);
}

public class AutoCar implements OperateCar {
    public void start() { System.out.println("출발"); }
    public void sotp() { System.out.println("정지"); }
    pubilc void setSpeed(int speed) { System.out.println("속도를 "+ speed + "km/h로 변경"); }
    public void turn(int degree) { System.out.println("방향을 " + degree + "도 만큼 변경"); }
}

public class AutoCarTest {
    public static void main(String[] args) {
        OperateCar obj = new AutoCar();
        obj.start();
        obj.setSpeed(30);
        obj.turn(15);
        obj.stop();
    }
}

 

12. Comparable 인터페이스

- 객체와 객체의 순서 비교할 때 사용

public interface Comparable {       // 실제로는 제네릭을 사용해서 정의됨
    int compareTo(Object other);    // -1, 0, 1 반환
}

class Rectangle implements Comparable {
    public int width = 0;
    public int height = 0;
    
    @Override
    public String toString() {
        return "Rectangle [width=" + width + ", height=" + height + "]";
    }
    
    public Rectangle(int w, int h) {
        width = w;
        height = h;
        System.out.println(this);
    }
    
    public int getArea() {
        return width * height;
    }
    
    @Override
    public int compareTo(Object other) {
        Rectangle otherRect = (Rectangle) other;
        if (this.getArea() < otherRect.getArea())
            return -1;
        else if (this.getArea() > otherRect.getArea())
            return 1;
        else
            return 0;
    }
}

public class RectangleTest {
    public static void main(String[] args) {
        Rectangle r1 = new Rectangle(100, 30);
        Rectangle r2 = new Rectangle(200, 10);
        int result = r1.compareTo(r2);
        if (result == 1)
            System.out.println(r1 + "가 더 큼");
        else if (result == 0)
            System.out.println("같음");
        else
            System.out.println(r2 + "가 더 큼");
    }
}

 

13. 중첩 클래스

- 클래스 안에서 클래스 정의

- 정적 중첩 클래스: 앞에 static이 붙어서 내장되는 클래스

- 비정적 중첩 클래스: static이 붙지 않은 일반적인 중첩 클래스

    - 내부 클래스(inner class): 클래스의 멤버처럼 선언되는 중첩 클래스

    - 지역 클래스(local class): 메소드의 몸체 안에서 선언되는 중첩 클래스

    - 익명 클래스(anonymouse class): 수식의 중간에서 선언되고 바로 객체화되는 클래스

 

13-1. 내부 클래스

- 클래스 안에 클래스를 선언하는 경우

- 내부 클래스는 외부 클래스의 인스턴스 변수와 메소드 전부 사용 가능

 

13-2. 지역 클래스

- 메소드 안에 정의되는 클래스

- 메소드 안에서만 사용 가능

 

13-3. 중첩 클래스 사용하는 이유

- 내부 클래스는 외부 클래스의 private 멤버도 접근할 수 있음

 

13-4. 익명 클래스

- 클래스 몸체는 정의되지만 이름이 없는 클래스

- 클래스를 정의하면서 동시에 객체 생성

- 이름이 없기 때문에 한번만 사용 가능

- 부모클래스 참조변수 = new 부모클래스 () { .. }

 

public interface RemoteControl {
    void turnOn();
    void turnOff();
}

public class AnonymousClassTest {
    public static void main(String[] args) {
        // 익명 클래스 정의
        RemoteControl ac = new RemoteControl() {
            public void turnOn() {
                System.out.println("TV turnOn()");
            }
            public void turnOff() {
                System.out.println("TV turnOff()");
            }
        }
        ac.turnOn();
        ac.turnOff();
    }
}

 

'Software > JAVA' 카테고리의 다른 글

[JAVA] Day8. 자바 GUI 기초  (2) 2023.01.08
[JAVA] Day7. 자바 API 패키지, 예외처리, 모듈  (0) 2023.01.02
[JAVA] Day5. 상속  (0) 2022.12.29
[JAVA] Day 3-4. 클래스와 객체  (2) 2022.12.29
[JAVA] Day2. 조건문, 반복문, 배열  (0) 2022.12.27

1. 상속

- 부모 클래스에 정의된 멤버 변수, 메소드를 자식 클래스가 물려 받음

- class 자식 extends 부모 { }

class Car {
    int speed;
    public void setSpeed(int Speed) {
        this.speed = speed;
    }
}

public class EletricCar extends Car {
    int battery;
    public void charge(int amount) {
        battery += amount;
    }
}

public class ElectricCarTest {
    public static void main(String[] args) {
        ElectricCar obj = new ElectricCar();
        
        obj.speed = 10;
        obj.setSpeed(60);
        obj.charge(10);
    }
}

 

- 상속 -> 이미 존재하는 클래스의 필드와 메소드 재사용 -> 중복되는 코드 줄일 수 있음

 

2. 자바 상속의 특징

- 다중 상속 지원하지 않음 (여러 개의 클래스로부터 상속 X)

- 다단계 상속은 가능 (A / B extends A / C extends B)

- 상속의 횟수에는 제한 없음 (자식 클래스의 개수 상관 X)

- 상속 계층 구조의 최상위에는 java.lang.Object 클래스가 있음

    - 모든 클래스의 부모 클래스

    - toString( ) 메소드

- 다른 패키지의 클래스도 상속 가능 (패키지.클래스 import 필요)

 

class Animal {
    int age;
    void eat() {
        System.out.println("먹고 있음 ... ");
    }
}

class Dog extends Animal {
    void bark() {
        System.out.println("짖고 있음 ...");
    }
}

public class DogTest {
     public static void main(String[] args) {
         Dog d = new Dog();
         d.bark();
         d.eat();
     }
 }
 
 // 짖고 있음 ...
 // 먹고 있음 ...

 

class Shape {
    int x, y;
}

class Circle extends Shape {
    int radius;
    public Circle(int radius) {
        this.radius = radius;
        x = 0;
        y = 0;
    }
    
    double getArea() {
        return 3.18 * radius * radius;
}

public class CircleTest {
    public static void main(String[] args) {
        Circle obj = new Circle(10);
        System.out.println("원의 중심: (" + obj.x + "," + obj.y + ")");
        System.out.println("원의 면적: " + obj.getArea());
    }
}

// 원의 중심: (0,0)
// 원의 면적: 314.0

 

3. 상속과 접근 지정자

- 자식 클래스는 부모 클래스의 public 멤버, protected 멤버, 디폴트 멤버(같은 패키지에 있는 경우) 상속 받음

- private 멤버는 상속되지 않음!

 

4. 상속과 생성자 

- 자식 클래스의 객체가 생성될 때 부모 클래스의 생성자도 호출됨!

class Base {
    public Base() {
        System.out.println("Base() 생성자");
    }
}

class Derived extends Base {
     public Derived() {
         System.out.println("Derived() 생성자");
     }
 }
 
 public class Test {
     public static void main(String[] args) {
         Derived r = new Derived();
     }
 }
 
 
// Base() 생성자
// Derived() 생성자

 

- 자식 클래스 객체 안에는 부모 클래스에서 상속된 부분이 들어있음

-> 부모 클래스 부분을 초기화하기 위해 부모 클래스의 생성자도 호출됨

 

- 순서) (부모 클래스 생성자) -> (자식 클래스 생성자)

 

5. 명시적인 생성자 호출

- super();  : 부모 클래스의 생성자 호출

class Base {
    public Base() {
        System.out.println("Base() 생성자");
    }
}

class Derived extends Base {
     public Derived() {
         super();
         System.out.println("Derived() 생성자");
     }
 }
class TwoDimPoint {
    int x, y;
    
    public TwoDimPoint() {
        x = y = 0;
    }
    
    public TwoDimPoint(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

class TreeDimPoint extends TwoDimPoint {
    int z;
    public ThreeDimPoint(int x, int y, int z) {
        super(x, y);
        this.z = z;
    }
}

- 이 경우 부모 클래스의 두 생성자 중 TwoDimPoint(int x, int y)가 호출됨

- 인수의 형태에 따라 적절한 생성자 선택

 

6. 묵시적인 생성자 호출

class Base {
    public Base() {
        System.out.println("Base() 생성자");
    }
}

class Derived extends Base {
     public Derived() {
         System.out.println("Derived() 생성자");
     }
 }

- 컴파일러는 부모 클래스의 기본 생성자가 자동으로 호출되도록 함

- 묵시적인 생성자 호출을 하려면 부모 클래스에 기본 생성자(매개 변수가 없는 생성자)가 반드시 정의되어 있어야 함!

 

7. 메소드 오버라이딩

- 자식 클래스가 부모 클래스의 메소드를 자신의 필요에 맞춰 재정의하는 것

- 메소드 이름이나 매개 변수, 반환형은 같아야 함!

 

class Shape {
    public void draw() { System.out.println("Shape"); }
}

class Circle extends Shape {
    @override
    public void draw() { System.out.println("Circle을 그립니다."); }
}

class Rectangle extends Shape {
    @override
    public void draw() { System.out.println("Rectangle을 그립니다."); }
}

class Triangle extends Shape {
    @override
    public void draw() { System.out.println("Triangle을 그립니다."); }
}

public class ShapeTest {
    public static void main(String[] args) {
        Rectangle s = new Rectangle();
        s.draw();
    }
}

// Rectangle을 그립니다.

- Rectangle 클래스의 객체에 대해 메소드가 호출되면 Rectangle 클래스 안에서 오버라이딩된 draw()가 호출됨

- 철자를 잘못 쓰는 경우 컴파일러는 새로운 메소드로 인식하기 때문에 오버라이드가 일어나지 않음

-> @Override 어노테이션을 앞에 붙이면 이러한 경우 오류 발생시키므로 붙이는 것이 좋음!

 

8. 오버라이딩 & 오버로딩

- 오버로딩 (overloading) : 같은 이름을 가진 여러 개의 메소드 작성

- 오버라이딩 (overriding) : 부모 클래스의 메소드를 자식 클래스가 다시 정의하는 것

 

9. 정적 메소드 오버라이드

- 어떤 참조 변수를 통해 호출되는지에 따라 달라짐

class Animal {
    public static void A() {
        System.out.println("static method in Animal");
    }
}

public class Dog extends Animal {
    public static void A() {
        System.out.println("static method in Dog");
    }
    
    public static void main(String[] args) {
        Dog dog = new Dog();
        Animal a = dog;
        a.A();
        dog.A();
    }
}

// static method in Animal
// static method in Dog

 

10. 키워드 super 

- super는 상속 관계에서 부모 클래스의 메소드나 필드를 명시적으로 참조하기 위해 사용됨

- 부모 클래스의 메소드를 오버라이딩한 경우에 super를 사용하면 부모 클래스의 메소드 호출 가능

class Shape {
    public void draw() {
        System.out.println("Shape 중에 하나를 그릴 예정입니다.");
    }
}

class Circle extends Shape {
    @Override
    public void draw() {
        super.draw();              // 부모 클래스의 draw 호출 
        system.out.println("Circle을 그립니다.");
    }
}

public class ShapeTest {
    public static void main(String[] args) {
        Circle s = new Circle();
        s.draw;
    }
}

// Shape 중에 하나를 그릴 예정입니다.
// Circle을 그립니다.

 

11. 다형성

- 오버로딩은 컴파일 시간에서의 다형성 지원

- 메소드 오버라이딩은 실행 시간에서의 다형성 지원

 

- 다형성: 객체들의 타입이 다르면 똑같은 메시지가 전달되더라도 서로 다른 동작을 하는 것

- 동일한 코드로 다양한 타입의 객체를 처리할 수 있는 기법

 

12. 업캐스팅

- 부모 클래스 변수로 자식 클래스 객체 참조 가능! 

- 자식 클래스의 필드와 메소드에는 접근할 수 없음

- 자식 클래스의 부모 클래스 부분만 접근 가능!

- ex) Rectangle 클래스의 x, y (O) // width, height (X)

 

- 부모 클래스로 캐스팅 된다는 것은 멤버의 갯수 감소 의미! (부모 클래스의 멤버만 접근 가능)

- 업캐스팅을 하고 메소드를 실행할때 자식 클래스에서 오버라이딩한 메소드가 있을 경우, 오버라이딩 된 메소드가 실행됨!

 

// ex) Rectangle, Triangle, Circle 등의 도형 클래스가 부모 클래스인 Shape 클래스로부터 상속된 경우

class Shape {
    protected int x, y;      // 모든 도형의 공통 속성인 위치 기준점 (x, y)
    public void draw() { System.out.println("Shape draw"); }
}

class Rectangle extends Shape {
    private int width, height;
    public void draw() { System.out.println("Rectangle draw"); }
}

class Triangle extends Shape {
    private int base, height;
    public void draw() { System.out.println("Triangle draw"); }
}

class Circle extends Shape {
    private int radius;
    public void draw() { System.out.println("Circle draw"); }
}

public class ShapeTest {
    public static void main(String[] args) {
        Shape s1, s2;
        
        s1 = new Shape();
        s2 = new Rectangle();
    }
}
publc class ShapeTest {
    public static void main(String[] args) {
        Shape s = new Rectangle();
        // 업캐스팅
        // s는 Shape 타입, Rectangle 객체 가리킴
        
        Rectangle r = new Rectangle();
        
        s.x = 0;
        x.y = 0;
        //s.width = 100;    -> 오류!
        //s.height = 100;   -> s로 Rectangle의 필드와 메소드에 접근할 수 없음
    }
}

 

- 다운캐스팅: 부모 객체를 자식 참조 변수로 참조하는 것, 명시적으로 해야 함

class Parent {
    void print() { System.out.println("Parent 메소드 호출"); }
}

class Chile extends Parent {
    @Override void print() { System.out.println("Child 메소드 호출"); }
}

public class Casting {
    public static void main(String[] args) {
        Parent p = new Child();   // 업캐스팅: 자식 객체를 부모 객체로 형변환
        p.print();                // 동적 메소드 호출, 자식의 print() 호출
        
        // Child c = new Parent();  -> 컴파일 오류!
        
        Child c = (Child)p;       // 다운캐스팅: 부모 객체를 자식 객체로 형변환
        c.print();                // 메소드 오버라이딩, 자식의 print() 호출
    }
}

// Child 메소드 호출
// Child 메소드 호출

 

13. 업캐스팅 하는 이유

- 공통적으로 할 수 있는 부분을 만들어 간단하게 다루기 위해

- 상속 관계에서 상속 받은 자식 클래스가 몇 개이든 하나의 인스턴스로 묶어서 관리할 수 있기 때문

// 기존
Rectangle[] r = new Rectangle[];
r[0] = new Rectangle();
r[1] = new Rectangle();
 
Triangle[] t = new Triangle[];
t[0] = new Triangle();
t[1] = new Triangle();
 
Circle[] c = new Circle[];
c[0] = new Circle();
c[1] = new Circle();
// 업캐스팅
Shape[] s = new Shape[];
s[0] = new Rectangle();
s[1] = new Rectangle();
s[2] = new Triangle();
s[3] = new Triangle();
s[4] = new Circle();
s[5] = new Circle();

- 하나의 타입으로 묶어 배열을 구성

- 코드량도 훨씬 줄어들고 가독성도 좋아지며 유지보수성도 좋아짐

- 자식 고유의 메소드 실행하려면 다운캐스팅

 

14. 동적 바인딩

- 업캐스팅: 여러 가지 타입의 객체를 하나의 자료구조 안에 모아서 처리하려는 경우에 필요

 

- 도형 클래스 예제) 각 도형을 그리는 방법은 모두 다르기 때문에 종류에 따라 다른 draw() 호출해야 함

- Shape 클래스가 draw() 갖고 있고, 자식 클래스들이 이 draw() 오버라이딩 한 경우

public class ShapeTest {
    public static void main(String[] args) {
        Shape[] arrayOfShapes;         // Shape의 배열 arrayOfShapes[] 선언
        arrayOfShapes = new Shape[3];
        
        // 배열 arrayOfShapes의 각 원소에 객체를 만들어 대입
        // 다형성에 의해 Shape 객체 배열에 모든 타입의 객체 저장 가능
        arrayOfShapes[0] = new Rectangle();
        arrayOfShapes[1] = new Triangle();
        arrayOfShapes[2] = new Circle();
        
        for (int i = 0; i < arrayOfShapes.length; i++) {
            arrayOfShapes[i].draw();
        }
    }
}

// Rectangle draw
// Triangle draw
// Circle draw

 

15. 업캐스팅의 활용

- 메소드의 매개 변수를 부모 타입으로 선언하면 훨씬 넓은 범위의 객체 받을 수 있음

- 부모 클래스에서 파생된 모든 클래스의 객체를 다 받을 수 있음

public class ShapeTest {
    public static void print(Shape s) {
        System.out.println("x= " + s.x + " y= " + s.y);
    }
    
    public static void main(String[] args) {
        Rectangle s1 = new Rectangle();
        Triangle s2 = new Triangle();
        Circle s3 = new Circle();
        
        print(s1);
        print(s2);
        print(s3);
    }
}

 

16. instanceof 연산자

- 변수가 가리키는 객체의 실제 타입 반환

 

17. 종단 클래스와 종단 메소드

- 종단 클래스(final class) : 상속시킬 수 없는 클래스

- 보안상의 이유로 주로 사용

- 서브 클래스에서 재정의 불가

final class String {
    ...
}

class Baduk {
    enum Player { WHITE, BLACK }
    ...
    final Player getFirstPlayer() {
        return Player.BLACK;
    }
}

1. 객체지향 프로그래밍

- 데이터와 함수를 하나의 덩어리로 묶어서 생각하는 방법: 캡슐화

public class Circle {
	double radius;           // data
	String color;            // data
	double getArea() {return 3.14*radius*radius; }   // func
}

 

2. 정보 은닉

- 객체의 외부에서는 내부 데이터와 알고리즘을 볼 수 없게 함

- 공개된 인터페이스를 통해서만 객체에 접근하도록

 

3. 상속

- 이미 작성된 클래스(부모 클래스)를 이어받아서 새로운 클래스(자식 클래스) 생성 가능

- 자식 클래스는 부모의 속성과 동작 물려받음

 

4. 클래스

- 객체에 대한 설계도 (틀)

- 클래스로부터 만들어지는 각각의 객체 -> '인스턴스'

- 하나의 클래스로 여러 인스턴스를 만들어내지만, 인스턴스마다 속성의 값은 다름

public class Circle {
    // 필드
    public int radius;
    public String color;
    
    // 메소드
    public double getArea() {
        return 3.14*radius*radius;
    }
}

 

5. 객체 생성

- 참조 변수 선언

//Type   변수명  
 Circle   obj;

- 객체 생성

//변수       객체의 참조값
  obj = new Circle();

 

public class CircleTest {
    public static void main(String[] args) {
        // 참조 변수 선언
        Circle obj;
        
        // 객체 생성 & 객체의 참조값 -> 참조 변수에 저장
        obj = new Circle();
        
        // 객체의 필드 사용
        obj.radius = 100;
        obj.color = "blue";
        
        // 객체의 메소드 사용
        double area = obj.getArea();
        System.out.println("원의 면적= " + area);
    }
}

 

6. 참조 변수

- 객체 를 참조할 때 사용되는 변수 - 객체의 참조값이 저장되어 있음

- 참조값은 일반적으로 객체의 주소

- 자바에서 모든 객체는 new 연산자를 이용해야 생성됨

public class DeskLamp {
    // 인스턴스 변수 정의
    private boolean isOn;
    
    // 메소드 정의
    public void turnOn()  { isOn = true; }
    public void turnOff() { isOn = false; }
    public String toString() {
        return "현재 상태는" + (isOn == true ? "켜짐" : "꺼짐");
    }
}

public class DeskLampTest {
    public static void main(String[] args) {
        // 객체 생성
        DeskLamp myLamp = new DeskLamp();
        
        // 객체의 메소드 호출
        myLamp.turnOn();
        System.out.println(myLamp);
        myLamp.turnOff();
        System.out.println(myLamp);
    }
}

 

7. 메소드 오버로딩

- 이름이 동일한 여러 개의 메소드 작성 가능

- 매개변수의 수, 타입, 순서 등이 달라야 함

public class MyMath {
    int add(int x, int y)          { return x+y; }
    int add(int x, int y, int z)   { return x+y+z; }
    int add(int x, int y, int z, int w)   { return x+y+z+w; }
    
    public static void main(String[] args) {
        MyMath obj;
        obj = new MyMath();
        System.out.println(obj.add(10, 20));
        System.out.println(obj.add(10, 20, 30));
        System.out.println(obj.add(10, 20, 30, 40));
    }
}

 

8. 생성자

- 객체가 생성될 때 객체를 초기화하는 특수한 메소드

- 중복 정의 가능

class Pizza {
    int size;
    String type;
    public Pizza 90 {
        size = 12;
        type = "슈퍼슈프림";
    }
    
    public Pizza(int s, String t) {
        size = s;
        type = t;
    }
}

public class PizzaTest {
    public static void main(String[] args) {
        Pizza obj1 = new Pizza();
        System.out.println("(" + obj1.type + ", " + obj1.size + ",)");
        
        Pizza obj2 = new Pizza(24, "포테이토");
        System.out.println("(" + obj2.type + ", " + obj2.size + ",)");

 

9. 기본 생성자

- 매개변수 없는 생성자

- 생성자 하나도 정의하지 않으면 컴파일러가 자동으로 기본 생성자 만듦

 

10. this 참조 변수

- 현재 객체 자신을 가리키는 참조 변수

- 컴파일러에서 자동으로 생성

- 생성자에서 매개 변수 이름과 필드 이름이 동일한 경우에 사용

public Circle (int radius) {
    this.radius = radius;
}

 

11. this()

- 다른 생성자 의미

 

12. 접근 제어

- private: 클래스 안에서만 접근 가능

- public: 누구나 접근 가능

- protected: 자식 클래스만 접근 가능

- 접근지정자 x (default) : 동일 패키지 안에서만 접근 가능

 

13. 접근자와 설정자

- 접근자 (getters) 메소드: 필드값 반환

- 설정자 (setters) 메소드: 필드값 설정

 

- 접근자와 설정자 메소드만을 통해 필드에 접근해야 함!

- 설정자에서 매개변수를 통해 잘못된 값이 넘어오는 경우, 이를 사전에 차단할 수 있음

- 필요할 때마다 필드값을 동적으로 계산하여 반환할 수 있음

- 접근자만 제공 -> 읽기만 가능한 필드 만들 수 있음

- Source 메뉴에서 자동 입력 가능

 

class Account {
    private int regNumber;
    private String name;
    private int balance;
    
    // 접근자
    public String getName() {
    	return name;
    }
    
    // 설정자
    public String setName(String name) {
    	this.name = name;
    }
    
    public int getBalance() {
    	return balance;
    }
    
    public int setBalance(int balance) {
    	this.balance = balance;
    }
}

 

14. 객체의 소멸과 가비지 컬렉션

- 객체 삭제 연산자 없음

- 자동 메모리 시스템 사용: 가비지 컬렉션

 

- 가비지 컬렉터: 힙 메모리에서 더이상 필요없는 객체를 찾아 지움

- 가비지 컬렉션 요청 -> 모든 다른 애플리케이션 멈춤 -> JVM이 실행 여부 판단

System.gc;

 

15. 인수전달 방법

- 기본적으로 Call by value

- 객체를 메소드로 전달 -> 객체의 참조값만 복사되어 전달됨

- 참조 변수는 참조값(주소) 갖고 있음

- 배열도 객체 -> 배열 전달은 배열 참조 변수를 복사하는 것

 

public class ArrayArgumentTest {
	public static double minArray(double[] list) {
    	double min = list[0];
        for (int i = 1; i < list.length; i++) {
        	if(list[i] < min) 
            	min = list[i];
        }
        return (min);
    }
    
    public static void main(String[] args) {
    	double[] a = { 1.1, 2.2, 3.3, 4.4, 0.1, 0.2 };
        double[] b = { -2.0, 3.0, -9.0, 2.9, 1.5 };
        double min;
        
        min = minArray(a);
        System.out.println("첫번째 배열의 최솟값= " + min);
        min = minArray(b);
        System.out.println("두번째 배열의 최솟값= " + min);
    }
}

// 0.1
// -9.0

 

16. 정적 멤버

- 여러 개의 객체가 하나의 변수를 공유해야 하는 경우 

-> 이러한 멤버를 정적 멤버 (static member) / 클래스 멤버 (class member) 라고 함 

- 정적 변수: 클래스 당 하나만 생성되는 변수

- 여러 개가 존재할 수 있음, 한개의 static 변수는 한 번 선언됨

 

- 클래스를 통한 접근

Television.count = 100;

 

- 객체를 통한 접근

Television obj = new Televison();
obj.count = 100;

 

- 정적 메소드: 객체를 생성하지 않고 클래스 이름으로 접근해서 사용 가능

public class Math {
	public static double sqrt(double a) {
    	...
    }
}
...
double value = Math.sqrt(9.0);  // 클래스.함수명 으로 사용

 

17. 정적 변수의 활용

- 정적 메소드는 정적 멤버만 사용할 수 있음

class Test {
    int a;              // 인스턴스 변수
    static int b;       // 정적 변수
    
    void sub1() { a = 0; }         // OK
    static void sub2() { a = 0; }  // 오류! 정적 메소드에서는 인스턴스 멤버 사용할 수 없음

- 정적 메소드에서 정적 메소드를 호출하거나 정적 멤버를 사용하는건 가능

- 정적 메소드는 this를 사용할 수 없음

class Test {
    static int a;
    static void sub(int x) { this.a = x; }    // 오류!

 

- main()도 정적 메소드이기 때문에 인스턴스 메소드를 호출할 수 없음

- 정적 메소드는 main()에서 호출 가능!

public class Test {
    public static int cube(int x) {
        int result = x*x*x;
        return result;
    }
    
    public static void main(String args[]) {
        System.out.println("10*10*10은 " + cube(10));   // 정적 메소드 호출
    }
}

 

18. final 키워드

- 필드에 final을 붙이면 상수가 됨

- static과 동시에 사용하는 경우 많음

public class Car {
    static final int MAX_SPEED = 100;
}

- 상수는 클래스 변수로 만들어서 공유하는 것이 메모리 공간 절약

 

19. 싱글톤 패턴

- 객체 중 전체 시스템을 통틀어서 딱 하나만 존재해야 하는 것들이 있음

- ex) 환경설정 클래스, 네트워크 연결 풀 / 스레드 풀을 관리하는 클래스들

- 싱글톤 패턴은 하나의 프로그램 내에서 하나의 인스턴스만을 생성해야 하는 경우에 사용

 

class Single {
    private static Single instance = new Single();   
    private Single() { }      // 전용 생성자
    
    public static Single getInstance() {
        return instance;
    }
}

public class SingleTest {
    public static void main(String[] args) {
        Single obj1 = Single.getInstance();
        Single obj2 = Single.getInstance();
        System.out.println(obj1);
        System.out.println(obj2);
    }
}

 

20. 객체배열

- 객체를 저장하는 배열

- 객체에 대한 참조값 저장

 

class Rect {
    int width, height;
    
    public Rect(int w, int h) {
        this.width = w;
        this.height = h;
    }
    
    double getArea() {
        return (double) width * height;
    }
}

public class RectArrayTest {
    public static void main(String[] args) {
        Rect[] list = new Rect[5];             // 객체 배열 생성
        
        for (int i = 0; i < list.length; i++)
            list[i] = new Rect(i,i);           // 배열에 객체 값 저장 
            
        for (int i = 0; i < list.length; i++)
            System.out.println(i + "번째 사각형의 면적= " + list[i].getArea());
    }
}

/** 
0번째 사각형의 면적= 0.0
1번째 사각형의 면적= 1.0
2번째 사각형의 면적= 4.0
3번째 사각형의 면적= 9.0
4번째 사각형의 면적= 16.0
**/

 

for(int i = 0; i < list.length; i++)
     list[i] = new Rect(i, i);

 

21. 동적 객체 배열

- ArrayList<>

import java.util.ArrayList;

public class ArrayListTest {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();
        list.add("홍콩");
        list.add("싱가포르");
        list.add("괌");
        list.add("사이판");
        list.add("하와이");
        
        System.out.println("여행지 추천 시스템");
        int index = (int)(Math.random()*list.size());
        System.out.println("추천 여행지는 " + list.get(index));
    }
}

- list.add(); 로 추가

 

import java.util.ArrayList;

class Person {
    String name;
    String tel;
    
    public Person(String name, String tel) {
        this.name = name;
        this.tel = tel;
    }
}

public class ArrayListTest2 {
    public static void main(String[] args) {
        ArrayList<Person> list = new ArrayList<Person>();
        list.add(new Person("Anna", "01023459293"));
        list.add(new Person("Jane", "01082983491"));
        list.add(new Person("Jim", "01012349722"));
        list.add(new Person("Emily", "01092938475"));
        for (Person obj : list)
            System.out.println("(" + obj.name + "," + obj.tel + ")");
    }
}

'Software > JAVA' 카테고리의 다른 글

[JAVA] Day6. 추상클래스, 인터페이스, 중첩클래스  (0) 2022.12.29
[JAVA] Day5. 상속  (0) 2022.12.29
[JAVA] Day2. 조건문, 반복문, 배열  (0) 2022.12.27
[JAVA] Day1. 자바 기초  (0) 2022.12.27
[JAVA] 예외처리  (0) 2021.07.22

+ Recent posts