728x90
은닉성
은닉성이란?
- 멤버변수나 메서드가 객체에 노출이 되지 않도록 설정 → private
- 멤버변수가 은닉된 형태(private)로 선언된 경우, 메서드를 통해 간접적으로 접근하는 방법이 마련되어야 한다.
- 이때 사용하는 메서드가 Getter, Setter 이다.
→ Getter : 은닉된 멤버변수값을 리턴하기 위한 메서드 (리턴 O)
→ Setter : 파라미터로 전달된 값을 멤버변수에 복사하기 위한 메서드 (리턴 X)
클래스 분리
- 하나의 클래스에서 모든 기능을 구현하게 되면 유지보수 비효율적 → 기능단위로 분리 → public으로 정의
Java Beans
- 자바 언어에서 사용하는 복합적 데이터 표현의 최소 단위
- 자바로 작성된 컴포넌트(=구성요소)들을 일컫는다
- 재사용 가능한 구성요소를 생성
자바빈즈 클래스를 작동하기 위해서는
- 명명법
- 생성법
- 클래스는 생성자를 갖고 있어야 한다.
- 클래스 속성들은 get, set 등 메서드를 통해 접근할 수 있어야 한다.
→ 이의 조건을 만족하는 클래스를 자바빈즈라고 부른다.
이클립스에서 자동 완성 기능
- 클래스에서 private로 멤버변수 선언
- Alt+Shift+S 를 눌러서 자동으로 생성자를 만들 수 있다
- Alt+Shift+S를 눌러서 Getter, Settet를 자동으로 만들 수 있다
상속(extends)
클래스 간의 상속이란?
- 클래스간에는 부모-자식의 상속 관계를 설정할 수 있다.
- 부모 A 클래스를 자식 클래스 B가 상속받을 때, B는 A의 모든 변수와 메서드를 상속받는다. 단, private는 상속되지 않는다.
//정의 방법
public class 자식클래스 extends 부모클래스 { ... }
}
- 상속관계가 이루어질 때 부모 클래스를 super 클래스라 한다.
✅ 기존의 존재하는 클래스를 소스 수정없이 기능을 확장하고자 할 때 상속을 사용한다. → 상속받은 메서드에 새로운 기능 추가.
부모와 자식 클래스 작성 방법
- 부모 클래스
//부모 클래스
public class ClacParent {
public int plus(int x, int y) {
return x + y;
}
public int minus(int x, int y) {
return x - y;
}
}
- 자식 클래스
//자식 클래스
/**ClacParent를 상속받는 클래스 */
public class ClacChild extends ClacParent {
public int times(int x, int y) {
return x * y;
}
public int divide(int x, int y) {
int result = 0;
if(y!=0) {
result = x/y;
}
return result;
}
}
- 메인 클래스
public class Main01 {
public static void main(String[] args) {
//객체 생성 ClacParent parent = new ClacParent();
System.out.println(parent.plus(100, 50));
System.out.println(parent.minus(100, 50));
System.out.println("---------");
//상속된 객체는 부모의 기능까지 부를 수 있다
ClacChild child = new ClacChild();
System.out.println(child.plus(200, 100));
System.out.println(child.minus(200, 100));
System.out.println(child.times(200, 100));
System.out.println(child.divide(200, 100));
}
}
✅ 상속은 공통 기능을 부모 클래스로 만들고, 부모 클래스를 토대로 추가 기능을 첨가하여 자식 클래스를 만드는 것이 주요 원리이다.
오버라이드(Override)
-
같은 이름이지만 다른 동작을 수행해야 하는 필요성 = 재정의
→ 공격이라는 공통된 특성을 갖지만, 방법은 다르게 처리되어야 한다.
super
클래스의 상속 관계에서 자식 클래스가 부모 클래스를 가리키는 예약어
✅ super를 멤버변수 앞에 붙이면 this와 같은 의미이기 때문에 잘 사용하지 않으며, 메서드 앞에는 구분을 위해 꼭 붙여야한다.
❗ 오버라이드 된 메서드 앞에 사용하게 되면 재정의 되기 이전 원본 메서드를 의미한다.
- 키워드 자체를 메서드처럼 사용할 수 있는데, 부모 클래스의 생성자를 의미한다.
class Hello {
//부모 클래스
public void say() {
System.out.println("Hello");
}
class Korean extends Hello {
//자식 클래스
public void say() {
super.say(); //super키워드 사용하여 부모 메서드 호출
System.out.println("안녕하세요"); //기능 확장
}
}
public class Foo {
public static void main(String[] args) {
Korean k = new Korean();
k.say(); //출력했을 때 Hello와 안녕하세요 모두 출력
}
}
상속 관계 속 생성자 처리
- 생성자는 상속되지 않는다.
- 부모 클래스에서 생성자를 생성할 때 super(); 가 생략이 될 수도 있다. → 컴파일 할 때 자동으로 실행
- 생성자가 정의된 클래스는 파라미터를 반드시 전달받아야 해서 그 클래스를 상속받게 되면 에러 발생.
문제 해결
- 자식 클래스의 생성자를 통해 부모 생성자를 강제 호출.
- super 키워드를 메서드 이름으로 사용.
어노테이션(@)
- 메서드 재정의 과정에서 오타 방지
오버로드(Overload)
- 원칙적으로 하나의 클래스 안에서는 동일한 이름의 메서드가 두 개 이상 존재할 수 없지만, 예외적으로 처리할 수 있게 하는 기법.
- 호출을 쓰는 측의 편리함을 위해 오버로드 권장.
오버로드 조건
- 파라미터의 데이터 타입이 다르다.
- 파라미터의 개수가 다르다.
- 서로 다른 데이터형을 갖는 파라미터의 전달 순서가 다르다.
- 리턴형이 다른 경우는 오버로드에 성립하지 않는다.
toString()
객체 안에 파라미터가 잘 들어가있는지(=입력이 잘 되어있는지) 확인하기 위해 재정의(오버라이드)하는 것
✅ 객체의 멤버변수 값이 할당되지 않은 경우 초기값
숫자 → 0
문자열 → null
boolean → false
❗ null값은 값이 없는게 아니라 특정 시점에 모르는 값이다
✅ 객체 하나를 선언하고, 그 객체 하나로 메서드를 호출하여 값을 매개변수에 넣으면 값은 누적된다. 하지만, 객체를 각각 선언하여 값을 대입하면 값은 누적되지 않고 개별의 값이 된다.
생성자 오버로드
- 생성자를 오버로드 할 경우 객체 생성 방법을 다양하게 준비할 수 있다.
this와 super의 차이
this를 키워드로 사용하는 오버로드
- this를 메서드처럼 사용할 경우, 현재 클래스의 다른 생성자 의미
class Hello {
public Hello(String msg) {
System.out.println(msg);
}
public Hello() {
this("Hello"); //2라인 생성자 의미
}
}
객체 형변환과 배열
객체 형변환
암묵적인 형변환
Parent parent = new Child();
- 서로 상속관계에 있고 왼쪽 객체(Parent)가 오른쪽 객체(Child)의 상위 클래스인 경우에만 암묵적인 형변환이 이루어진다. → 반대의 경우 명시적 형변환이 이루어진다.
- 암묵적 형변환이 이루어진 경우 Child는 Parent의 오버라이드 한 기능만 사용할 수 있도록 제한된다.
✅ 그렇다고 독자적 기능이 사라진 것이 아니다. 가려진 것이다.
명시적 형변환
ChildClass child = (ChildClass)parent;
- 부모의 클래스 객체를 자식 클래스 형태로 변환하는 것
- 부모의 형태로 암묵적 형변환이 된 상테에서 다시 원래 자식 클래스 형태로 돌릴 때 사용된다.
명시적 형변환 조건
- 객체가 최초 생성될 때 자식 클래스 형태로 생성
- 그 자식 클래스가 부모 형태로 암묵적 형변환이 된 상태
//객체의 형변환 예제
public class Main01 {
public static void main(String[] args) {
//각 객체 할당 AirForce af = new AirForce("공군");
Navy nv = new Navy("해군");
Army am = new Army("육군");
//각각의 객체는 자신들의 고유 기능을 사용할 수 있다
af.bombing();
nv.nucleus();
am.tank();
System.out.println("-----형변환중------");
//모든 객체는 자신의 상위 형태로 암묵적 형변환 가능
//Unit은 부모 클래스
Unit temp1 = af;
Unit temp2 = nv;
Unit temp3 = am;
//형변환이 되더라도 상속받거나 재정의한(오버라이드)
//자신들의 기본 특성들은 그대로 유지
temp1.attack();
temp2.attack();
temp3.attack();
System.out.println("----복구중-----");
//상위 클래스 형변환이 되면 독립 기능은 사용 X
//temp1.bombing();
//temp2.nucleus();
//temp3.tank();
//다시 원래의 기능을 되돌리기 위해서
//하위 클래스 형태로 명시적 형변환 필요
AirForce re1 = (AirForce)temp1;
Navy re2 = (Navy)temp2;
Army re3 = (Army)temp3;
re1.bombing();
re2.nucleus();
re3.tank();
}
}
객체 배열
- 같은 클래스 객체 여러 개를 그룹화 할 수 있다.
Army[] data = new Army[3];
//Army는 클래스
data[0] = new Army(); ...
객체 배열과 형변환 같이 사용하기
- 배열의 생성이 부모 클래스로 지정되었을 경우, 모든 자식 클래스의 객체들은 그 배열에 포함될 수 있다.
- 반복문으로 일괄 처리가 가능하다.
- 배열의 요소에 자식 클래스 객체를 할당하면 자동적으로 암묵적 형변환이 이루어진다.
- 순서나 종류에 상관없이 배열에 저장할 수 있다.
instanceof 연산자 사용
- 이 연산자는 어떤 객체에 대한 출처를 판단하여 boolean형으로 결과 반환 → 조건문으로 활용 가능하다
이 내용은 itpaper 주영아 강사님의 교재를 발췌했습니다.
728x90