[TIL] Udemy 17일차 프론트엔드/백엔드 - Java 기초

강준호·2024년 1월 5일

Udemy

목록 보기
21/44
post-thumbnail

메소드 오버로딩 vs 메소드 오버라이딩

  • 둘다 다형성의 한 형태

메소드 오버로딩

  • 두 개 이상의 메소드가 이름은 동일하지만 매개변수(수, 유형 또는 둘 다)가 다른 경우

  • 동일한 클래스 내에서 오버로딩이 발생

class ExampleClass {
    // Method 1: Overloaded with two integer parameters
    void display(int a, int b) {
        System.out.println("Parameters: " + a + " and " + b);
    }

    // Method 2: Overloaded with a single string parameter
    void display(String message) {
        System.out.println("Message: " + message);
    }
}

// Usage
ExampleClass obj = new ExampleClass();
obj.display(5, 10);      // Calls first method
obj.display("Hello");    // Calls second method

메소드 오버라이딩

  • IS-A(상속) 관계를 갖는 두 클래스에서 발생합니다. 하위 클래스의 메서드가 상위 클래스의 메서드와 동일한 이름, 반환 유형 및 매개 변수를 갖는 경우 해당 메서드는 상위 클래스의 메서드를 재정의합니다.
class Superclass {
    void display() {
        System.out.println("Display method in Superclass");
    }
}

class Subclass extends Superclass {
    // Overrides the display method from Superclass
    void display() {
        System.out.println("Display method in Subclass");
    }
}

// Usage
Subclass obj = new Subclass();
obj.display();  // Calls the overridden method in Subclass


팀스터디 - 객체지향의 추상화/ 다형성

추상화

  • 핵심적인 코드만 보여주기. 불필요한 부분을 숨긴다. => 깔끔하고 유지 관리가 용이하며 재사용이 가능한 코드가 만들어집니다.

  • 인터페이스와 구현을 분리

장점

  • 단순성: 추상화를 사용하면 프로그래머는 복잡한 내부 작업에 대해 걱정하지 않고 간단한 인터페이스로 작업할 수 있습니다.

  • 재사용성: 추상 클래스와 인터페이스를 재사용하여 특정 동작이 포함된 새 클래스를 만들 수 있습니다.

  • 유지관리성: 추상 클래스 또는 인터페이스의 변경 사항은 코드를 변경하지 않고도 하위 클래스에 쉽게 전파될 수 있습니다.

면접: 추상 클래스 vs 인터페이스

  • 존재 목적이 다르다.

추상클래스

  • 추상메소드: 선언부만 있고 구현부는 없는 껍데기 메소드

  • 추상 클래스는 클래스 내 '추상 메소드'가 하나 이상 포함되거나 abstract로 정의된 경우

특징

  • 다중 상속이 불가능하여 단일 상속만 허용한다.

용도

  • 클래스간의 연관 관계를 구축하는 것에 초점을 둔다.

  • 추상 클래스를 상속받아서 기능을 이용하고, 확장시키는 데 있다.

  • 코드 재사용 및 기본 기능 확장을 위해 상속됩니다.

  • 클래스이기 때문에 필드를 가질 수 있고, 메소드 구현이 가능하다. 그래서 한 80% 정도 구현하고, 나머지 20%를 자유롭게 구현하도록 할때 이를 사용.(예시)

abstract class Animal {
    // Abstract method
    abstract void makeSound();

    // Concrete method
    public void breathe() {
        System.out.println("I can breathe.");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Bark");
    }
}

class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("Meow");
    }
}
  • Animal은 추상 메서드 makeSound와 구체적인 메서드 breathe가 있는 추상 클래스입니다. Dog와 Cat은 Animal을 확장하는 구체적인 클래스로 makeSound의 자체 구현을 제공합니다.

인터페이스

  • 클래스가 아님. 추상 메소드로만 이루어져있음.

  • 모든 메소드가 추상 메소드인 경우

  • 인터페이스 끼리는 다중 상속 지원.

  • 특정 동작/방법을 보장하기 위한 계약으로 구현

용도:

  • 함수의 껍데기만 있는데, 그 이유는 그 함수의 구현을 강제하기 위해서

  • 구현 객체가 같은 동작을 한다는 것을 보장하기 위해 사용하는 것에 초점

  • 미리 이러한 메소드들을 만들겠다 하는 규약.

interface Movable {
    void move();
}

class Car implements Movable {
    @Override
    public void move() {
        System.out.println("Car moves");
    }
}

class Bicycle implements Movable {
    @Override
    public void move() {
        System.out.println("Bicycle moves");
    }
}


다형성

  • 같은 이름의 메서드나 연산자가 상황에 따라 다른 클래스에 대해 다른 동작을 하도록 하는 것을 말합니다.

장점

  • 코드의 1.재사용성과 2.유연성이 향상되며, 3.코드의 가독성도 높아집니다.

오버라이딩(overriding) : 부모클래스 메서드를 자식클래스에서 재정의하는 것

class Animal {
    void makeSound() {
        System.out.println("Some sound");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Bark");
    }
}

class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("Meow");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myAnimal = new Dog();
        myAnimal.makeSound();  // Outputs: Bark

        myAnimal = new Cat();
        myAnimal.makeSound();  // Outputs: Meow
    }
}
  • makeSound 메소드는 Dog 및 Cat 클래스 모두에서 재정의됩니다.

오버로딩(overloading) : 한 클래스에서 메소드 이름은 같지만 파라미터 개수나 자료형을 다르게 하여 서로 다르게 동작하게 하는 것

class Calculator {
    int add(int a, int b) {
        return a + b;
    }

    double add(double a, double b) {
        return a + b;
    }
}

public class Main {
    public static void main(String[] args) {
        Calculator calc = new Calculator();
        System.out.println(calc.add(5, 3));        // Outputs: 8
        System.out.println(calc.add(5.5, 3.5));    // Outputs: 9.0
    }
}

  • 유연하고 변경이 용이한 방법
  • 역할(인터페이스)과 구현(인터페이스를 구현한 클래스, 구현 객체)을 분리.
    => 역할(인터페이스) 를 먼저 부여하고, 이를 수행할 구현을 만든다!

멘토링 QnA

NoSQL에서 no의 해석에서는 의견이 갈린다고 들었습니다. 멘토님께서는 NoSQL에서 no를 어떻게 해석하시나요?

1.no 2.not only 3.non-relational operational 4. non-relational database
한국에서는 not-only로 해석하는 경우가 주류라고 들었는데, 만약 not-only로 해석한다면, SQL은 NoSQL의 하위집합인걸까요..?
더불어서 멘토님께서는 현업에서 어떤 형태의 DB를 사용하시는지, 보통 어떠한 때에 NoSQL을 사용하시고, 어떠한 때에 RDBMS를 사용하시는지 궁금합니다..!
마지막으로 현업에서도 NoSQL을 사용하다가 해당 데이터를 SQL로 옮기는 경우도 있는지 궁금합니다..!
팀 프로젝트 초반에 기획이 끝나지 않아 스키마가 완전히 정해지지 않고 추가하거나 빠질 부분이 많았을 때 NoSQL을 통해 개발을 했던 적이 있는데, 수정이 잦은 기능의 데이터가 NoSQL에 담겨있어 SQL로 변경을 할까 고민이 되었던 적이 있어 궁금합니다..!

  • 저는 NOT ONLY 로 생각한다. 개인적으로는 RDB를 그렇게 선호하지는 않아. RDB 만으로는 모든게 되지 않기 때문에.
    분산 DB,도큐먼트 DB,키밸류 DB, 매트랩DB 등 세부분류가 매우 많고.. NoSQL 로 다 묶기 힘들어.

  • NOSQL 을 훨씬 선호하는중. 몽고 디비를 선호하지만, 동료간의 협업에서 설득이 어려움. 그래서 RDB 를 섞어쓰고, 트랜잭션을 쓰는중.

  • 솔직히 트랜잭션은 성능에서 손해가 많기 때문에, 잘 사용하고 싶어하지않아. 근데 이건 내 의견이니까 대중적인 사람들은 RDB 를 더 선호해.

Q. 현업에서는 개발을 하실 때 어느정도까지 log를 남기시나요?

Java 강의 수강 도중 console에 출력하는 System.out에 대해서 다루었습니다. sout 관련해서 기존부터 받아왔던
“Sout은 성능면에서나 로그를 남기는 이유와 관련해서나, Sout 사용을 지양하고 logger또는 logger 프레임워크를 사용하는것이 좋습니다” 라는 피드백이 생각나, “왜 개발 및 운영환경에서 Sout의 사용을 지양해야하는지” 이번 기회에 공부해보았습니다…
관련해서 생긴 궁금증으로는
“운영환경이 아닌 개발환경에서 임시로 디버깅을 하기 위해서는 System.out을 사용해도 괜찮지 않을까?“라는 생각이 듭니다.
하지만 이러한 궁금증 관련해서 전자정부 프레임워크의 메뉴얼에서도 “개발/테스팅 시점에만 System.out.println()을 사용하고 운영으로 이관하기 전에 삭제하는 것은 좋은 방법이 아님.“라고 하는데, 그 이유가 궁금합니다..!
개발 도중 마주한 이슈를 해결하기 위해 필요했던 log라면, 운영환경에서 예외발생을 대비한다는 관점에서는 유의미한 log일수 있기 때문일까요?
그렇다면, 현업에서는 어느정도의 수준까지 log를 관리하시는지 궁금합니다..!
추가) 이러한 log관련해서 국내 혹은 국제적으로 표준이 있을까요?

  • 로거 레벨을 낮게두고, 디버깅과 테스트에서는 레벨을 높이는거야. 동적으로 사용하는게 좋아. sout 같은경우는 실제 동작이 달라질 수 있어. 아주 약간의 차이지만 이게 썩 좋지 않을 수 있거든.
  • 현업에서는 로그 표준이 없어. 매우 많이 관리하지만 폭발하지 않을 정도로. 많은 로그를 저장시켜두고 이를 필터링하는 방법을 사용중이야. get을 제외한 모든 api 를 다 남기긴해. 그래서 이게 양이 너무 많으니 200대가 아닌 응답을 남긴다거나, 저장 기간을 줄이거나 해.

Q.단순 연산이 필요할 때 자바코드로 연산하는것과 쿼리문으로 연산하는 것 중 어느것이 더 낫다고 생각하시나요?

  • 무조건 자바 코드가 좋습니다. DB 쿼리는 매우 느리기 때문에. 디비가 생각보다 비효율적이야. 그래서 어떠한 작은 부담이라도 DB 보다는 WAS 로 몰아가는 중이야. 이걸 알면서도 금융권은 찜찜해서 DB 에 부하를 주고있어.

몽고 db 같은 경우에는 atlas에서 mongodb를 사용하거나, aws에서 documentDB를 사용해서 클라우드 db 서비스를 간편하게 사용할 수 있는데, 카우치DB의 경우 전용 서비스를 본 적이 없어서요... AWS를 이용한다는 가정 하에 EC2를 사용해서 구성하고 백업은 S3에 올리는 형식으로 DB 구성을 진행하나요?

  • 그렇게 구성을 하는 편.

Q. nosql 관련해서, 현업에서 NoSQL을 사용하다가 해당 데이터를 SQL로 옮기는 경우도 종종 있는지 궁금합니다..!

팀 프로젝트 초반에 기획이 끝나지 않아 스키마가 완전히 정해지지 않고 추가하거나 빠질 부분이 많았을 때 NoSQL을 통해 개발을 했던 적이 있는데, 수정이 잦은 기능의 데이터가 NoSQL에 담겨있어 SQL로 변경을 할까 고민이 되었던 적이 있어 궁금합니다..!

  • 있을 수는 있는데 대단한 고민은 아닌 이유가 저런 일을 해야하니까 하는거지 옳고 그름의 문제가 아니야. DB 를 옮기는건 가능한 안하는게 좋아. rdb 를 써야한다면 계속 그걸 쓰거나, nosql 을 사용한다면 그냥 쭉 쓰는게 좋아.

Q. 현업에서는 도커or 쿠버네티스를 통해 DB 를 운영하는건 근본이 없고, 위험하다고 생각하는데 정말 그런지?

  • 규모있는 회사는 그렇게 안하려고했어. 컨테이너의 장점을 누린다는것은 최소한의 비용을 누리는거야. 근데 돈이 있는곳은 최소한의 비용보다 실수 발생의 가능성을 싫어하기 때문에 선호하지 않아.

  • 스타트업은 자사 서버가 없고, 비용을 아끼고 싶으니 도커나 쿠버네티스에 DB 를 올리긴해. 꽤 나쁘지는 않지만, 실수가 많이 나올 수 있어. EC2 와 달리 안전장치가 많이 없어서 이게 꼬이면 바로 실수가 나오거든. 그래서 이런 사고들을 조심해야해.

Q. 실무에서 javadoc을 많이 작성하시는지 궁금합니다!

  • 많이 사용하는거 같지는 않아. 사실 한번도 안써봤어. 오히려 documentation 을 받았을때 swagger 를 많이 사용했어.

0개의 댓글