지역 변수
: 특정 지역에서만 의미를 갖는 변수
: 주로 메소드 내부에 선언되는 변수
: (), 클래스 {}가 아닌 메소드 {}에서 선언된 변수
: 메소드가 실행 될 때만 메모리에 load, 메소드 실행 종료시, 소멸
◎ 메소드
: 호출이 되면 메모리에 load, 실행
: 메소드 수행 종료시, 소멸
멤버 변수
: class 내부에 선언된 변수
: 효력 범위 - class 내부
: class가 메모리에 load 된 동안, 같이 load 상태
: class가 소멸될 때, 같이 소멸
◎ class 효력
new를 통해 메모리에 load되면, 더이상 사용되지 않아 garbage collector에 수집될 때까지 존재
package ch04_2;
class Ch04_2Dummy {
String memVar = "멤버 변수";
void method1() {
String loVar = "지역 변수";
System.out.println("local variable : " + loVar);
}
}
public class Ch04_2Ex06 {
public static void main(String[] args) {
// 메모리에 Ch04_2Cummy class load
Ch04_2Dummy dummy = new Ch04_2Dummy();
// 메모리에 메소드 load
dummy.method1();
// 실행 후 소멸
}
}
출력 결과
local variable : 지역 변수
◎ 지역 / 멤버 변수 호출
: 같은 이름의 지역 / 멤버 변수가 있을 때, 지역 변수가 먼저 호출
: 멤버 변수를 호출하려면 this.변수이름 을 사용
▶ this
: 현재 instance(class, 사용되는 상황에 따라 좁혀지는 범위 표현)
package ch04_2;
class Ch04_2Dummy2 {
String memberVar = "멤버 변수";
void print() {
String memberVar = "지역 변수";
System.out.println("memberVar : " + memberVar);
System.out.println("this.memberVar : " + this.memberVar);
}
}
public class Ch04_2Ex07 {
public static void main(String[] args) {
Ch04_2Dummy2 dummy = new Ch04_2Dummy2();
dummy.print();
Ch04_2Dummy2 dummy2 = new Ch04_2Dummy2();
dummy2.memberVar = "더미2 인스턴스";
dummy2.print();
}
}
출력 결과
memberVar : 지역 변수
this.memberVar : 멤버 변수
memberVar : 지역 변수
this.memberVar : 더미2 인스턴스
method
: class 내부 동적인 수행을 담당
▶ 접근 제한자 + return type + 메소드 이름 + (파라미터(arguments)) + {수행 코드}
: return type - 메소드 수행 후, 돌려주는 data type(int, double, String 등)
→ return - 메소드 수행 후 반환 선언
→ void - 반환값 X, return 사용 X
: 메소드 이름 - 메소드의 동작이 잘 나타나도록 명명(카멜 표기법 적용)
→ 첫문자 소문자, 이어지는 단어의 첫문자 대문자, 숫자 가능(맨앞 X), 특수문자 비권장
: 파라미터(arguments) - 메소드 수행에 필요한 값 입력 공간
▶ 장점
: 코드의 재사용성 - 한 번 만든 method는 재사용 가능
→ 코드의 모듈화, 코드의 중복 회피, 개발 기간 단축, 유지 보수 용이
package ch04_2;
class Ch04_2Dummy3 {
// return data type : String
String returnTest() {
return "문자열 return 예";
}
// argument 1개
void argumentsTest(int iVar1) {
System.out.println("argument iVar1 : " + iVar1);
}
// argument 2개
void printPuls(int iVar1, int iVar2) {
System.out.println(iVar1 + " + " + iVar2 + " = " + (iVar1 + iVar2));
}
// argument 배열
void printStrArr(String args[]) {
for (int i = 0; i < args.length; i++) {
System.out.print(args[i] + " ");
}
}
// return, argument 사용
String strConcat(String str1, String str2) {
return str1 + str2;
}
}
public class Ch04_2Ex08 {
public static void main(String[] args) {
Ch04_2Dummy3 dummy = new Ch04_2Dummy3();
// Ch04_2Dummy3의 retrunTest() 메소드 호출, 실행으로 return 값 받기
String returnedData = dummy.returnTest();
System.out.println(returnedData);
dummy.argumentsTest(777);
dummy.printPuls(25, 62);
String strArr[] = {"nice", "to", "meet", "you,", "too."};
dummy.printStrArr(strArr);
System.out.println();
String concatRes = dummy.strConcat("Hello, ", "World");
System.out.println(concatRes);
}
}
출력 결과
문자열 return 예
argument iVar1 : 777
25 + 62 = 87
nice to meet you, too.
Hello, World
▶ 호출
: 메소드는 다른 메소드 호출 가능
: 메소드 호출의 흐름 파악 필요
package ch04_2;
// method call
public class Ch04_2Ex09 {
public static void main(String[] args) {
System.out.println("main start"); // 수행 순서 1
Ch04_2Ex09 test = new Ch04_2Ex09(); // 수행 순서 2
test.worker1(); // 수행 순서 3
System.out.println("main end"); // 수행 순서 9
}
void worker1() {
System.out.println(" ▷ worker1 start"); // 수행 순서 4
worker2(); // 수행 순서 5
System.out.println(" ▷ worker1 end"); // 수행 순서 8
}
void worker2() {
System.out.println(" ▷ worker2 start"); // 수행 순서 6
System.out.println(" ▷ worker2 end"); // 수행 순서 7
}
}
출력 결과
main start
▷ worker1 start
▷ worker2 start
▷ worker2 end
▷ worker1 end
main end
▶ 메소드 구분법
: 자바 프로그램 실행 - JRE
: JRE의 메소드 구분법 - 메소드 이름 + arguments
→ 이름 또는 arguments가 다르면 다른 메소드
→ 메소드 이름이 같아도 arguments가 다르면 다른 메소드
→ 메소드 이름과 arguments가 같으면 error
▷ Method Overload
: 하나의 class에 arguments가 다르고, 이름은 동일한 메소드를 여러 개 선언 가능
: 기능적으로 같으나, 수행을 위해 받는 데이터가 다른 경우
: 동일 기능을 수행 시, 다루는 데이터가 다르더라도 하나의 통일된 이름으로 접근하는 것이 복잡도 ↓ (★)
: class로 instance 생성 시, 최초 1번만 실행되는 특수한 메소드
→ JRE가 객체 생성될 때, 최초 1번만 호출
→ return type 없음
: new를 통해 메모리에 load 될 때 호출 (ex. new Ch04_2Dummy5();의 ()가 생성자 호출)
: 메소드의 일종이므로 method overload가 가능
▶ 사용 목적
: instance 생성 시, 멤버 변수 값 대입 / instance에 데이터 전달
▶ 규칙
: 생성자의 이름은 class name과 동일
▷ 생성자를 만들지 않은 경우
: 아무 값도 없는 생성자가 있는 것으로 간주
→ default constructor - public className() {}, 해당 형태가 존재한다고 간주
▷ 생성자가 하나라도 존재하는 경우
: default constructor 제공 X
→ public className() {}, 형태의 생성자 필요
◎ class가 instance가 되는 과정
: (1) 변수 만들기
→ Ch04_2Dummy5 dummy1;
: (2) 메모리 만들기
→ new Ch04_2Dummy5;
: (3) 생성자 실행
→ Ch04_2Dummy5("메모리 load 시, 데이터 전달");
: (4) =
→ (2)번 메모리 위치 값을 (1)번 변수에 저장
package ch04_2;
class Ch04_2Dummy5 {
String memStr = "최초의 문자열";
// default constructor
public Ch04_2Dummy5() { }
public Ch04_2Dummy5(String str) {
memStr = str;
}
void print() {
System.out.println(memStr);
}
}
public class Ch04_2Ex11 {
public static void main(String[] args) {
// default constructor
Ch04_2Dummy5 dummy1 = new Ch04_2Dummy5();
dummy1.print();
// constructor
Ch04_2Dummy5 dummy2 = new Ch04_2Dummy5("메모리 load 시, 데이터 전달");
dummy2.print();
}
}
출력 결과
최초의 문자열
메모리 load시, 데이터 전달
◎ get, set
: 단축키 - Alt+S+R (★)
▶ this를 통한 생성자 접근
: 생성자 내부에서 this가 ()와 함께 쓰이면 현재 객체 내부의 또 다른 생성자 호출
: 반드시 생성자의 첫 라인에서 호출
package ch04_2;
class Ch04_2Dummy7 {
public Ch04_2Dummy7() {
this("HOW "); // 8 line 호출
}
public Ch04_2Dummy7(String str1) {
this(str1, "ARE "); // 12 line 호출
}
public Ch04_2Dummy7(String str1, String str2) {
this(str1, str2, "YOU?"); // 16 line 호출
}
public Ch04_2Dummy7(String str1, String str2, String str3) {
System.out.println(str1 + str2 + str3);
}
}
public class Ch04_2Ex13 {
public static void main(String[] args) {
Ch04_2Dummy7 dummy = new Ch04_2Dummy7();
}
}
출력 결과
HOW ARE YOU?
: 하나의 class의 유전적 특징(member 변수, member method)을 또 다른 class에 이식하는 방법
: 유전적 특징을 주는 class - parent, super, 상위, 부모 class
: 유전적 특징을 받는 class - child, sub, 하위, 자식 class
▶ extends
: 상속을 만드는 문법
: Child extends Parent - Child는 Parent를 확장(뿌리는 parent)
: java에서는 단일 상속만 지원
→ extends 뒤에 단 하나의 class만 가능
: 상속 is a relationship
→ 자식은 일종의 부모
: 하위 class는 상위 class의 일종
▶ 사용 목적
: 구조의 단순화
: 코드 재사용성 ↑
: 추가 개발 및 수정 용이 (프로그램 유연성 ↑)
: 프로그램의 확장과 관리 용이
package ch05_1;
class Ch05_1Parent {
String familyName;
void printParent() {
System.out.println(familyName);
}
}
class Ch05_1Child extends Ch05_1Parent {
String name;
void printChild() {
System.out.println(familyName + " " + name);
}
}
public class Ch05_1Ex01 {
public static void main(String[] args) {
Ch05_1Child child = new Ch05_1Child();
child.familyName = "Hong";
child.printParent();
child.name = "Gil Dong";
child.printChild();
}
}
출력 결과
Hong
Hong Gil Dong
◆ 구조 Example
package ch05_1;
public class People {
String familyName; // 성
String name; // 이름
String address; // 주소
String tel; // 전화번호
}
class Teacher extends People {
String subject; // 과목
String payAccount; // 급여 계좌
}
class Student extends People {
String grade; // 학년
String group; // 반
String protectorTel; // 보호자 전화번호
}
: 그리스어 - poly(많은) + morphos(형태)
: 상속 관계(is a relationship)에서만 성립
: 상속 받은 객체(child)의 내부에는 부모 객체(parent) 존재,ol
: 부모 타입의 변수는 자식 타입의 객체가 있는 메모리 주소 사용 가능
→
▶ 사용 목적
: Heterogeneous Collection (★)
→ 이종 배열 - 상속 개념에서 다른 데이터 타입도 다 들어가는 배열
→ 상속과 다형성 관계에서만 성립
→ non same data type, group handling, java object
▷ Homogeneous Collection - 전통적 배열 개념
→ same data type, group handling, java object
: Polymorphoic Arguments
→ 다른 글에서 보강
▶ 한계
: 부모 타입 변수는 자식 객체의 고유 영역 접근 불가능
▷ 해결
: Object Data Type Casting, 객체 타입 변경
▶ instanceof 연산자
: 어느 class 형태의 메모리인지 판별
→ true, false 만 반환
▶ method override / method overriding
: 부모 타입에 선언된 메소드를 자식 타입에서 재정의 하는 것
→ 조건 : 부모 타입에 선언된 메소드와 이름, arguments가 동일
: method overriding 된 메소드는 자식 타입에 재정의 된 메소드가 호출
▷ 사용 목적
: 자식 타입의 객체에 통일된 method를 정의, 부모 타입에서도 자식 타입의 고유 method 실행 가능
: 부모 타입의 변수로 접근 불가능한 자식 타입의 고유 영역에 접근 가능
package ch05_1;
class Ch05_1DummyParent {
String familyName;
void setting(String str) {}
void print() {
System.out.println(familyName);
}
}
class Ch05_1DummyChild extends Ch05_1DummyParent {
String name;
//method override
void setting(String str) {
this.name = str;
}
//method override
void print() {
System.out.println(familyName + name);
}
}
public class Ch05_1Ex07 {
public static void main(String[] args) {
Ch05_1DummyChild cTest = new Ch05_1DummyChild();
cTest.familyName = "강";
cTest.name = "감찬";
cTest.print();
Ch05_1DummyParent parent = new Ch05_1DummyChlid();
parent.familyName = "김";
//method override를 통해 name setting
parent.setting("수로");
//method override를 통해 (성 + 이름) 출력
parent.print();
}
}
출력 결과
강감찬
김수로