JAVA 객체에 대한 문제를 보면서 아직 내 것으로 만들지 못했다고 느꼈다...
똑같은 문제, 똑같은 로직인데도 코드를 짜다가 멈추고를 반복했다.- 내가 어느 부분을 어려워 했는지
- 내가 어느 부분을 대충 넘어갔는지
위의 두 가지를 계속 생각하며 혼자 찾아보거나, 코드를 짜거나
강사님께 질문했다. 복습하면서 나중에 잊더라도 찾아보자
개념을 배울 때 이해가 안되는 건 아니였지만,
막상 코드를 짜다보니 두 개념이 헷갈렸다.
한 클래스 내에 동일한 이름의 메소드를 여러 개 작성하는 것이다.
아래의 예시 코드를 보면 나는 delete
의 이름을 가진 메소드를
2개 생성했다.
// 회원정보 하나 삭제
public boolean delete(String id) {
for(int i=0; i<m.length; i++) {
if(m[i] != null && m[i].getId().equals(id)) {
m[i] = null;
return true;
}
}
return false;
}
// 전체회원정보 삭제
public void delete() {
for(int i=0; i<m.length; i++) {
m[i] = null;
}
}
하지만 매개변수의 개수와 타입이 다르다면 같은 이름의 메소드를
사용할 수 있다.
(단, return 값만 다르다면 오버로드할 수 없다.)
상속관계인 클래스에서 부모클래스에 선언된 메소드를 자식클래스가 재정의하는 것 (부모클래스에 선언된걸 자식클래스에서 덮어쓰기)
// 부모 클래스
public class OverrideParent {
public void print() {
System.out.println("!이건 부모클래스 함수!");
}
}
// 자식 클래스
public class OverrideChild extends OverrideParent {
@Override
public void print() {
System.out.println("!이건 자식클래스 함수!");
}
}
// 실행
OverrideParent op = new OverrideParent();
op.printMsg(); // !이건 부모클래스 함수!
OverrideChild oc = new OverrideChild();
oc.printMsg(); // !이건 자식클래스 함수!
(단, 메소드, 매개변수 개수, 매개변수 타입, 리턴 타입이 동일해야하고,
private
와 final
메소드는 오버라이딩 불가능)
static
을 이용하면 정적필드와 정적메소드를 만들 수 있다.static
은 클래스로 인식하기에 클래스의 로딩이 끝나는 즉시 사용할 수 있다.static
은 힙 영역이 아닌 static 영역에 할당된다.static 영역의 장점으로 여러 객체가 공유해서 접근할 수 있는 장점이 있지만
static 영역은 GC가 관여하지 못하기에 프로그램이 종료될 때까지 메모리가 할당된 채로 존재하기에 너무 static
을 많이 쓰면 시스템에 악영향을 끼칠 수 있다.
static을 선언한 클래스 맴버는 new로 인해 인스턴스를 생성하지 않아도 접근할 수 있다.
public class Test() {
public void testPrint() {
System.out.println("생성자를 만들어야함!");
}
public static void staticTestPrint() {
System.out.println("생성자 안만들어도 돼!");
}
}
public class StaticTest {
public static void main(String[] args) {
// static을 선언안한 경우 생성해서 사용
Test test = new Test();
test.testPrint();
// static을 선언한 경우
Test.staticTestPrint();
}
}
스택 영역의 메모리 크기보다 더 많이 사용할 경우 발생하는 에러로,
보통 스택 영역은 원시 타입, 또는 객체의 주소 값을 저장하는 데
GC에 의해 관리된다.
학원과제를 풀던 중 아래와 같은 코드를 작성했을 때,
왜 이런 에러가 뜨는지 몰랐다.
// 학생 화면을 담당하는 클래스
public class MainView {
Scanner sc = new Scanner(System.in);
StudentController controller = new StudentController();
...
}
// 학생 관리 프로그램의 기능을 담당하는 클래스
public class StudentController {
MainView mv = new MainView();
...
}
위의 MainView와 StudentController를 보면,
new 생성자를 통해 서로를 계속 실행시켜 무한루프에 빠진다.
처음에 이해가 안가서 그림을 그리고 보니 이해가 갔다.
(아래 그림처럼 계속 서로를 new 생성자로 호출)
return도 학원과제를 풀던 중 이해를 잘 하지못하고 사용하다 이해했다.
public void inputMenu() {
while(true) {
System.out.println("===== 도형 프로그램 =====");
System.out.println("3. 삼각형");
System.out.println("4. 사각형");
System.out.println("9. 프로그램 종료");
System.out.print("메뉴 번호 : ");
int choiceMenu = sc.nextInt();
switch(choiceMenu) {
case 3 : triangleMenu(); break;
case 4 : squareMenu(); break;
case 9 : System.out.println("프로그램 종료"); return;
default : System.out.println("잘못된 번호입니다. 다시 입력해주세요."); break;
}
}
}
public void triangleMenu() {
while(true) {
System.out.println("===== 삼각형 =====");
System.out.println("1. 삼각형 면적");
System.out.println("2. 삼각형 색칠");
System.out.println("3. 삼각형 정보");
System.out.println("9. 메인으로");
System.out.print("메뉴 번호 : ");
int choiceMenu = sc.nextInt();
switch(choiceMenu) {
case 1 : inputSize(3, 1); break;
case 2 : inputSize(3, 2); break;
case 3 : printlnformation(3); break;
// 여기가 문제!!
case 9 : System.out.println("메인으로 돌아갑니다."); inputMenu(); return;
default : System.out.println("잘못된 번호입니다. 다시 입력해주세요.");
}
}
}
위처럼 코드를 짜고 실행해보니 9
번을 입력하면 inputMenu()
로 돌아가길 바랬다.
하지만 계속 inputMenu()
가 두 번 실행되어 종료를 두 번해야지
종료가 되었는데... 알고보니 위의 주석처리처럼 문제가 있었다.
return을 사용하면 그 즉시 해당 메소드를 중지하고 호출한 메소드로 돌아가는 것, 이걸 나는 해당 메소드를 중지하는 것으로 끝인줄 알고 있었다... (그림참고)
덕분에 잘못된 개념도 고치고 배우게 된 점도 있었다.