[멀캠|Java] 4일차 수업
KB IT’s Your Life 4기 - Java 4일차
객체배열
- 기본 타입의 배열: int[],…
- 클래스, 객체의 배열: 객체 배열
package day_04;
public class MyMemberExam {
public static void main(String[] args) {
// 회원정보 관리 - 등록, 검색, 수정, 삭제 (CRUD)
// 회원: 이름, 나이
// ctrl + . : 오류가 발생한 곳으로 커서를 이동해줌.
MyMember m1 = new MyMember("홍길동", 23);
System.out.println(m1.toString());
// = System.out.println(m1); 내부적으로 객체의 주소값이 입력되면, toString매서드가 호출되도록 함.
// MyMember와 MyMember[]는 완전히 다른 타입이다. int와 int[]도 다른 타입으로 봐야한다.
// 만들어진 객체의 총 개수 : 4개 (new가 4개)
MyMember[] mems = new MyMember[3];
mems[0] = new MyMember("길동이", 33);
mems[1] = new MyMember("길동김", 25);
mems[2] = new MyMember("길동박", 35);
}
}
메모리 관리
//다음에 저장할 저장 위치를 따로 지정 X
MyMember[] mems2 = new MyMember[300];
int count = 0; //객체 저장 위치 = 저장 개수
mems2[count++] = new MyMember("길동이", 33);
mems2[count++] = new MyMember("길동김", 25);
mems2[count++] = new MyMember("길동박", 35);
CRUD
//목록출력
System.out.println("** 목록 **");
for (int i = 0; i < count; i++) {
System.out.println(mems[i]);
}
//회원검색
System.out.println("** 회원검색 **");
String findName = "길동이";
int targetIndex = -1; //찾은 회원의 위치번호.
for (int i = 0; i < count; i++) {
if(findName == mems[i].getName()) {
targetIndex = i;
}
}
if(targetIndex == -1) {
System.out.println("못찾았음");
}else {
System.out.println("찾았음: " + mems[targetIndex]);
}
//수정: 길동이의 나이를 1증가시킬 것.
System.out.println("** 회원수정 **");
for (int i = 0; i < count; i++) {
if(findName == mems[i].getName()) {
targetIndex = i;
}
}
if(targetIndex == -1) {
System.out.println("못찾았음");
}else {
System.out.println("찾았음: " + mems[targetIndex]);
// 검색 코드에서 이 부분을 추가하면 수정 코드가 됨.
int age = mems[targetIndex].getAge();
mems[targetIndex].setAge(age+1);
System.out.println("수정후: "+ mems[targetIndex]);
}
//삭제: 길동이를 찾아서 삭제할 것.
System.out.println("** 회원삭제 **");
for (int i = 0; i < count; i++) {
if(findName == mems[i].getName()) {
targetIndex = i;
}
}
if(targetIndex == -1) {
System.out.println("못찾았음");
}else {
System.out.println("찾았음: " + mems[targetIndex]);
// 검색 코드에서 이 부분을 추가하면 삭제 코드가 됨.
// 다음 index에 값을 덮어씌운다. 그리고 count값을 줄인다.
mems[targetIndex] = mems[targetIndex+1];
count--;
}
//삭제후 목록 출력
System.out.println("** 목록 **");
for (int i = 0; i < count; i++) {
System.out.println(mems[i]);
}
Manager/Service 클래스 작성
package day_04;
public class MyMemberExam2 {
public static void main(String[] args) {
MyMemberService ms = new MyMemberService();
MyMember mm = new MyMember("홍길동", 33);
ms.add(mm);
mm = new MyMember("김길동", 30);
ms.add(mm);
mm = new MyMember("박길동", 23);
ms.add(mm);
System.out.println("저장 개수= " + ms.getCount());
// 목록출력
ms.printAll();
// 검색 - 김길동의 참조값 반환 / 순서번호 반환 (문제 발생 가능성 높음)
// 검색의 성공/실패 -> 성공:0 or 양수 (옛날 style), 실패: -1 / true false / 참조값 null (객체지향
// style)
MyMember findMem = ms.searchByName("김길동");
if (findMem == null) {
System.out.println("못 찾음");
} else {
System.out.println("찾음: " + findMem);
}
// 수정 - 김길동의 나이 1증가
boolean b = ms.update("김길동", 1);
if (b) {
System.out.println("수정성공: " + findMem);
} else {
System.out.println("수정실패");
}
}
}
package day_04;
import java.util.Iterator;
public class MyMemberService {
private MyMember[] mems = new MyMember[300];
private int count = 0;
public MyMemberService() {
}
public void add(MyMember mm) {
mems[count] = mm;
count++;
// 한줄로 mems[count++] = mm; 해도 됨.
}
public int getCount() {
return count;
}
public void printAll() {
System.out.println("** 전체 출력 **");
System.out.println("* 저장 개수 = " + count);
for (int i = 0; i < count; i++) {
System.out.println(mems[i]);
} // end for
}// end printAll()
public MyMember searchByName(String findName) {
for (int i = 0; i < count; i++) {
if (findName == mems[i].getName()) {
return mems[i];
}
} // end for
return null; // 검색 실패
}
public boolean update(String name, int i) {
MyMember m = searchByName(name);
if(m == null) {
return false;
}
int age = m.getAge();
m.setAge(age+1);
return true;
}
}
상속, 추상, 인터페이스, 다형성
- 상속 자바는 다중 상속 지원X -> 하나의 부모 클래스만 상속
사용 가능한 class 정의 위치
package day_04;
public class ExtendsExam {
public static void main(String[] args) {
class A{}
}
class B{}
}
class B{} //가장 일반적임.
package day_04;
public class ExtendsExam {
public static void main(String[] args) {
A a1 = new A();
a1.i = 100;
B b1 = new B();
b1.i = 200;
b1.j = 300;
}
}
class A{int i;}
//다중상속 불가!!!!!!!!!!!!!!
class B extends A{int j;
public void prn() {
this.i = 500;}
}
-
초기화가 부모 클래스부터 발생함. 그래서 자식에 부모 클래스 생성자를 불러오는 코드가 없으면 에러가 남.
-
- 오버라이딩
- 상속관계에서 상속 메서드를 자식 클래스에서 재정의하는 것. 호출시점에서 자식클래스 메서드가 우선 호출.
-
오버로딩은 리턴 타입이 달라도 되지만, 오버라이딩은 반드시 상속관계여야하고 파라미터가 모두 같아야한다. 즉, 함수 이름이 같을 때, 파라미터가 같냐 다르냐에 따라 오버로딩인지 라이딩인지 갈라진다.
- 부모가 퍼블릭이면 자식도 퍼블릭이어야한다. 더 큰 지정을 해주어야한다.
package day_04;
public class SchoolExam {
public static void main(String[] args) {
// 학교 내 인원 관리
// 관리 대상 - 학생, 교수, 직원
// 학생 - 학번, 이름, 학과
// 교수 - 교번, 이름, 연구실 호수
// 직원(Employee) - 사번, 이름, 부서
//class Person{ id, name}
//class Student extends Person{ hakgwa }
//class Teacher extends Person{ yeongusil }
//class Emp extends Person{ buseo }
Person p = new Person("100", "길동이");
System.out.println(p);
Student st = new Student("200", "김길동", "컴공");
System.out.println(st);
Emp e = new Emp("300", "박길동", "개발");
System.out.println(e);
Teacher t = new Teacher("400", "한길동", "302");
System.out.println(t);
}
}
package day_04;
public class Person {
private String id, name;
public Person() {
}
public Person(String id, String name) {
super();
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "id=" + id + ", name=" + name ;
}
}
package day_04;
public class Student extends Person{
private String hakgwa;
public Student() {
}
public Student(String id, String name, String hakgwa) {
setId(id);
setName(name);
// =super(id, name);
this.hakgwa= hakgwa;
}
public String getHakgwa() {
return hakgwa;
}
public void setHakgwa(String hakgwa) {
this.hakgwa = hakgwa;
}
@Override
public String toString() {
return super.toString() + ", "+ "hakgwa=" + hakgwa ;
}
}
package day_04;
public class Emp extends Person {
private String buseo;
public Emp() {
}
public Emp(String id, String name, String buseo) {
super(id, name);
this.buseo = buseo;
}
public String getBuseo() {
return buseo;
}
public void setBuseo(String buseo) {
this.buseo = buseo;
}
@Override
public String toString() {
return super.toString() + ", "+ "buseo=" + buseo ;
}
}
package day_04;
public class Teacher extends Person{
private String yeongusil;
public Teacher() {
}
public Teacher(String id, String name, String yeongusil) {
super(id, name);
this.yeongusil = yeongusil;
}
public String getYeongusil() {
return yeongusil;
}
public void setYeongusil(String yeongusil) {
this.yeongusil = yeongusil;
}
@Override
public String toString() {
return super.toString() + ", "+ "yeongusil=" + yeongusil;
}
}
- (부모)person의 this와 (자식)person을 호출하는 super와 (자식)emp에서 호출하는 this는 모두 타입이 달라보이지만 같은 주소를 가리키고 있다.
Final
클래스, 변수, 메서드에 붙일 수 있다.
final 클래스는 상속이 안되는 클래스라서 extends가 불가하다.
final 메서드는 상속은 가능하지만, 오버라이딩이 불가하다.
자동 타입 변환
- upcasting 상속되는 관계에서 변환 가능 ex. Aniaml animal = new Cat();
why? upcasting을 하는 이유는 편리함을 위해서이다. (관리의 편안함 : ex. 타입을 하나만 만들고, 자식들을 자유롭게 넣을 수 있음. )
Person[] pa = new Person[100];
pa[0] = st;
pa[1] = e;
package day_04;
/** 그림판 어플 예제 */
public class DrawExam {
public static void main(String[] args) {
// 그려진 도형 정보를 관리
// 선, 원, 삼각, 사각, ...
// Line: x, y, x2, y2
// Circle: x, y, radidus
// Shape{ x, y }
// Line extends Shape{ x2, y2}
// Circle extends Shape{ radius }
Line[] lines = new Line[100];
int lineCount = 0;
Circle[] circles = new Circle[100];
int circleCount = 0;
lines[lineCount++] = new Line(...);
circles[circleCount++] = new Circle(...);
circles[circleCount++] = new Circle(...);
lines[lineCount++] = new Line(...);
Shape[] sarr = new Shape[100];
int shapeCount = 0 ;
sarr[shapeCount++] = new Line(...);
sarr[shapeCount++] = new Circle(...);
sarr[shapeCount++] = new Circle(...);
sarr[shapeCount++] = new Line(...);
}
}
instanceOf
Person[] pa = new Person[100];
pa[0] = st;
pa[1] = e;
//학교인원관리기능
SchoolService ss = new SchoolService();
ss.add(st);
ss.add(e);
//st가 가리키는 객체는 Student의 객체냐? or Student 자식 타입의 객체냐? > true, 오류
System.out.println(st instanceof Student); // true
System.out.println(st instanceof Person); // true
System.out.println(st instanceof Enp); // 오류발생
다운 캐스팅 하는 방법.
- 다운캐스팅의 경우에는 instanceof를 지나쳐야만 강제로 (Student) 타입을 바꾸어 다운캐스팅할 수 있다.
if( p instanceof Student) {
Student st2 = (Student) p; //다운캐스팅
System.out.println("학생입니다.");
}else {
System.out.println("학생이 아닙니다.");
}
컬렉션 API(ArrayList, HashMap, TreeSet)
자료구조를 class로 만든 것.
- 라이브러리 vs 프레임 워크
- 자주 쓰는 코드를 모아둔 것 -> 라이브러리
-
정해져 있는 흐름이 있어서 개발자가 틀에 맞추어 개발해야하는 것 -> 프레임 워크
- List : 순서지원X, 중복 저장O
- Set : 순서지원X, 중복 저장X
//리스트 예제
package day_04;
import java.util.ArrayList;
public class CollectionExam {
public static void main(String[] args) {
//로또 번호 생성기
// List 타입: int[]
ArrayList<Integer> lottoList = new ArrayList<Integer>();
for(int i=0; i<6; i++) {
int r = (int)(Math.random()*45+1); // 1~45 난수
lottoList.add(r);
}
System.out.println(lottoList);
System.out.println(lottoList.get(0));
}
}
- 이 외에도 size() 등 이용가능한 메소드 존재.
//리스트에서 중복을 지우고 싶을 때,
for (int i = 0; i < 6; i++) {
int r = (int) (Math.random() * 45 + 1); // 1~45 난수
if (lottoList.contains(r)) {
i--;
continue;
}
lottoList.add(r);
}
//set 예제
HashSet<Integer> lottoSet = new HashSet<Integer>();
for (int i = 0; i < 6; i++) {
int r = (int) (Math.random() * 45 + 1); // 1~45 난수
lottoSet.add(r);
}
System.out.println(lottoSet);
System.out.println(lottoSet.size());
인터페이스
구현이 없는 함수의 껍데기만을 가지고 있음
package day_04;
public class InterfaceExam {
public static void main(String[] args) {
//혈연 : 클래스 , 동호회 : 인터페이스
//수영 동호회 구성
//수영 가능한 사람만 모음
//수영하기() 메서드가 있는 객체를 정의
PersonSwim p1 = new PersonSwim("100", "홍길동");
Swimmable sm = p1;
sm.swim();
System.out.println(sm);
}
}
//interface는 주로 able이 붙는 형용사형이다.
interface Swimmable{
public void swim();
}
//수영이 가능한 사람
class PersonSwim extends Person implements Swimmable{
public PersonSwim(String id, String name) {
super(id, name);
}
@Override //컴파일러에게 내가 override를 제대로 했는지를 묻는 표현임.
public void swim() {
System.out.println("사람이.페트병으로 수영");
}
}
-
- 사용 이유
- 수영을 할 수 있는 사람만 모아서 작성할 것이다.
sma = new Swimmable[100];
sma[0] = p1;
Comparable, Comparator
- Comparable : 비교 가능한
- 인터페이스
- 객체가 정렬 당하게 함.
package day_04;
public class MyMember implements Comparable<MyMember>{
private String name; //이름
private int age; //나이
//기본 생성자, 모든 변수를 받는 생성자
public MyMember() {
}
public MyMember(String name, int age) {
super();
this.name = name;
this.age = age;
}
//getter, setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//toString() 변수의 현재값을 문자열로 반환 (디버깅용)
@Override
public String toString() {
return "MyMember [name=" + name + ", age=" + age + "]";
}
//Comparable 인터페이스 구현
//이 함수를 호출한 객체인 나랑 MyMember o랑 비교하는 함수.
@Override
public int compareTo(MyMember o) {
//나이기준 정렬
return this.age - o.age;
}
}
- Comparator : 비교기 (=정렬기)
package day_04;
import java.util.Arrays;
public class CompareExam {
public static void main(String[] args) {
MyMember[] mems2 = new MyMember[3];
int count = 0; //객체 저장 위치 = 저장 개수
mems2[count++] = new MyMember("길동이", 33);
mems2[count++] = new MyMember("길동김", 25);
mems2[count++] = new MyMember("길동박", 35);
///정렬함수
Arrays.sort(mems2);
for(int i = 0 ; i<count; i ++) {
System.out.println(mems2[i]);
}
}
}