Car myCar = new Sonata //선언과 생성 이름 다를 수 있음 → 다형성
다형성
하나의 객체가 여러 가지 타입을 가질 수 있는 것
부모-자식 상속관계에 있는 클래스에서, 상위 클래스가 동일한 메시지로 하위 클래스들을 서로 다르게 동작시키는 객체 지향 원리
하나의 타입으로 다양한 실행 결과를 얻을 수 있어 객체를 부품화하여 유지 보수하기 용이함
생성자
디폴트 생성자는 생략이 가능하다
파라미터를 갖는 생성자는 생략이 불가하다
생성자가 하나라도 생성되어 있으면 디폴트 생성자를 만들어주지 않는다
생성자의 제1역할은 전역 변수의 초기화이다
package dev_java.week3;
class A {
int i = 1;
Amain aMain = null;
public A(Amain aMain) {
System.out.println("A(AMain aMain) 호출");
this.aMain = aMain; // 주석으로 막으면 초기화x, NullPointerException
}
void methodB() {
aMain.methodA();
}
}
public class Amain {
A a = new A(this);
void methodA() {
System.out.println("AMain methodA() 호출");
}
public static void main(String[] args) {
Amain aMain = new Amain();
aMain.a.methodB();
}
}
깊은 복사
실제 값을 새로운 메모리 공간에 복사하는 것
복사한 객체를 변경해도 기존의 객체는 변경되지 않음
얕은 복사
주소 값을 복사하는 것
주소 값을 복사하기에 참조하고 있는 실제 값은 같음
복사한 객체가 변경되면 기존의 객체도 변경됨
package dev_java.week3.tables;
import java.util.Arrays;
/*
* 배열 복사의 두 가지
* 얕은 복사
* 주소값 복사, 참조하는 실제값은 같음
* 복사된 배열이나 원본 배열이 변경될 때 서로간의 값이 같이 바뀌는 것
*
* 깊은 복사
* 실제값을 새로운 메모리 공간에 복사
* 복사본을 바꿔도 원본은 그대로
*/
public class ArrayCopy1 {
void shallowCopy() {
int[] org = { 1, 2, 3 };
int[] org_copy = org; // 얕은 복사
org_copy[2] = 5; // 카피를 바꿨을 때 원본도 바뀜
for (int e : org) {
System.out.print(e + " ");
}
System.out.println();
for (int e : org_copy) {
System.out.print(e + " ");
}
System.out.println("\n==========");
}
void deepCopy() {
int[] org = { 1, 2, 3 };
int[] org_copy = org.clone(); // 깊은 복사
org_copy[2] = 5; // 카피를 바꿔도 원본을 그대로
for (int e : org) {
System.out.print(e + " ");
}
System.out.println();
for (int e : org_copy) {
System.out.print(e + " ");
}
System.out.println("\n==========");
}
void deepCopy2() {
int[] org = { 1, 2, 3, 4, 5 };
int[] org_copy = Arrays.copyOf(org, 2); // 2개만 복사됨, 원본은 그대로
org_copy[1] = 5; // 인덱스1은 5로 변경
for (int e : org) {
System.out.print(e + " ");
}
System.out.println();
for (int e : org_copy) {
System.out.print(e + " ");
}
System.out.println("\n==========");
}
public static void main(String[] args) {
ArrayCopy1 ac1 = new ArrayCopy1();
ac1.shallowCopy();
ac1.deepCopy();
ac1.deepCopy2();
}
}
// 1 2 5
// 1 2 5
// ==========
// 1 2 3
// 1 2 5
// ==========
// 1 2 3 4 5
// 1 5
// ==========
package dev_java.week3.tables;
public class StringCopy {
public static void main(String[] args) {
String str = "Hello";
String str1 = "Hello";
System.out.println(str == str1); // true, 주소번지가 같다
System.out.println(str.equals(str1)); // true, 주소번지가 가리키는 값(Hello)이 같다
String str2 = new String("Hello");
String str3 = new String("Hello");
System.out.println(str2 == str3); // false, new를 사용했기에 주소번지가 다르가
System.out.println(str2.equals(str3)); // true, 그 안의 값(Hello)은 같다
}
}
package dev_java.week3.tables;
public class DeptVO {
private int deptno;
private String dname;
private String loc;
public int getDeptno() {
return this.deptno;
}
public void setDeptno(int deptno) {
this.deptno = deptno;
}
public String getDname() {
return this.dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return this.loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
}
package dev_java.week3.tables;
import javax.swing.JFrame;
import javax.swing.table.DefaultTableModel;
public class DeptTable2 extends JFrame { // DeptTable1 is a JFrame
// 선언부
String header[] = { "부서번호", "부서명", "지역" };
String datas[][] = new String[1][3];
DefaultTableModel dmt_dept = new DefaultTableModel(datas, header);
// 생성자
public DeptTable2() {
initDisplay();
}
public DeptTable2(String title) {
}
public DeptTable2(int i) {
}
// 화면그리기
public void initDisplay() {
this.setTitle("부서관리 시스템 Ver1.0");
this.setSize(500, 400);
this.setVisible(true);
}
// 메인메소드
public static void main(String[] args) {
new DeptTable2(null); // String의 디폴트값 null, 2번째 생성자 호출
new DeptTable2(5); // 3번째 생성자 호출
}
}
package dev_java.week3.tables;
import java.awt.Color;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
// 이른 인스턴스화, 게으른 인스턴스화 -> 나눠보기 추가 연습
// 어떤 클래스를 상속받을 때에는 extends 예약어를 사용한다.
// A is a B 관계이면 상속으로 처리한다.
// 소나타는 자동차이다 -> 상속관계
// 작은 범위는 큰 범위다
// 부모클래스가 가진 변수와 메소드도 사용 가능하다. -> 자손이 더 많이 누릴 수 있다.
public class DeptTable1 extends JFrame { // DeptTable1 is a JFrame
// 선언부
String header[] = { "부서번호", "부서명", "지역" };
String datas[][] = new String[1][3];
// this는 사용되는 클래스 영역에서 선언된 클래스를 카리킨다
// 그러면 여기서는 DeptTable1 타입인 것
// 그런데 DefaultTableModel은 자바에서 제공되는 클래스이다(생성자도 정해져 있음)
// 생성자는 메소드 오버로딩 규칙을 따른다(파라미터의 개수나 타입이 달라야함)
// this를 파라미터에 넣는다면, 제공되는 생성자에 없음 -> 결국 사용 못함 -> 컴파일 에러(문법에러 발생)
DefaultTableModel dmt_dept = new DefaultTableModel(datas, header); // DefaultTableModel 생성자 호출
JTable jtb_dept = new JTable(dmt_dept);
JScrollPane jsp_dept = new JScrollPane(jtb_dept,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
JPanel jp_north = new JPanel();
JButton jtbn_sel = new JButton("선택");
JButton jtbn_ins = new JButton("입력");
JButton jtbn_upd = new JButton("수정");
JButton jtbn_del = new JButton("삭제");
// 생성자
public DeptTable1() {
initDisplay();
}
// 화면그리기
public void initDisplay() {
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
jp_north.setLayout(new FlowLayout(FlowLayout.RIGHT));
// 버튼 색 설정
jtbn_sel.setBackground(new Color(158, 9, 9));
jtbn_sel.setForeground(Color.WHITE);
jtbn_ins.setBackground(new Color(19, 99, 57));
jtbn_ins.setForeground(Color.WHITE);
jtbn_upd.setBackground(new Color(54, 54, 54));
jtbn_upd.setForeground(Color.WHITE);
jtbn_del.setBackground(new Color(7, 84, 170));
jtbn_del.setForeground(Color.WHITE);
// 버튼 추가
jp_north.add(jtbn_sel);
jp_north.add(jtbn_ins);
jp_north.add(jtbn_upd);
jp_north.add(jtbn_del);
// this(상속받은 JFrame)에 추가
this.add("North", jp_north);
this.add("Center", jsp_dept);
this.setTitle("부서관리 시스템 Ver1.0");
this.setSize(500, 400);
this.setVisible(true);
}
// 메인메소드
public static void main(String[] args) {
new DeptTable1();
}
}
Vector
java.util패키지에 소속된 Collection 프레임워크의 일부
ArrayList와 마찬가지로 Vector 내부에 값이 추가되면 자동으로 크기가 조절됨
ArrayList와 다른 점은 Vector는 동기화된 메소드로 구성되어있기에 하나의 스레드를 실행 완료해야만 다른 스레드를 실행할 수 있다는 것(자동동기화)
그렇기에 멀티 스레드 환경에서 안전하게 객체 추가, 삭제가 가능
Vector v = new Vector(); // 타입 미설정 Object로 선언됨
Vector<Student> student = new Vector<Student>(); // Student객체만 사용가능
Vector<Integer> num2 = new Vector<Integer>(); // int타만 사용가능
Vector<Integer> num3 = new Vector<>(); // new에서 타입 파라미터 생략가능
Vector<String> v2 = new Vector<String>(10); // 초기 용량 지정
Vector<Integer> v3 = new Vector<Integer>(Arrays.asList(1,2,3)); // 초기값 지정
package dev_java.week3.tables;
import java.util.Vector;
public class Vector1 {
public static void main(String[] args) {
Vector v = new Vector(); // <>안의 타입을 명시하지 않음(불편함)
Vector<String> v2 = new Vector<>(); // 벡터는 오브젝트 단위로 담을 수 있다
v2.add("안녕");
v2.add("2");
Vector<Integer> v3 = new Vector<>(); // 원시형은 안되지만 래퍼클래스는 가능
Vector<DeptVO> v4 = new Vector<>(); // 3차배열은 안쓴다(직관적x)
// v.add(1); // 오토박싱, v.add(new Integer(1))와 같음(int를 Integer로)
v.add("안녕"); // v.get(0)
v.add(1); // v.get(1)
System.out.println(v.size()); // 2
System.out.println(v.get(0)); // 안녕
System.out.println(v.get(1)); // 1
String insa = (String) v.get(0); // 타입이 안맞음!, 강제형전환 필요
System.out.println(insa); // 안녕
String insa2 = v2.get(0);
System.out.println(insa2); // 안녕
if (v.get(1) instanceof Integer) {
System.out.println("정수형입니다.");
}
if (v.get(0) instanceof String) {
System.out.println("문자열입니다.");
}
}
}
package dev_java.week3.tables;
import java.util.Vector;
public class Vector2 {
public static void main(String[] args) {
Vector<String> v = new Vector<>();
v.add("사과"); // 인덱스0
v.add("토마토"); // 인덱스1
v.add(1, "바나나"); // 인덱스1에 바나나넣기(배열과 다르게 끼워넣기 가능)
for (int i = 0; i < v.size(); i++) {
System.out.println(v.get(i)); // 사과, 바나나, 토마토
}
}
}
package dev_java.week3.tables;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.dnd.DropTarget;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
// 이른 인스턴스화, 게으른 인스턴스화 -> 나눠보기 추가 연습
// 어떤 클래스를 상속받을 때에는 extends 예약어를 사용한다.
// A is a B 관계이면 상속으로 처리한다.
// 소나타는 자동차이다 -> 상속관계
// 작은 범위는 큰 범위다
// 부모클래스가 가진 변수와 메소드도 사용 가능하다. -> 자손이 더 많이 누릴 수 있다.
// ActionListener-인터페이스(단독으로 인스턴스화가 불가, 구현체 클래스가 필요함)
// 추상 메소드를 선언하고있다.
// ActionListener al = new DeptTable3(); -> 선언부와 생성부가 다를 수 있다(이럴때만 다형성이 가능함)
// 선언부와 생성부가 다르다 -> 동일한 메소드를 호출했는데 다른 기능이 처리되었다(다형성)
// 추상클래스도 구현체클래스가 필요하다 - this
// Duck myDuck = new WoodDuck(); -> myDuck.fly(); -> 비행x
// Duck herDuck = new RubberDuck(); -> herDuck.fly(); -> 비행x
// Duck himDuck = new MallardDuck(); -> himDuck.fly(); -> 비행가능!
public class DeptTable3 extends JFrame implements ActionListener { // DeptTable1 is a JFrame
// 선언부
String header[] = { "부서번호", "부서명", "지역" };
String datas[][] = new String[0][3]; // 디폴트값 null
// this는 사용되는 클래스 영역에서 선언된 클래스를 카리킨다
// 그러면 여기서는 DeptTable1 타입인 것
// 그런데 DefaultTableModel은 자바에서 제공되는 클래스이다(생성자도 정해져 있음)
// 생성자는 메소드 오버로딩 규칙을 따른다(파라미터의 개수나 타입이 달라야함)
// this를 파라미터에 넣는다면, 제공되는 생성자에 없음 -> 결국 사용 못함 -> 컴파일 에러(문법에러 발생)
DefaultTableModel dtm_dept = new DefaultTableModel(datas, header); // DefaultTableModel 생성자 호출
JTable jtb_dept = new JTable(dtm_dept);
JScrollPane jsp_dept = new JScrollPane(jtb_dept,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
JPanel jp_north = new JPanel();
JButton jtbn_sel = new JButton("조회");
JButton jtbn_ins = new JButton("입력");
JButton jtbn_upd = new JButton("수정");
JButton jtbn_del = new JButton("삭제");
// 부서목록 조회에 들어갈 샘플 데이터 생성
String[][] depts = {
{ "10", "개발부", "서울" },
{ "20", "인사부", "인천" },
{ "30", "총무부", "부산" }
};
// 생성자
public DeptTable3() {
initDisplay();
}
// 화면그리기
public void initDisplay() {
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
jp_north.setLayout(new FlowLayout(FlowLayout.RIGHT));
// 버튼 색 설정
jtbn_sel.setBackground(new Color(158, 9, 9));
jtbn_sel.setForeground(Color.WHITE);
jtbn_ins.setBackground(new Color(19, 99, 57));
jtbn_ins.setForeground(Color.WHITE);
jtbn_upd.setBackground(new Color(54, 54, 54));
jtbn_upd.setForeground(Color.WHITE);
jtbn_del.setBackground(new Color(7, 84, 170));
jtbn_del.setForeground(Color.WHITE);
// 버튼 추가
jp_north.add(jtbn_sel);
jp_north.add(jtbn_ins);
jp_north.add(jtbn_upd);
jp_north.add(jtbn_del);
// 이벤트리스너 연결
jtbn_sel.addActionListener(this);
jtbn_ins.addActionListener(this);
jtbn_upd.addActionListener(this);
jtbn_del.addActionListener(this);
// this(상속받은 JFrame)에 추가
this.add("North", jp_north);
this.add("Center", jsp_dept);
this.setTitle("부서관리 시스템 Ver1.0");
this.setSize(500, 400);
this.setVisible(true);
}
// 메인메소드
public static void main(String[] args) {
new DeptTable3();
}
@Override
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if (obj == jtbn_sel) { // 조회버튼을 눌렀을 때
while (dtm_dept.getRowCount() > 0) { // 먼저 원래 있던 것들을 지우기
dtm_dept.removeRow(0);
}
for (int x = 0; x < depts.length; x++) {
Vector<String> oneRow = new Vector<>(); // 벡터로 한 열씩 담기
oneRow.add(depts[x][0]); // 부서번호
oneRow.add(depts[x][1]); // 부서명
oneRow.add(depts[x][2]); // 지역
dtm_dept.addRow(oneRow);
}
for (int i = 0; i < depts.length; i++) {
for (int j = 0; j < depts[i].length; j++) {
// System.out.print(depts[i][j] + " "); // ln을 빼서 i인덱스의 j를 연이어 출력
dtm_dept.setValueAt("여기", 1, 1); // 내용 수정 setValueAt
System.out.println(dtm_dept.getValueAt(i, j)); // 내용 출력
} // end of inner for문
System.out.println();
} // end of outter for문
// DefaultTableModel에 데이터 초기화하기
} else if (obj == jtbn_ins) {
String[] temp = { "", "", "" };
Vector<Object> oneRow = new Vector<>();
oneRow.add(temp[0]);
dtm_dept.addRow(oneRow);
} else if (obj == jtbn_upd) {
} else if (obj == jtbn_del) {
int indexR = jtb_dept.getSelectedRow(); // 선택한 row
int indexC = jtb_dept.getSelectedColumn(); // 선택한 column
// Integer deptno = Integer.parseInt((String) dtm_dept.getValueAt(index, 0));
// System.out.println(deptno);
String deptinfo = (String) dtm_dept.getValueAt(indexR, indexC);
System.out.println(deptinfo);
// 하나씩 지우기
dtm_dept.setValueAt("", indexR, indexC);
// 한 행씩 지우기
// dtm_dept.removeRow(indexR);
}
}
}
package dev_java.week3.example;
import java.util.Scanner;
// **연습문제1**
// 키보드로 부터 5개의 정수를 입력 받아서 배열에 저장하세요.
// 그리고 이들의 합계와 평균을 출력하는 프로그램을 작성하시오.
public class Exam1_221215_1 {
// 배열 선언
int users[] = new int[5]; // 0, 0, 0, 0, 0
// 배열에 숫자 입력
void initUsers() {
Scanner s = new Scanner(System.in);
for (int i = 0; i < users.length; i++) {
System.out.print("숫자 5개를 입력해주세요. ");
users[i] = s.nextInt();
System.out.println(users[i]);
}
s.close();
}
// 총합 구하기
int total() {
int hap = 0; // 지역변수는 반드시 초기화를 해줘야한다
for (int i = 0; i < users.length; i++) {
hap += users[i];
}
return hap;
}
// 평균 구하기
void average(int hap) {
double avg = 0.0;
avg = hap / (double) users.length;
System.out.println("평균: " + avg);
}
public static void main(String[] args) {
Exam1_221215_1 ex1 = new Exam1_221215_1();
ex1.initUsers();
int hap = ex1.total();
System.out.println("총점: " + hap);
ex1.average(hap);
}
}
'국비학원 > 수업기록' 카테고리의 다른 글
국비 지원 개발자 과정_Day16 (0) | 2022.12.19 |
---|---|
국비 지원 개발자 과정_Day15 (0) | 2022.12.16 |
국비 지원 개발자 과정_Day13 (0) | 2022.12.14 |
국비 지원 개발자 과정_Day12 (0) | 2022.12.13 |
국비 지원 개발자 과정_Day11 (1) | 2022.12.12 |
댓글