//////
Search
📓

09/27 다형성, 추상 클래스, 인터페이스, 과제 1, 2

생성일
2022/09/27 07:08
태그

다형성(Polymorphism) - 김상호

다형성이란?

하나의 객체가 여러가지의 타입을 가질 수 있는 것 다형성은 상속, 추상화와 함께 객체 지향 프로그래밍에서 중요한 특징 중 하나이다.
Tv => 부모 타입, SmartTv => 자식 타입 일때
부모 타입 참조 변수로 자식 타입 객체를 다루는 것
ex)
Tv t = new SmartTv();
Plain Text
복사
단, 자식 타입의 참조변수로 부모 타입의 객체를 가리킬 수 없다.
Tv t = new SmartTv(); // 허용 SmartTv t = new Tv(); // 허용X
Plain Text
복사
참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 많기 때문에 자식 클래스 타입의 참주 변수로는 부모 클래스 타입의 인스턴스를 참조 할 수 없다.
정리하자면
1.
같은 타입의 인스턴스 참조 (O)
2.
부모 -> 자식 인스턴스 참조 (O)
3.
자식 -> 부모 인스턴스 참조 (x)
클래스는 상속을 통해 확장, 유지는 가능하지만 축소는 되지 않기 때문에 자식 클래스에서 사용할 수 있는 멤버의 개수가 부모 클래스와 언제나 같거나 많다.

다형성을 사용하는 이유

유지보수가 쉽다.
여러 객체를 하나의 타입으로 관리 할 수 있기 때문에 코드 관리가 편해져 유지보수가 쉽다.
결합도 하락
클래스간의 의존성이 줄어들어 결합도가 낮아지고 독립성이 강해진다.

다형성 예제 코드

class MobilePhone { protected String number; public MobilePhone(String num) { number = num; } public void answer() { System.out.println("Hi~ from " + number); } } class SmartPhone extends MobilePhone { private String androidVer; public SmartPhone(String num, String ver) { super(num); androidVer = ver; } public void playApp() { System.out.println("App is running in " + androidVer); } } public class dkd { public static void main(String[] args) { SmartPhone ph1 = new SmartPhone("010-555-777", "Nougat"); MobilePhone ph2 = new SmartPhone("010-999-333", "Nougat"); ph1.answer(); ph1.playApp(); System.out.println(); ph2.answer(); // ph2.playApp(); } }
Plain Text
복사

출력 결과

Hi~ from 010-555-777 App is running in Nougat Hi~ from 010-999-333
Plain Text
복사

추상 클래스(Abstract Class) - 이가현

추상메서드 (abstract method)

메서드는 선언부와 구현부로 구성되어 있지만 추상메서드는 선언부만 작성
미완성 메서드
/* 주석을 통해서 어떤 기능을 수행할 목적으로 작성하였는지 설명한다.*/
abstract 리턴타입 메서드 이름();
추상클래스를 상속받는 자손클래스는 ‘오버라이딩’을 통해 추상클래스의 구현부를 모두 구현주어야한다.
public abstract 리턴타입 메서드 이름();
Java
복사
예제
public abstract class Shape { int x,y; public void translate(int x, int y) { // 추상클래스 안에 보통메서드 사용 가능 this.x = x; this.y=y; } public abstract void draw(); } class Rectangle extends Shape{ int width, height; public void draw() { System.out.println("사각형 그리기 메소드"); }//추상클래스의 추상메서드 draw를 오버라이딩하여 구현부 작성 후 abstract 삭제 } class Circle extends Shape{ int radius; public void draw() { System.out.println("사각형 그리기 메소드"); }//추상클래스의 추상메서드 draw를 오버라이딩하여 구현부 작성 후 abstract 삭제 }
Java
복사

인터페이스(Interface) - 임학준

인터페이스

개발코드와 객체가 서로 통신하는 역활을한다
협업할때 인터페이스를 기반으로 한다
인터페이스 타입으로 사용함을 알려주기위해 implements키워드를 추가하고 인터페이스 이름을 명시해야 한다
interface로 생성된 메소드 앞에는 public abstract(생략가능 컴파일러 기본생성)이 들어간다
인터페이스 선언
[public]interface 인터페이스 이름 { ... } public class 구현클래스 이름 implements 인터페이스 이름{ ... } //인터페이스에 선언된 추상 메소드의 실체 메소드 선언
Java
복사
인터페이스 예제
interface Printable{ public abstract void print(String doc);//abstract붙으면 함수구현부{}가없다 } class SprinterDriver implements Printable{//클래스 상속받을때는 extends //implements는 interface의 상속 @Override public void print(String doc) { System.out.println("삼성 프린터 입니다."); System.out.println(doc); } } class LPrinterDriver implements Printable{ //abstract라 자손이 구현해야함 @Override public void print(String doc) { System.out.println("LG 프린터 입니다."); System.out.println(doc); } } public class DriverTest { public static void main(String[] args) { Printable prn = new SprinterDriver();//다형성 prn.print("출력해 주세요"); prn = new LPrinterDriver(); prn.print("출력해 주세요"); }//출력결과 }/*삼성 프린터 입니다. 출력해 주세요 LG 프린터 입니다. 출력해 주세요*/
Java
복사

다중상속(다중 인터페이스 구현 클래스)

자바는 다중상속이 지원되지 않는다 (프로그램 복잡도가 높아지기 때문)
다중상속을 하고싶으면 인터페이스를 사용한다(지원까지는 아니고 비슷하게 가능)
다중 인터페이스 선언
public class 구현클래스이름 implements 인터페이스A , 인터페이스B
Java
복사
다중 인터페이스 구현 클래스 예제
interface Printable{//inter public abstract void print(String doc);//abstract붙으면 함수구현부{}가없다 } interface Drivable{ void drive();//기본적으로 public abstract을 컴파일러가 넣는다 } interface Flyable{ void fly(); } class FlyingCar implements Drivable,Flyable{//다중상속을 흉내 //인터페이스는 다중상속 클래스는 단일상속 @Override public void fly() { System.out.println("날수 있습니다"); } @Override public void drive() { System.out.println("드라이브가 가능합니다:"); } } public class DriverTest { public static void main(String[] args) { FlyingCar flyingcar = new FlyingCar(); flyingcar.drive(); flyingcar.fly(); }//출력결과 }/*드라이브가 가능합니다: 날수 있습니다*/
Java
복사

디폴트 메소드

인터페이스 다음에는 추가함수,상수 가 온다
JDK 1.8부터 default로 일반함수(구현된 함수)도 구현 할 수 있게 되었다

인터페이스(Interface) - 최아영

인터페이스

인터페이스란?
interface 인터페이스명 { 추상 메소드 };
클래스들이 구현해야 하는 동작을 지정하는데 사용되는 추상 자료형이다.
다른 클래스를 작성하는데 도움 줄 목적으로 작성된다.
모든 필드는 public static final이어야 하며 이를 생략할 수 있다.
모든 메소드는 public abstract 이어야 하며 이를 생략할 수 있다. (static 메소드와 default 메소드는 예외)
인터페이스의 구현
class 클래스명 implements 인터페이스명 {…};
자신에 정의된 추상 메서드의 구현체 만들어주는 클래스를 작성해야한다.
인터페이스 사용
관련 없는 클래스들이 동일한 동작을 구현하기를 원할때 사용한다.
특정한 자료형의 동작을 지정하고 싶지만 누가 구형하든지 신경 쓸 필요가 없을 때 사용한다.
다중 상속이 필요할 때 사용한다.
인터페이스 예제
interface Printable { public abstract void print(String doc); } class SPrinterDriver implements Printable { @Override public void print(String doc) { System.out.println("삼성 프린터 입니다."); System.out.println(doc); } } class LPrinterDriver implements Printable { @Override public void print(String doc) { System.out.println("LG 프린터 입니다."); System.out.println(doc); } } public class PrinterTest { public static void main(String[] args) { Printable prn1 = new SPrinterDriver(); Printable prn2 = new LPrinterDriver(); prn1.print("출력해주세요."); prn2.print("출력해주세요."); } }
Java
복사

다중상속

다중 상속
자바는 다중상속을 허용하지 않는다.
인터페이스를 이용하면 다중상속의 효과를 낼 수 있다.
다중 상속 예제
interface Drivable { void drive(); } interface Flyable { void fly(); } // 다중 상속 class FlyingCar implements Drivable, Flyable { @Override public void drive() { System.out.println("드라이브가 가능합니다."); } @Override public void fly() { System.out.println("날 수 있습니다."); } } public class CarTest { public static void main(String[] args) { FlyingCar car = new FlyingCar(); car.drive(); car.fly(); } }
Java
복사

디폴트 메소드

디폴트 메소드
인터페이스에 메소드 구현이 가능하다.
메소드 앞에 default를 붙여야 한다.
디폴트 메소드 예제
interface Shape { final double PI = 3.14; public abstract void draw(); public abstract double getArea(); default public void redraw() { System.out.println("--- 다시 그립니다.."); draw(); } } class Circle implements Shape { private int radius; public Circle (int radius) { this.radius = radius; } @Override public void draw() { System.out.println("원을 그립니다."); } @Override public double getArea() { return radius * radius * PI; } @Override public void redraw() { Shape.super.redraw(); } } public class ShapeTest { public static void main(String[] args) { Shape donut = new Circle(10); donut.redraw(); System.out.println("면적은 " + donut.getArea()); } }
Java
복사

과제1(Selection Sort) - 조국현

public class SelectionSort { public static void main(String[] args){ int[] arr = {7, 3, 2, 8, 9, 4, 6, 1, 5}; int min; int temp, index=0; for(int i = 0; i < arr.length-1; i++) { min = arr[i]; for(int j = i+1; j < arr.length; j++) { if(min > arr[j]) { min = arr[j]; index = j; } } temp = arr[i]; arr[i] = arr[index]; arr[index] = temp; } for (int num : arr) { System.out.println(num); } } }
JavaScript
복사

과제2(Stack Implement) - 김기헌

Stack을 Array 기반으로 구현하기
Main class → main 메소드
package _0927.stack; import java.util.Scanner; public class Main { public static void main(String[] args) { int size = 0; Scanner sc = new Scanner(System.in); System.out.println("스택 사이즈 입력:"); size = sc.nextInt(); Stack stack = new Stack(size); while (true) { int num; System.out.println("0: Stop 1: push 2: pop 3: peek 4: number of stack member 5: isEmpty 6: clear"); num = sc.nextInt(); if (num == 0) { System.out.println("종료되었습니다"); break; } Action action = new Action(num, stack); action.exe(); stack.printStack(); } } }
Java
복사
Function Interface
package _0927.stack; public interface Function { boolean isEmpty(); void push(char input); void clear(); void pop(); void peek(); void number(); void printStack(); }
Java
복사
Stack Class → 스택 기능들을 구현한 클래스
package _0927.stack; public class Stack implements Function { private int size, top = -1; private char arrayStack[]; public Stack(int size) { this.size = size; this.arrayStack = new char[size]; } @Override public boolean isEmpty() { if (top == -1) return true; else return false; } @Override public void push(char input) { if (top < size - 1) { arrayStack[top + 1] = input; top++; System.out.println(input + "값을 스택에 넣었습니다"); } else { System.out.println("스택이 가득 찼습니다"); } } @Override public void clear() { if (!isEmpty()) { arrayStack = new char[this.size]; top = -1; System.out.println("스택 클리어 완료"); } else { System.out.println("스택이 이미 비어있습니다"); } } @Override public void pop() { if (!isEmpty()) { char tmp = arrayStack[top]; top--; System.out.println(tmp + " 제거 완료"); } else { System.out.println("스택이 비어 있습니다"); } } @Override public void peek() { if (!isEmpty()) { System.out.println("현재 스택의 top: " + arrayStack[top]); } else { System.out.println("스택이 비어 있습니다"); } } @Override public void printStack() { if (isEmpty()) { System.out.println("Stack is empty"); } else { System.out.printf("현재 스택에는 "); for (int i = 0; i < top + 1; i++) { System.out.printf("%c ", arrayStack[i]); } System.out.println("가 있습니다"); } } @Override public void number(){ System.out.println("현재 스택에는 "+(top+1)+"개의 멤버가 있습니다"); } }
Java
복사
Action Class → 어떤 기능을 수행할지 전달 받아 기능을 수행하는 클래스
package _0927.stack; import java.util.Scanner; public class Action { private int num; private Stack stack; public Action(int num, Stack stack) { this.num = num; this.stack = stack; } public void exe() { switch (num) { case 0: break; case 1: char input; Scanner sc = new Scanner(System.in); System.out.println("입력 값:"); input = sc.next().charAt(0); stack.push(input); break; case 2: stack.pop(); break; case 3: stack.peek(); break; case 4: stack.number(); break; case 5: stack.isEmpty(); break; case 6: stack.clear(); break; } } }
Java
복사