Notice
Recent Posts
Recent Comments
«   2024/10   »
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
10-11 00:15
Archives
Today
Total
관리 메뉴

Developer_Neo

[코드스테이츠 백엔드 2기(40기) SEB BE] 14일차 본문

코드스테이츠

[코드스테이츠 백엔드 2기(40기) SEB BE] 14일차

_Neo_ 2022. 7. 12. 09:35
반응형

오늘 나의 학습 목표는 무엇인가요?

- 다형성이 가지는 의미와 장점, 참조변수의 타입 변환에 대한 내용을 이해하고, 업캐스팅과 다운캐스팅의 차이를 설명할 수 있다
- 추상화의 핵심 개념과 목적을 이해하며, 추상 클래스의 핵심 개념과 기본 문법을 이해할 수 있다.
- final 키워드를 이해하고,추상 클래스와 인터페이스의 차이를 설명할 수 있다.

다형성

- 하나의 객체가 여러 가지 형태를 가질 수 있는 성질

- 자바 프로그래밍에서 다형성은 한 타입의 참조변수를 통해 여러 타입의 객체를 참조할 수 있도록 만든 것을 의미 (상위 클래스 타입의 참조변수를 통해서 하위 클래스의 객체를 참조할 수 있도록 허용한 것)

class Friend {
    public void friendInfo() {
        System.out.println("나는 당신의 친구입니다.");
    }
}

class BoyFriend extends Friend {
   
    public void friendInfo() {
        System.out.println("나는 당신의 남자친구입니다.");
    }
}

class GirlFriend extends Friend {
    
    public void friendInfo() {
        System.out.println("나는 당신의 여자친구입니다.");
    }
}

public class FriendTest {

    public static void main(String[] args) {
        Friend friend = new Friend(); // 객체 타입과 참조변수 타입의 일치
        BoyFriend boyfriend = new BoyFriend();
        Friend girlfriend = new GirlFriend(); // 객체 타입과 참조변수 타입의 불일치
        //  GirlFriend friend1 = new Friend(); -> 하위클래스 타입으로 상위클래스 객체 참조 -> 불가능

        friend.friendInfo();
        boyfriend.friendInfo();
        girlfriend.friendInfo();
    }
}

// 출력값
나는 당신의 친구입니다.
나는 당신의 남자친구입니다.
나는 당신의 여자친구입니다.

Friend라는 상위클래스가 하위클래스 여러개를 가질 수 있다는 것이다. 반대는 불가하다.

 

참조변수의 타입 변환

세 가지 조건을 충족해야한다.

1. 서로 상속관계에 있는 상위 클래스 - 하위 클래스 사이에만 타입 변환이 가능합니다.
2. 하위 클래스 타입에서 상위 클래스 타입으로의 타입 변환(업캐스팅)은 형변환 연산자(괄호)를 생략할 수 있습니다.
3. 반대로 상위 클래스에서 하위 클래스 타입으로 변환(다운캐스팅)은 형변환 연산자(괄호)를 반드시 명시해야합니다.
(상위클래스에서 하위클래스로의 변경은 어렵다. 안된다.)
public class VehicleTest {
    public static void main(String[] args) {
        Car car = new Car();
        Vehicle vehicle = (Vehicle) car; // 상위 클래스 Vehicle 타입으로 변환(생략 가능)
        Car car2 = (Car) vehicle; // 하위 클래스 Car타입으로 변환(생략 불가능)
        MotorBike motorBike = (MotorBike) car; // 상속관계가 아니므로 타입 변환 불가 -> 에러발생
    }
}

class Vehicle {
    String model;
    String color;
    int wheels;

    void startEngine() {
        System.out.println("시동 걸기");
    }

    void accelerate() {
        System.out.println("속도 올리기");
    }

    void brake() {
        System.out.println("브레이크!");
    }
}

class Car extends Vehicle {
    void giveRide() {
        System.out.println("다른 사람 태우기");
    }
}

class MotorBike extends Vehicle {
    void performance() {
        System.out.println("묘기 부리기");
    }
}

캐스팅이 가능한지 여부를 boolean타입을 확인할 수 있는 자바의 문법요소가 있다. -> instanceof

참조_변수 instanceof 타입

참조_변수 instanceof 타입을 입력했을 때 리턴 값이 true가 나오면 참조 변수가 검사한 타입으로 타입 변환이 가능하며, 반대로 false가 나오는 경우에는 타입 변환이 불가능하다는 것이다. 만약에 참조 변수가 null인 경우에는 false를 반환한다.

 

활용 예제

class Coffee {
    int price;

    public Coffee(int price) {
        this.price = price;
    }
}

class Americano extends Coffee {
	public Americano(int price){
		super(price);
	}
};
class CaffeLatte extends Coffee {};

class Customer {
    int money = 50000;
    
    void buyCoffee(Americano americano) { // 아메리카노 구입
	money = money - americano.price;
    }

    void buyCoffee(CaffeLatte caffeLatte) { // 카페라테 구입
      money = money - caffeLatte.price;
    }
}

위의 코드 보다 밑의 코드가 객체의 다형성을 활요해 더 간단히 중복없이 만들 수 있다.

class Coffee {
    int price;

    public Coffee(int price) {
        this.price = price;
    }
}

class Americano extends Coffee {};
class CaffeLatte extends Coffee {};

class Customer {
    int money = 50000;
    
    void buyCoffee(Coffee coffee) { // 매개변수의 다형성
        money = money - coffee.price;
    }
}

자바의 다형성을 잘 활용하면 많은 중복되는 코드를 줄이고 보다 편리하게 코드를 작성하는 것이 가능해진다.

 


추상화

- 공통성과 본질을 모아 추출하는 것 . 자바에서의 추상화는 객체의 공통적인 속성과 기능을 추출하여 정의하는 것을 의미한다.

자바에서는 주로 추상 클래스인터페이스라는 문법 요소를 사용해서 추상화를 구현

- abstract 제어자사용

- 주로 클래스와 메서드를 형용하는 키워드로 사용되는데, 메서드 앞에 붙은 경우를 ‘추상 메서드(abstract method)’, 클래스 앞에 붙은 경우를 ‘추상 클래스(abstract class)’라고 부른다.

- 어떤 클래스에 추상 메서드가 포함되어있는 경우 해당 클래스는 자동으로 추상 클래스가 됩니다.

- 인터페이스나 추상클래스내에 있는 추상메서드는 class로 implements나 extends로 만드는 경우 반드시 구현을 해주어야한다.

abstract class AbstractExample { // 추상 메서드가 최소 하나 이상 포함돼있는 추상 클래스
	abstract void start(); // 메서드 바디가 없는 추상메서드
}

 추상 클래스는 앞서 설명한대로 미완성 설계도이기 때문에 메서드 바디가 완성이 되기 전까지 이를 기반으로 객체 생성이 불가합니다.

 

추상 클래스

- 미완성된 구조를 가지고 있기에 이를 기반으로 객체를 생성하는 것이 불가능하다.

- 자바 객체지향 프로그래밍의 마지막 기둥인 추상화를 구현하는데 핵심적인 역할을 수행

- 상속을 받는 하위 클래스에서 오버라이딩을 통해 각각 상황에 맞는 메서드 구현이 가능하다는 장점이 있다.

- 클래스의 한 종류로 생성자나 구현된 메서드들과 함께 추상메서드를 가진다. 또, 다중 상속이 불가하다.

abstract class Animal {
	public String kind;
	public abstract void sound();
}

class Dog extends Animal { // Animal 클래스로부터 상속
	public Dog() {
		this.kind = "포유류";
	}

	public void sound() { // 메서드 오버라이딩 -> 구현부 완성
		System.out.println("멍멍");
	}
}

class Cat extends Animal { // Animal 클래스로부터 상속
	public Cat() {
		this.kind = "포유류";
	}

	public void sound() { // 메서드 오버라이딩 -> 구현부 완성
		System.out.println("야옹");
	}
}

class DogExample {       
    public static void main(String[] args) throws Exception {
       Animal dog = new Dog();
       dog.sound();

       Cat cat = new Cat();
       cat.sound();
    }
 }

//Output
멍멍
야옹

final 키워드

- 필드, 지역 변수, 클래스 앞에 위치할 수 있으며 그 위치에 따라 그 의미가 조금씩 달라지게된다,

위치 의미
클래스 변경 또는 확장 불가능한 클래스, 상속 불가
메서드 오버라이딩 불가
변수 값 변경이 불가한 상수
final class FinalEx { // 확장/상속 불가능한 클래스
	final int x = 1; // 변경되지 않는 상수

	final void getNum() { // 오버라이딩 불가한 메서드
		final int localVar = x; // 상수
		return x;
	}
}

인터페이스

- interface 키워드 사용  (class 키워드 대신 interface 키워드를 사용)

- 추상 메서드와 상수만을 멤버로 가질 수 있다

 

- 내부의 모든 필드가 public static final로 정의되고, 앞서 간단하게 언급한 staticdefault 메서드 이외의 모든 메서드가 public abstract로 정의된다
( 모든 인터페이스의 필드와 메서드에는 위의 요소가 내포되어있기 때문에 명시하지 않아도 생략이 가능합니다.)

- 멤버 변수는 항상 "public static final"이다., 멤버 메소드는 항상 "public abstract"이다 하지만 public static final" 키워드는 생략 가능, "public abstract"는 생략 가능하다 (추가로 정적메소드도 선언이 가능하지만 구현부가 있어야한다.)

- 추상메서드들의 집합으로 추가로 상수를 멤버로 가질 수 있으며, 깡통으로 다중상속이 가능하다

public interface InterfaceEx {
    public static final int rock =  1; // 인터페이스 인스턴스 변수 정의
    final int scissors = 2; // public static 생략
    static int paper = 3; // public & final 생략

    public abstract String getPlayingNum();
		void call() //public abstract 생략 
}

 

인터페이스의 구현

- implements 키워드를 사용

class 클래스명 implements 인터페이스명 {
		... // 인터페이스에 정의된 모든 추상메서드 구현
}

 

- 인터페이스는 다중적 구현이 가능

class ExampleClass implements ExampleInterface1, ExampleInterface2, ExampleInterface3 { 
				... 생략 ...
}

 

장점

- 역할과 구현을 분리시켜 사용자 입장에서는 복잡한 구현의 내용 또는 변경과 상관없이 해당 기능을 사용할 수 있다는 점

 

인터페이스 내의 메서드를 보통 public abstract를 생략하여 나타낸다. 왜냐하면 public abstract로 모든 메서드가 정의되기 떄문이다.

interface Animal { // 인터페이스 선언. public abstract 생략 가능.
	public abstract void cry();
} 

interface Pet {
	void play();
}
class Dog implements Animal, Pet { // Animal과 Pet 인터페이스 다중 구현
    public void cry(){ // 메서드 오버라이딩
        System.out.println("멍멍!"); 
    }

    public void play(){ // 메서드 오버라이딩
        System.out.println("원반 던지기");
    }
}

class Cat implements Animal, Pet { // Animal과 Pet 인터페이스 다중 구현
    public void cry(){
        System.out.println("야옹~!");
    }

    public void play(){
        System.out.println("쥐 잡기");
    }
}
public class MultiInheritance {
    public static void main(String[] args) {
        Dog dog = new Dog();
        Cat cat = new Cat();

        dog.cry();
        dog.play();
        cat.cry();
        cat.play();
    }
}

//출력값
멍멍!
원반 던지기
야옹~!
쥐 잡기

클래스들을 각각 AnimalPet 인터페이스를 다중으로 구현하여 각각의 객체에 맞는 메서드를 오버라이딩하였다.

 

인터페이스의 경우 다중상속이 가능한 이유

- 상속받은 메소드가 구현체가 없는 추상메소드이기 때문이다. 왜냐하면 구현체가 없기때문에 해당 클래스에서 구현하면 해당하는 메소드를 정상적으로 호출이 가능하기 때문이다.


추상클래스 VS 인터페이스 언제 사용해야하는가

추상클래스 : Is - A 관계로 특정하며, 모두에게 필요한 공통된 기능을 사용하되, 이 기능은 각각 다를 수 있을 때 추상메서드 + 모두에게 필요한 공통된 기능을 사용할 때 메서드(구현된)

인터페이스 : HAS -A 관계로 특정하며, 공통된 기능이 아닌 추가적으로 가질 수도 있고 안 가질 수도 있는 기능들.

 

https://myjamong.tistory.com/150

 

[JAVA] 추상클래스 VS 인터페이스 왜 사용할까? 차이점, 예제로 확인 :: 마이자몽

추상클래스 인터페이스 왜... 사용할까? 우리는 추상클래스와 인터페이스에 대해서 알고 있냐고 누가 물어본다면 알고 있다고 대답을 하고있습니다. 그런데 이론적인 내용 말고 정작 "왜 사용하

myjamong.tistory.com

 

 

오버로딩 Vs 오버라이딩

오버로딩 - 매개변수의 값이나 매개변수의 갯수의 변화로 이름과 반환타입이 동일한 메서드들

오버라이딩 - 상속관계에서 상위 클래스에서의 메서드를 하위 클래스에서 다시 적는것.

 

interface Cover { // 인터페이스 정의
    public abstract void call();
}

public class Interface4 {
    public static void main(String[] args) {
        User2 user2 = new User2();
//        Provider provider = new Provider();
//        user.callProvider(new Provider());
        user.callProvider(new Provider2());
    }
}

class User {
    public void callProvider(Cover cover) { // 매개변수의 다형성 활용
        cover.call();
    }
}

class Provider implements Cover {
    public void call() {
        System.out.println("무야호~");
    }
}

class Provider2 implements Cover {
    public void call() {
        System.out.println("야호~");
    }
}

//출력값
야호~

 

 


오늘 학습 내용 중 새롭게 배운 내용은 무엇인가요?
       -  추상클래스와 인터페이스 간 사용시기

오늘 새롭게 학습한 내용을 다른 사람에게 설명할 수 있나요?
      - 네

오늘 학습한 내용 중 아직 이해되지 않은 불확실한 내용은 무엇인가요?
     -  없습니다.

이해되지 않은, 불확실한 내용을 보완하기 위해서 나는 무엇을 할 수 있을까요?
     -  구글링을 해본다.

나의 오늘 학습 만족도는 몇 점인가요?
     - 90점 (아는 내용들이라고 설렁설렁 넘어간 것들이 있는 것같다.)
반응형
Comments