Java의 상속, abstract, interface

zihooy·2023년 5월 3일
0

Java Programming

목록 보기
6/21
post-thumbnail

Java의 기본 문법 중 상속, abstract, interface에 대해 알아보자

🏹 상속

class A가 있고, class B extends A라면
B가 자식, A가 부모이며, 자식이 부모의 속성을 상속한다고 생각하면 된다.

간단하게, 항상 자식 class가 우선된다고 생각하면 된다.
그런데 만약, 부모 class를 강제로 호출하고 싶다면, super 키워드를 활용하면 된다.

class A {
	void f1() {
		System.out.println(1);
	}
	void f3() {
		System.out.println(31);
	}
}

//상속을 사용하는 이유: 기존 기능확장, 다형성 사용 
class B extends A {
	void f2() {
		System.out.println(2);	
	}
	void f3() {
		System.out.println(32);
	}
	void f4() {
		//자식이 먼저기 때문에 32가 출력됨 
		f3();
		//super를 통해 부모를 강제로 호출
		super.f3();
	}
}

public class hello {
	public static void main(String[] args) {
		B t = new B();
		// 자식한테 가보고 없으면 부모한테 감
		t.f1();	//1
		t.f2();	//2
		t.f3();	//32
		// 자식한테 가보고 없으면 부모한테 가기 때문에, 자식이 항상 먼저
		//A.f3()을 출력하는 방법: super 사용
	}
}

그런데, 주의할 점이 있다 !
생성자를 활용할 때는, 자식의 생성자 안에 super()가 있다는 것을 기억해야 한다 !
예를 들어 자식의 객체 b를 호출했다면, 자식 생성자 접근 >> 생략된 super를 통한 부모 생성자 접근 >> 다시 자식 생성자 이행 이런 흐름으로 진행된다.

만약 자식 생성자 접근 >> 생략된 super를 통한 부모 생성자 접근을 했는데 부모 생성자에 매개변수가 있다면...
자식에서 super를 명시해줘야 한다.

class A {
	A() {
		super(); //생략 가능 , 반드시 첫 줄에 있어야 한다. 
		System.out.println(1);
	}
	A(int a) {
		System.out.println(3);
	}
}
class B extends A {
	B() {
//		super(); //생략 가능 
//		super(1000); //생략 가능 
		System.out.println(2);
	}
}
//B를 call 하면 A 생성자가 불러와진다. 
//부모 >> 자식: 잘못된 해석
//자식 >> 부모: 자식의 생략된 super가 부모를 call한다. 
public class hello {
	public static void main(String[] args) {
	B b = new B();
		
	}
}

🏹 abstract

알아야 할 점 !

  • 추상 함수를 하나라도 가지고 있는 class는 반드시 abstract이어야 한다.
  • 추상 클래스는 객체를 생성시킬 수가 없다.
  • 그럼 언제 쓰나?
    상속을 목적으로 하는 -> 부모가 구현하지 못하는 것을 자식이 구현하기 원할 때 사용 가이드 라인 역할을 한다.

만약, abstract class A가 있고, class B extends A라면
B가 A에서 구현되지 않은 함수를 반드시 구현해야 한다.

abstract class A {
	// abstract(추상) : 미완성 함수 
	abstract void f1();
	// 존재하지 않기 때문에 {} 없이 선언만 
	
	// 스스로 객체를 생성하지 못함
	void f2() {
		System.out.println(2);
	}
	
}
class B extends A{
	//	부모가 구현하지 못한 것을 반드시 자식이 구현해야 해서 f1()을 가져야 한다. 
	void f1() {
		System.out.println(1);
	}
	void f3() {
		System.out.println(3);
	}
}
public class hello {
	public static void main(String[] args) {
		// 추상 클래스는 객체를 생성시킬 수가 없으므로, 코드가 성립되지 않는다. 
        // A a = new A(); // error
		B b = new B();
		b.f1();
		b.f2();

	}
}

🏹 interface

한마디로, interface는 표준 형식을 구현한 것이다.
예를 들면 한국 은행에서 여러 기업의 은행의 표준 규격을 지정하는 것처럼 interface도 표준 형식, 규격을 정한다고 생각하면 된다.

만약, interface A가 있고, class B implements A라면
B는 A가 구현하지 않은 것들을 구현해야 하며(overriding), 항상 public이어야 한다.

추상 함수만 있을 때는 interface가 된다.
단독으로 객체 생성이 불가능하다.
보통 1개의 함수가 존재한다.

abstract class A {
	abstract void f1();
	abstract void f2();
}

interface A {
	abstract void f1(); //정석 코드 
	void f2();	//abstract 생략 가능 
}

//부모가 못다한 코드를 구현 
//항상 public

class B implements A {
	//overriding
	public void f1() {
		System.out.println(1);
	}
	public void f2() {
		System.out.println(2);
	}
	void f3() {
		System.out.println(3);
	}
}

//구현되지 않은 것이 1개인지 확인하는 annotation 
@FunctionalInterface
interface C {
	void f1();
	//void f2(); // error
}

public class hello {
	public static void main(String[] args) {
		B o = new B();
		o.f1();
	}
}
profile
thisIsZihooLog

0개의 댓글