1. 상속 (Inheritance)
- 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것
- 상속을 사용하기 위해 'extends' 키워드를 사용한다
- 부모클래스(상속해주는 클래스)와 자식클래스(상속받는 클래스)로 구성되며 단일 상속 개념이므로 1:1이다
- 자식클래스에서 부모클래스의 내용을 사용할 수 있다
- 상속 개념을 적용함으로써 개발시간 단축, 재사용성 등으로 OOP 장점을 살릴 수 있다
- 부모 자식간에 "자식 is a 부모"라는 is a 관계가 성립해야한다
부모클래스
public class Parent {
// [멤버변수]
String name;
int age;
// [생성자]
// 기본생성자]
public Parent() {
}// Person()
// 인자생성자]
public Parent(String name, int age) {
this.name = name;
this.age = age;
}// Person(name,age)
// [멤버메소드]
private void eat() {
System.out.println("부모님이 드신다");
}// eat()
String sleep(int age) {
System.out.println("부모님이 주무신다");
return null;
}// sleep()
protected int walk(Date date) {
System.out.println("부모님이 산책하신다");
return 0;
}// work()
public void exercise() {
System.out.println("부모님이 운동하신다");
}// exercise()
String getParent() {
return String.format("이름: %s, 나이:%d ", name, age);
}// getParent()
void printParent() {
System.out.println(getParent());
}// printParent()
static void staticMethod() {// 미리 메모리 생성
System.out.println("부모님의 정적 메소드");
}// staticMethod()
}// Person
자식클래스
public class Child extends Parent {
// [멤버변수]
String newExtendVar;// 자식에서 새로 확장한 변수
// [인자생성자]
public Child(String name, int age, String newExtendVar) {
// [멤버변수 초기화]
/*this.name=name;
this.age=age;*/
super(name,age);// 위 this랑 같음
this.newExtendVar=newExtendVar;
}// Child
// [멤버메소드]
void newExtendMethod() {// 자식에서 새롭게 확장한 멤버
System.out.println("자식에서 새롭게 확장한 메소드");
}// newExtendMethod()
// 자식에서 새롭게 정의한 메소드] - 오버라이딩 아님
// 부모의 private이 붙은 메소드는 오버라이딩 절대불가 (자식에게서 안보임)
private void eat() {// 오버라이딩 규칙에 맞으나 부모꺼가 안보임
System.out.println("자식이 먹는다");
}// eat()
@Override // @Override 붙으면 밑에 메소드는 오버라이딩한 메소드라는걸 알려줌
public String sleep(int year) {// 오버라이딩에 해당됨 - public 붙어서 더 넓음
// 접근지정자가 부모와 같거나 더 넓어야 됨
System.out.println("자식이 잔다");
return "";
}// sleep()
// 오버라이딩 안하고 그대로 사용 , 매개변수 타입만 다르게 사용
// 자식에게서 새롭게 확장한 멤버
int walk(int date) {// 상속 받았는데 중복 정의해서 빨간줄 감 // int date 는 오버로딩
System.out.println("나이가 "+age+"살인 자식이 걷다");
return 0;
}// walk()
@Override
public void exercise() {
// 부모의 메소드를 그대로 사용하도록 재정의
// super.exercise();// 의미 없음
// 그대로 사용하지 않고 재정의
System.out.println("자식이 운동한다");
}// exercise()
// @Override // 정적 메소드는 오버라이딩 할수 없다
static void staticMethod() {// 미리 메모리 생성
System.out.println("자식의 정적 메소드");
}// staticMethod()
@Override
String getParent() {
return super.getParent()+"] ,자식멤버 변수] "+newExtendVar;
}// getParent()
@Override
void printParent() {
System.out.println(getParent());
}// printParent()
}// Child
2. 오버로딩(OverLoading)
- 하나의 클래스 안에서 적용되는 개념으로 같은 이름의 메소드를 여러개 정의 할 수 있다
- 메소드 명이 동일 해야한다
- 매개변수의 데이터 타입이 다르거나 매개변수의 갯수가 다르거나 매개변수의 타입, 순서가 다른경우로 오버로딩에 해당한다
- 매소드의 반환타입은 상관 없다
메소드 오버로딩 방법
// 1] 매개변수 타입이 다른 경우 - 양념의 종류가 다른 경우 (매개변수 개수와 순서는 동일)
void paramTypeDiff(int param) {}
void paramTypeDiff(float param) {}
void paramTypeDiff(double param) {}
// 2] 매개변수 개수가 다른 경우 - 양념을 넣는 횟수가 다른경우
void paramCountDiff() {}
void paramCountDiff(int param) {}
void paramCountDiff(int param, int param2) {}
void paramCountDiff(int param, int param2, int param3) {}
// 3] 매개변수 타입이 같고 개수도 같지만 순서가 다른 경우 - 양념은 같은데 넣는 순서가 다름
void paramOrderDiff(int param1, float param2, double param3) {}
void paramOrderDiff(float param2, int param1, double param3) {}
void paramOrderDiff(double param3, float param2, int param1) {}
3. 오버라이딩(OverRiding)
- 상속시에 적용되는개념 즉 부모로부터 상속 받은 메소드를 재정의해서 사용하는 것
- 메소드명이 동일해야 한다.
- 메소드의 매개변수 갯수, 데이터타입이 같아야 한다.
- 메소드의 반환타입도 같아야 한다.
- 부모 메서드의 접근 지정자가 public이거나 protected인 경우에만 오버라이딩이 된다.
- 부모 메서드가 default 지정자나 private지정자를 가진 메서드를 오버라이딩 한경우 자식 고유의 메서드로 처리된다 (오버라이딩 한 것이 아님)
- 단,default접근 지정자는 다른 패키지에서는 접근이 안됨으로 부모와 자식이 다른 패키지일 경우에만 오버라이딩 한것이 아님. 같은 패키지일 경우는 오버라이딩에 해당
- Exception의 경우 부모 클래스의 메소드와 동일하거나 더 구체적인 Exception을 발생시켜야 한다.
public class OverridingApp {
public static void main(String[] args) {
// 인스턴스 변수 - Child타입
// 메모리 - Child타입
Child child = new Child("가길동",20,"자식멤버변수");
System.out.println("[자식 타입의 인스턴스 변수-오버라이딩 메소드 호출]");
child.sleep(10);
child.exercise();
System.out.println(child.getParent());
child.printParent();
System.out.println("[자식 타입의 인스턴스 변수-자식에서 새롭게 확장한 메소드 호출]");
child.newExtendMethod();
child.walk(0);
Parent.staticMethod();
Child.staticMethod();
// 인스턴스 변수 - Parent타입 (부모)
// 메모리 - Child타입 (자식)
Parent parent = new Child("나길동", 30, "새롭게 만든 멤버변수");
// 원래는 안되는데 상속관계때문에 된다 반대는 안됨 // 하나의 다형성 업캐스
// 자식에게서 새롭게 정의한건 안보이지만 오버라이딩 한건 보임
// 인스턴스 변수가 부모타입이든 자식타입이든 무조건 오버라이딩한 메소드가 호출됨
// 단, 오버라이딩 하지 않았다면 상속받은 부모의 메소드가 호출됨
// 만약 오버라이딩한 메소드 호출시 부모의 메소드를 사용하고자 한다면
// super로 접근해서 재정의 하면됨
System.out.println("[부모 타입의 인스턴스 변수-오버라이딩 메소드 호출]");
parent.sleep(10);
parent.exercise();
System.out.println(parent.getParent());
parent.printParent();// 전부 부모꺼로 되있지만 자식(오버라이딩)이 뜸
System.out.println("[부모 타입의 인스턴스 변수-자식에서 새롭게 확장한 메소드 호출]");
// parent.newExtendMethod();[x] 절대 접근 안됨
// parent.walk(0);[x]
// 그러나 형변환 하면 됨
((Child) parent).newExtendMethod();// 단, 두 관계가 상속 관계여야만 함, 형변환
Child ch = ((Child) parent);// 형변환 다운 캐스팅
ch.walk(0);
}// main
}// class
4. this()
- 정의 : 자신의 객체 또는 생성자를 지칭하는 대명사
- 사용 목적
ㄴ 생성자나 메소드 내에서 지역변수와 이름이 같은 멤버변수를 사용하려고 할 때 사용한다
ㄴ 자신의 생성자를 호출할 때 사용한다
ㄴ 자신의 객체를 다른 클래스에게 넘길 때 사용한다
ㄴ 한 클래스 안에 여러개의 생성자가 오버로딩된 형태로 존재하며 기능이 유사할때 자기 자신의 다른 생성자를 호출
할 수 있다
- 단, this()는 생성자 안에서만 호출해야 하며 super()와 같이 쓸수 없다
class C {
int age;
String name = "";
void m1(int age) {
this.age = age;
}
C() {
this("C의 멤버 name");
new CUser(this).use();
}
C(String name) {
this.name = name;
}
public static void main(String[] args) {
C c = new C();
}
}
class CUser {
C c;
CUser(C c) {
this.c = c;
}
void use() {
c.m1(25);
System.out.println(c.age); // 25
System.out.println(c.name); // C의 멤버 name
}
}
5. super()
- 정의 : 부모의 객체 또는 생성자를 지칭하는 대명사
- 사용 목적
ㄴ 부모의 생성자를 호출할 때 사용한다
ㄴ 이름이 같은 부모의 멤버 변수를 접근할 때 사용한다
ㄴ 오버라이딩하기 전의 부모 메소드를 호출할 때 사용한다
ㄴ 정적 메소드 안에서 사용할 수 없다
- 부모클래스의 멤버에 접근 할때 사용하지만 private은 접근 불가
class D {
String name;
D(String name) {
this.name = name;
}
void m() {
System.out.println("부모의 메소드 m()");
}
public static void main(String[] args) {
new DChild().use();
}
}
class DChild extends D {
final String name = "자식 Dchild의 멤버 name"; // 자신의 것이 우선
DChild() {
super("부모 D의 멤버 name");
}
void m() { // 오버라이딩
System.out.println("자식의 메소드 m()");
}
void use() {
System.out.println("name: " + this.name); // this 생략됨
System.out.println("name: " + super.name);
this.m();
super.m();
}
}
-----
name: 자식 Dchild의 멤버 name
name: 부모 D의 멤버 name
자식의 메소드 m()
부모의 메소드 m()
'개발 > JAVA' 카테고리의 다른 글
15. JAVA 패키지 / 패키지 배포 (0) | 2020.06.08 |
---|---|
14. JAVA 추상화 / 캡슐화 / 은닉화 / 생성자 / 싱글톤 (0) | 2020.06.08 |
12. JAVA ect 클래스 (Math / Date / Calendar / SimpleDateFormat) (0) | 2020.06.08 |
11. JAVA String Basic / String Method / StringBuffer (0) | 2020.06.08 |
10. JAVA static블락 / wrapper클래스 : 네이버 블로그 (0) | 2020.06.08 |