티스토리 뷰
| 추상 클래스 | 인터페이스 |
| 객체 생성 불가능 → 자식 클래스에서 객체 생성 |
객체 생성 불가능 → 클래스로 구현해 객체 생성 |
| 부모 클래스가 추상 클래스라면 자식 클래스에서 미완성 메소드 반드시 구현 |
|
실제로는 클래스를 만들다, 공통 특성을 가지게 될 때 부모 클래스를 만듦.
1. abstract
여러 사람이 협업할 때, 메소드 매개변수 입력 종류나 순서 등의 공통적인 틀을 갖추기 위해 사용.
※추상클래스
객체는 생성하지 않고 공통 특성만 모아두는 곳 ex) 자료형, 메소드 등등
-일반 클래스 : 객체 생성 가능
-추상 클래스 : 객체 생성 불가능
abstract class거나 abstract method가 하나라도 포함된 클래스
(1) abstract 메소드
미완성 메소드로 기능없이 이름만 정의된 것. 구현 x(중괄호 없는 메소드)
구현 여부 : 중괄호({ })가 없으면 구현 x, 있으면 구현 o
리턴 타입 앞에 입력.
abstract void cry();
//구현 안 된 '추상 메소드'
void cry(){
//구현된 '메소드'. 실행할 내용이 없을 뿐.
}
(2) abstract 클래스
내부에 추상 메소드를 하나 이상 포함하고 있거나 클래스 자체가 추상 클래스인 것.
추상 클래스는 객체 생성 불가하므로 서브 클래스(자식 클래스)에서 객체 생성한다.
abstract class A{
abstract void abc(); //추상 메소드
void bcd(){...} //일반 메소드
}
└클래스 내부에 abstract 메소드가 하나라도 있으면 abstract class여야 함.
└부모 클래스가 추상 클래스라면 자식클래스에서 미완성 메소드를 무조건 구현해줘야 한다.
(3) 추상 클래스 구현
-오버라이딩 : 부모 클래스 메소드를 자식 클래스에서 재정의(수정, 추가 등등)
-구현(implements) : 부모 클래스의 미완성 메소드를 자식 클래스에서 재정의
추상 클래스의 추상 메소드를 상속받은 자식 클래스에서 반드시 재정의해줘야 함. 해줄 때까지 오류
package aa;
public abstract class Animal{
abstract void cry(); // 추상 메소드 cry()
void func(){
System.out.println("구현 메소드");
}
}//추상 클래스
class Dog extends Animal{
//빨간 줄 쳐진 Dog에 커서 갖다대면 Add ~ 누르면 메소드 자동완성해줌.
@Override
void cry(){
System.out.println("멍멍");
}
}
class Cat extends Animal{
@Override
void cry(){
System.out.println("냐옹");
}
}
└abstract Animal의 추상 메소드 cry()를 자식 클래스인 Dog, Cat에서 메소드 구현했음. 구현하지 않으면 구현할 때까지 오류.
(4) 객체 생성하는 법
추상 클래스 자체로는 객체 생성 불가
package ff;
public abstract calss Animal{
abstract void cry(); //추상 메서드
}
//출력하는 메인 함수
public class AnimalTest{
public static main(String[] args){
Animal animal = new Animal(); //객체 생성 불가
//Animal class가 abstract class라서
}
}
-아래의 추상클래스를 바탕으로 객체 생성하는 방법 2개 설명.
package aa;
public abstract class Animal{
abstract void cry(); // 추상 메소드 cry()
void func(){
System.out.println("구현 메소드");
}
}//추상 클래스
class Dog extends Animal{
//빨간 줄 쳐진 Dog에 커서 갖다대면 Add ~ 누르면 메소드 자동완성해줌.
@Override
void cry(){
System.out.println("멍멍");
}
}
class Cat extends Animal{
@Override
void cry(){
System.out.println("냐옹");
}
}
(4-1) 상속받은 자식 클래스에서 객체 생성
객체를 많이 만들 때 유용. 정의해놓고 필요할 때마다 불러쓸 수 있어서.
상속 받은 자식 클래스 이름을 사용해 객체 만든다.
package aa;
public class AnimalTest {
public static main (String[] args){
Animal a = new Dog(); //Animal의 자식클래스 Dog에서 객체 생성
Animal a = new Cat(); //Animal의 자식클래스 Cat에서 객체 생성
a.cry(); // 멍멍
a.func(); // 구현 메소드
b.cry(); // 냐옹
b.func(); // 구현 메소드
}
}
(4-2) 익명이너클래스
일회용. 잠깐 쓰고 말 거라면 익명이너클래스 이용한다.
추상 클래스 이름을 사용해 객체를 만든다.
package aa;
public class AnimalTest {
public static void main (String[] args){
Animal c = new Animal(){ //추상클래스 - 익명이너클래스
@Override
void cry(){
System.out.println("왈왈");
}
};
Animal d = new Animal(){ //추상클래스 - 익명이너클래스
@Override
void cry(){
System.out.println("컹컹");
}
};
c.cry(); // 월월
d.cry(); // 컹컹
}
}
└익명이너클래스의 중괄호 끝에 세미콜론(;) 붙여줄 것!
-자식 클래스에서 객체 생성 vs 익명이너클래스 비교
└자식 클래스로 객체 생성 : 객체를 많이 만들 때 유용. 정의해놓고 필요할 때마다 호출해서 사용할 수 있으므로.
└익명이너클래스 : 일회용. 잠깐 쓰고 말 때.
package aa;
public class AnimalTest02{
public static void main(String[] args){
//자식클래스에서 객체 생성
Animal dog = new Dog();
Animal cat = new Cat();
//익명이너클래스 이용해 객체 생성
//└사용하려면 구현부터 해줘야 한다.
Animal c = new Animal(){
@Override
void cry(){
System.out.println("짹짹");
}
};
}//main
}
언제, 왜 쓰는가를 이해할 것!
2. 인터페이스(interface)
동일한 목적 하에서 동일한 기능을 수행하게끔 강제하는 것.
가이드라인(틀)을 주는 것. 어떤 자료형, 어떤 순서, 어떤 리턴 타입 등을 쓸 것인지 틀을 미리 정해두는 것.
자체적으로 객체 생성 불가.
상수와 추상메소드로만 구성 -(자바 1.8)→ default method(구현된 메소드), static method
어떤 객체(클래스)가 있고, 그 객체(클래스)가 특정한 인터페이스를 사용한다면(구현하고 있다면), 그 객체(클래스)는 반드시 인터페이스의 메소드를 구현(implements)해야 한다.
interface I{
public void abc();
}
class A implements I{
public void abc(){
//상속받고 있는 interface I의 구현되지 않은 메소드를 구현해야 함.
}
}
(1) 인터페이스 정의(또는 구현)
일반 필드 못 씀. 그냥 적어도 상수(public static final)과 추상 메소드(public abstract)가 자동으로 붙음.
package bb;
public interface bb {
//field
public static final int a = 3;
//추상 메소드
public abstract void abs();
//디폴트 메소드
default void bcd(){
//구현 안 해도 됨.
}
//정적 메소드
static void cde(){
System.out.println("cde");
}
}
(1-1) 필드(field)
인터페이스엔 일반 필드 못 씀. 그냥 선언해도 public static final이 자동 붙으며 생략된 것으로 간주함.
interface A{
int a = 3;
//public static final int a = 3;
}
객체 생성 불가. static이라 객체 생성없이 접근 가능. 상수라 값 변경 불가능.
package bb;
public class InterfaceTest{
public static void main(String[] args){
//객체 생성 불가능
// A a = new A();
// B b = new B();
//static이라 A 이름으로 바로 접근 가능
System.out.println(A.a);
//final이라 값 변경 불가능
// a.a = 4;
}
}
(1-2) 추상 메소드(abstract method)
(1-3) 디폴트 메소드(default method)
인터페이스를 상속하는 클래스가 존재. 이후 인터페이스에 메소드를 추가하면 인터페이스를 상속받는 클래스에서 전부 구현해줘야 함. 해줄 때까지 오류뜸. 그런데 추가한 메소드를 '디폴트 메소드'라고 해주면 괜찮음. 오류 안 뜸.
디폴트 메소드는 다른 클래스에서 공통적으로 사용하는 것. 수정없이. 즉, 상속받는 클래스에서 구현할 필요 없는 메소드
package ee;
public interface A {
void abc();
default void bcd(){ //구현 안 해도 됨.
System.out.println("method bcd");
}
}
class B implement A {
@Override
public void abc() {
System.out.println("B class의 abc");
}
}
class C implement A {
@Override
public void abc(){
System.out.println("C class의 abc");
}
}
-메인 함수에서 객체 생성 및 출력
package ee;
public class DefaultTest {
public static void main(String[] args) {
//인터페이스 A를 가지고 B, C 클래스의 객체 만들 수 있음.
A b = new B();
A c = new C();
b.abc(); //B class의 abc
b.bcd(); //method bcd
c.abc(); //C class의 abc
c.bcd(); //method bcd
}
}
*디폴트 메소드(default method)는 구현할 필요 없음. 근데 굳이 구현해보겠다.
package ee;
public interface A {
void abc();
default void bcd(){ //구현 안 해도 됨.
System.out.println("method bcd");
}
}
class B implement A {
@Override
public void abc() {
System.out.println("B class의 abc");
}
//default method 굳이 구현
public void bcd(){
A.super.bcd(); //부모의 bcd 출력
//interface는 부모가 여러 개일 수 있으므로 지정해줘야 한다.
System.out.println("B 클래스에서 재정의한 bcd");
}
}
class C implement A {
@Override
public void abc(){
System.out.println("C class의 abc");
}
//default method 굳이 구현
public void bcd(){
A.super.bcd();
System.out.println("C 클래스에서 재정의한 bcd");
}
}
package ee;
public class DefaultTest {
public static void main(String[] args) {
//인터페이스 A를 가지고 B, C 클래스의 객체 만들 수 있음.
A b = new B();
A c = new C();
b.abc(); //B class의 abc
b.bcd(); //method bcd / B 클래스에서 재정의한 bcd
c.abc(); //C class의 abc
c.bcd(); //method bcd / C 클래스에서 재정의한 bcd
}
}
(1-4) 정적 메소드(static method)
완성형으로 만들 수 있음.
package ee;
public interface A {
static void cde(){
System.out.println("cde");
}
}
A라는 인터페이스 소속 메소드. 객체 생성없이 바로 접근할 수 있음.
package ee;
public class DefaultTest {
public static void main(String[] args) {
A.cde(); //cde
}
(2) 인터페이스 상속
인터페이스는 구현 불가 → 클래스로 상속받아 구현
상속 시 implements 키워드 사용. 다중상속 가능(*일반/추상 클래스는 다중상속 불가)
//가능
클래스 extends 클래스 { }
인터페이스 extends 인터페이스 { }
클래스 implements 인터페이스 { }
//불가능
인터페이스 implements 클래스 { }
└종류가 같은 것일 때는 extends 쓰고 다를 때 implement 쓰나?
package bb;
public interface A {
public static final int a = 3;
public abstract void abc(); //추상 메소드
}
interface B{
int b = 5; //생략됐지만 public static final 붙어있음
void bcd();
}
//상속 type_1
class C_class implement A {
//A가 추상 메소드를 포함하고 있기 때문에 메소드를 구현할 때까지 오류.
@Override
public void abc(){
System.out.println("C_class");
}
}
//상속 type_2 : 다중상속 가능
class A_B_class implement A, B {
//A, B가 추상 메소드를 포함하고 있기 때문에 메소드를 구현할 때까지 오류.
@Override
public void abc(){ //interface A 메소드 구현
System.out.println("A Interface method");
}
@Override
public void abc(){ //interface B 메소드 구현
System.out.println("B Interface method");
}
}
//상속 type_3 : 클래스 C 상속받고 A, B를 구현
class C {
void func(){
System.out.println("C의 메소드");
}
}
class D extends C implements A, B {
@Override
public void abc(){ }
@Override
public void bcd(){ }
@Override
void func(){
super.func();
System.out.println("D의 메소드");
}
}
-메인 함수에서 객체 생성 및 출력
package bb;
public class InterfaceTest{
public static void main(String[] args){
//interface 객체 생성 불가
//A a = new A();
//static이라 객체 생성없이 접근 가능
System.out.println(A.a); //3
A c = new C_class();
c.abc(); //C_class
B ab = new A_B_class();
ab.abc(); //B Interface method
ab.bcd(); //A Interface method
D d = new D();
d.abc(); //
d.bcd(); //
d.func(); //C의 메소드 / D의 메소드
}
}
└d.abc();, d.bcd();은 구현하지 않아서 출력될 것이 없음.
_예제) 상속
interface A를 상속한 interface B를 구현한 클래스 생성. 이때 B의 메소드뿐만 아니라 B가 상속받은 A의 메소드도 구현해줘야 함.
package bb;
public interface A {
public static final int a = 3;
public abstract void abc(); //추상 메소드
}
interface B extends A {
int b = 3;
void bcd(); //추상 메소드
}
//B를 구현한 클래스 생성
class BImple implements B {
//B의 메소드뿐만 아니라 B가 상속받은 A 메소드까지 구현.
@Override
public void abc(){
System.out.println("method abc");
}
@Override
public void bcd(){
System.out.println("method bcd");
}
}
//A, B를 상속받은 ABExt를 구현한 클래스 ABExtImple
interface ABExt extends A, B {
void cde();
}
class ABExtImple implements ABExt {
@Override
public void abc(){ //interface A
System.out.println("abc method");
}
@Override
public void bcd(){ //interface B
System.out.println("bcd method");
}
@Override
public void cde(){ //interface ABExt
System.out.println("cde method");
}
}
(3) 인터페이스 객체 생성
자체 객체 생성 불가.
(3-1) 인터페이스를 일반 클래스로 상속해 클래스에서 객체 생성
(위에서 했던 예시들이 인터페이스를 일반 클래스로 상속해 클래스에서 객체 생성한 것)
(3-2) 익명이너클래스 사용
package cc;
public interface Computer {
void display(String name); //추상 메소드
void typing(int ssd, String cpu, int memory); //추상 메소드
}
class Desktop implements Computer { //구현
@Override
public void display(){
System.out.println("My "+name+" 컴퓨터입니다.");
}
@Override
public void typing(int ssd, String cpu, int memory){
System.out.println("모니터 크기 : 22인치");
System.out.println("SSD : "+ssd+", CPU : "+cpu+", 메모리 :"+memory+"입니다.");
}
}
class Notbook implements Computer { //구현
@Override
public void display(){
System.out.println("My "+name+" 노트북입니다.");
}
@Override
public void typing(int ssd, String cpu, int memory){
System.out.println("무게 : 300mg");
System.out.println("SSD : "+ssd+", CPU : "+cpu+", 메모리 :"+memory+"입니다.");
}
}
└모니터 크기나 노트북 무게 출력문장은 구색맞추려고 넣은 것...
package cc;
public class ComputerTest {
public static void main(String[] args){
Computer[] computers = new Computer[3];
computers[0] = new Desktop();
computers[1] = new Desktop();
computers[2] = new Notbook(); //배열로 객체 생성
computers[0].display("samsung");
computers[0].typing(512, "i5", 16); System.out.println();
computers[1].display("LG");
computers[1].typing(512, "i7", 16); System.out.println();
computers[2].display("Apple");
computers[2].typing(512, "IOS", 16);
}
}
| My samsung 컴퓨터입니다. 모니터 크기 : 22인치 SSD : 512, CPU : i5, 메모리 :16입니다. My LG 컴퓨터입니다. 모니터 크기 : 22인치 SSD : 512, CPU : i7, 메모리 :16입니다. My Apple 노트북입니다. 무게 : 300mg SSD : 512, CPU : IOS, 메모리 :16입니다. |
(↔) 추상 클래스 사용
package dd;
public abstract class Computer {
int ssd;
String cpu;
int memory;
String name;
void display(){ //method - 추상클래스에 구현된 메소드
System.out.println("My "+name+" 입니다.");
}
public abstract void typing(); //추상메소드
}
class Desktop extends Computer {
int size;
//생성자
public Desktop(int ssd, String cpu, int memory, String name, int size){
this.ssd = ssd;
this.cpu = cpu;
this.memory = memory;
this.name = name;
this.size = size;
}
@Override
public void typing(){
System.out.println("Monitor size : "+size);
System.out.println("SSD : "+ssd+", CPU : "+cpu+", MEMORY : "+memory+"입니다.");
}
}
-main 함수에서 객체 생성 및 출력
package dd;
public class ComputerTest{
public static void main(String[] args) {
// Computer computer = new Computer(); //abstract class라 객체 생성 불가
Computer computer = new Desktop(512, "i7", 16, "DeskTop", 25);
computer.display();
computer.typing();
}
| My DeskTop 입니다. Monitor size : 25 SSD : 512, CPU : i7, MEMORY : 16입니다. |
인터페이스 사용? 추상 클래스 사용? 둘 중 어느 것 사용?
인터페이스는 함수를 모아두는 역할.
(4) 인터페이스 필요성
일을 할 때, 틀을 만들어 두는 것.
interface A {
public void abc();
}
interface B {
public void bcd();
}
-각기 다른 사람에게 클래스를 만들어 interface 구현하도록 지시
class C implements A {
public void abc(){...}
}
class D implement B {
public void bcd(){...}
}
-사용 : 객체 생성 및 출력
A a1 = new C();
a1.abc();
B b1 = new D();
b1.bcd();
'수업 > └Java' 카테고리의 다른 글
| [실습문제6_1]Person, Customer, Test (0) | 2022.02.04 |
|---|---|
| [CH10]이너클래스(innner class) (0) | 2022.02.04 |
| [Ch08]자바 제어자 : final (0) | 2022.02.02 |
| [00]Wrapper class (0) | 2022.02.02 |
| [CH7]상속과 다형성 (0) | 2022.02.02 |
- Total
- Today
- Yesterday
- html pre
- A%B
- 입력양식
- html atrribute
- ScriptTag
- html input type
- scanner
- caption-side
- improt
- CascadingStyleSheet
- 미디어 태그
- 기본선택자
- 스크립태그
- border-spacing
- Java
- BAEKJOON
- html base tag
- html
- JavaScript
- 외부구성요소
- empty-cell
- html a tag
- selcetor
- css
- typeof
- html layout
- initialized
- input type 종류
- text formatting
- 변수
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |