반응형

자바를 공부하다 보면 헷갈리는 용어가 많은데, 특히 오버로딩(Overloading)과 오버라이딩(Overriding)이 비슷해서 많이 헷갈린다. 그런데, 사실 둘은 아무 관계 없는 내용이다. 둘의 차이점을 알아보자.

 

  오버로딩(Overloading) 오버라이딩(Overriding)
접근 제어 달라도 됨 같음
반환형 달라도 됨 같음
메서드 이름 같음 같음
매개변수 달라도 됨 같음

 

1. 오버로딩(Overloading)

같은 클래스 내에서 매소드를 확장하기 위한 것. 메소드 명은 같지만, 매개 변수, 반환형 등을 다르게 하여 편리하게 사용 가능하다.

  • 메서드 이름이 같다.
  • 매개 변수, 반환형(return)은 달라도 된다. 
  • 같은 클래스 내에 선언 되어야 한다.
  • 만약 매개 변수의 개수가 같다면 자료형이 달라야 하고, 자료형이 모두 같다면 매개 변수의 개수를 다르게 해야 한다.

코드 예시를 통해 개념을 익혀보자.

class Hello {
    void overL() {
        System.out.println("오버로딩을 위한 메서드");
    }

    void overL(String str){
        System.out.println("매개 변수 타입이 String 이고, 값은 " + str);
    }

    void overL(int k){
        System.out.println("매개 변수 타입이 int 이고, 값은 " + k);
    }

    int overL(int x, int y){
        System.out.println("반환형이 다른 메서드");
        return x;
    }
}


public class HelloJava {
    public static void main(String[] args) {

        Hello ov = new Hello();

        ov.overL();
        ov.overL("오버로딩 예제");
        int num = ov.overL(5, 6);
        System.out.println(num);

    }
}

 

2. 오버라이딩(Overriding)

부모 클래스의 메서드를 자식 클래스에서 메서드를 '재정의'하는 것이다. 

  • 메서드 명, 매개 변수, 반환형, 접근 제어자가 모두 같다.
  • 상속 받은 부모 클래스의 메서드를 재정의 하는 것이다. 다른 클래스의 메서드를 재정의 하는 것이 아니다!
class Animal {
    public void makeSound() {
        System.out.println("동물이 소리를 내고 있습니다.");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("강아지가 멍멍 소리를 내고 있습니다.");
    }
}

public class HelloJava {
    public static void main(String[] args) {
        Animal animal = new Animal();
        Dog dog = new Dog();

        animal.makeSound(); // "동물이 소리를 내고 있습니다." 출력
        dog.makeSound();    // "강아지가 멍멍 소리를 내고 있습니다." 출력

    }
}

 

반응형
반응형

추상클래스란?

1. 추상 메소드와 완성된 메소드로 구성되어 있는 클래스.
 
2. 추상 메소드(Abstract Method)선언부만 존재하며, 구현부 {}는 존재하지 않는다.
 
3. 만약 main 함수에서 추상 클래스 자료형의 객체를 생성하려면, 상속 클래스를 통해 추상 메소드를 구현(구현부를 작성)을 해야 한다.
 
4. 추상 클래스를 상속받은 클래스는 추상 클래스에 있는 추상 메소드를 구현해줘야한다. 단, 상속 받은 클래스가 추상 클래스일 경우에는 모든 추상 메소드를 구현하지 않아도 된다.

우선 첫 번쨰와 두 번째 정의를 살펴보자.

 

1. 추상 메소드와 완성된 메소드로 구성되어 있는 클래스.

2. 추상 메소드(Abstract Method)는 선언부만 존재하며구현부 {}는 존재하지 않는다.

초록색 네모 안에는 class 앞에 abstract를 사용하여 추상 클래스임을 확인할 수 있다.

빨간색 네모 안에 있는 abstract void move(int x, int y);는 여타 메소드와는 다르게 구현부 {}, 중괄호로 되어 있는 부분이 없다. 이런 메소드를 추상 메소드라고 불리며, 껍데기만 있다고 표현할 수 있다.

검은 네모 안에 있는 메소드는 흔히 볼 수 있는 메소드이다. 선언부에 void stop()이 있고, 구현부에는 값을 출력하는 것을 보이고 있다.

이처럼 추상 클래스는 클래스 내에 추상 메소드, 일반 메소드가 모두 존재할 수 있다. 하지만, 인터페이스는 무조건 추상 메소드만 있어야 한다는 것이 추상 클래스와의 차이점이다.

 

3. 만약 main 함수에서 추상 클래스 자료형의 객체를 생성하려면상속 클래스를 통해 추상 메소드를 구현(구현부를 작성)을 해야 한다.

abstract class Unit {       // 추상 클래스에는 일반 메서드도 포함. 인터페이스는 무조건 추상메서드
    int x, y;
    abstract void move(int x, int y);
    void stop() {/* 현재 위치에 정지 */}
}

class Marine extends Unit {
    void move(int x, int y){
        System.out.println("Marine[ x = " + x + ", y = " + y + "]");
    }
}

class Tank extends Unit {
    void move(int x, int y){
        System.out.println("Tank[ x = " + x + ", y = " + y + "]");
    }
}   

class Dropship extends Unit {
    void move(int x, int y) {
        System.out.println("Dropship[ x = " + x + ", y = " + y + "]");
    }
}

public class Abstract3 {
    public static void main(String args[]){
//      Unit[] group = {new Marine(), new Dropship(), new Tank()}; 아래 세 줄을 한 줄로 줄인 것   // 추상 클래스 객체를 만드는 건 불가능. 왜냐면 추상 클래스에는 추상 메서드가 있을 수 있기 때문. 그래서 상속받은 클래스 형으로 객체를 생성해야 함.
        Unit[] group = new Unit[3];
        group[0] = new Marine();
        group[1] = new Dropship();
        group[2] = new Tank();
    
        group[0].move(100, 200);
        group[1].move(100, 200);
        group[2].move(100, 200);

    }
}

 

우측이 추상 클래스, 좌측이 추상 클래스를 상속받은 Marine, Tank, Dropship 클래스

Unit 이라는 추상 클래스를 상속 받은 Marine, Tank, Dropship 클래스들은 추상 메서드인 abstract void move(int x, int y);를 구현(완성)하고 있는 것을 확인할 수 있다. 만약 Unit 추상 클래스를 상속받은 일반 클래스에서, move 메서드를 구현하지 않았다면 컴파일러에서 에러를 발견하여 빨간 줄이 뜨는 걸 볼 수 있다. 이렇게 추상 매서드를 구현해야 main에서 Unit 객체를 생성할 수 있다.

 

이렇듯, 여러 클래스에 공통적으로 사용될 수 있는 추상 클래스를 바로 작성하거나 기존 클래스의 공통 부분을 뽑아서 추상 클래스를 만들 수 있다.

 

(참고, Marine, Tank, Dropship 객체를 생성하되 참조변수는 Unit 으로 선언할 수 있다. 왜냐하면 상속 받았기 때문!

 

ex) Unit[] group = new Unit[3]; 

Unit[] group = new Marine[3];

Unit[] group = new Tank[3];

Unit[] group = new Dropship[3] ;

 

하지만 Marine 객체를 선언하면 Marine 클래스 내에 있는 메소드와 상속 받은 Unit 클래스 내에 있는 메소드만 사용 가능하다. 나머지도 동일!)

 

4. 추상 클래스를 상속받은 클래스는 추상 클래스에 있는 추상 메소드를 구현해줘야한다. 단, 상속 받은 클래스가 추상 클래스일 경우에는 모든 추상 메소드를 구현하지 않아도 된다.

 

이게 무슨 뜻인지 아래 코드를 보며 이해해보자.

 

좌측이 추상 클래스, 우측이 Marine 클래스

추상 클래스 Unit에는 세 가지의 메서드가 있다.

abstact void move, abstract void fly, void stop.

 

<만약 main 함수에서 추상 클래스 자료형의 객체를 생성하려면상속 클래스를 통해 추상 메소드를 구현(구현부를 작성)을 해야 한다>라는 3번의 정의에 따르면,  현재 Marine 클래스에는 move 메서드는 구현했지만 fly 메서드는 구현하지 않았다. 그래서 빨간 줄이 나오는 것을 볼 수 있다. 

 

하지만, 여기서 Marine 클래스를 추상 클래스로 선언한다면, 굳이 모든 추상 메서드를 구현할 필요가 없어진다.

반응형
반응형

 

https://school.programmers.co.kr/learn/courses/30/lessons/181892

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


1. 문제 설명

정수 리스트 num_list와 정수 n이 주어질 때, n 번째 원소부터 마지막 원소까지의 모든 원소를 담은 리스트를 return하도록 solution 함수를 완성해주세요.

 

 

2. 접근 방법

  1. answer 배열의 크기가 num_list.length - n + 1 것을 파악한다.
  2. num_list[n-1] 부터 num_list[n], num_list[n+1]의 수를 각각 answer[0], answer[1], answer[2] 이렇게 차례로 넣을 for 문을 만든다.

 

3. 코드

class Solution {
    public int[] solution(int[] num_list, int n) {
        int[] answer = new int[num_list.length - n + 1];
        
        for(int i = 0; i < answer.length; i++){
            answer[i] = num_list[n-1];
            n++;	// n을 1씩 증가시켜서 anser[i+1]에는 num_list[n]이 오도록 한다
        }
        return answer;
    }
}
반응형
반응형

https://school.programmers.co.kr/learn/courses/30/lessons/181928

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


1. 문제 설명

정수가 담긴 리스트 num_list가 주어집니다. num_list의 홀수만 순서대로 이어 붙인 수와 짝수만 순서대로 이어 붙인 수의 합을 return하도록 solution 함수를 완성해주세요.

 

2. 접근 방법

1) 일단 if문으로 짝수, 홀수 나눠서 새로운 배열에 저장한다. 이떄, num_list에 있는 int 형을 String으로 변환하여 각각 짝수 문자열(even)과 홀수 문자열(odd)에 저장.

 

2) String으로 저장된 값을 Integer.parseInt()로 형변환 하여 두 배열의 합을 구한다.

 

class Solution {
    public int solution(int[] num_list) {
        int answer = 0;
        
        String even = "";
        String odd = "";
        
        for(int i = 0; i < num_list.length; i++){
            if(num_list[i] % 2 == 0){
                even = even + Integer.toString(num_list[i]);	//짝수 입력
            }
            else{
                odd = odd + Integer.toString(num_list[i]);		// 홀수 입력
            }
            
        }
        answer = Integer.parseInt(even) + Integer.parseInt(odd);
        return answer;
    }
}

 

3. 회고

처음에는 Integer 객체를 쓰지 않고 구현하려고 했다.  근데 너무 복잡하게 생각했던 나머지, 그냥 String으로 변환해서 풀기로 했다. 굳이 10의 제곱수를 만들기 위해 2중 for문을 안 만들어도 됐었는데.. 역시 알고리즘 풀 때는 간단하게 생각해야 하는 것 같다.

 

반응형
반응형

https://school.programmers.co.kr/learn/courses/30/lessons/181943

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


1. 문제 설명

 문자열 my_string, overwrite_string과 정수 s가 주어집니다. 문자열 my_string의 인덱스 s부터 overwrite_string의 길이만큼을 문자열 overwrite_string으로 바꾼 문자열을 return 하는 solution 함수를 작성해 주세요.

 

 

2. 접근 방법

1) 주어진 인덱스(s)까지의 문자열 + overwriting_string 으로 구현하면 된다.

2) 이때, overwriting_string 문자열을 붙인 후에도 my_string 문자열을 추가해야 하는 경우를 생각한다.

3) 그래서, sub_st_02 (아래 코드 참고)를 사용하여 뒤에 붙여준다.

 

class Solution {
    public String solution(String my_string, String overwrite_string, int s) {
        String answer = "";
        
        int my = my_string.length();	
        int over = overwrite_string.length();
        
        String sub_st_01 = my_string.substring(0, s);
        String sub_st_02 = my_string.substring((s+over), my);
        
        return answer = answer + sub_st_01 + overwrite_string + sub_st_02;
    }
}

 

3. 회고

- 처음에는 substring 메소드 없이 구현하려고 했다. 왜냐하면, Java를 잘 몰라서 substring가 있는지 조차 몰랐기 때문이다. 그래서 my_string의 길이 - index 값이 overwring된 문자열의 길이보다 큰지, 작은지, 같은지 케이스를 모두 구분하려고 했다.

 

 그런데 알고보니 제한사항에 그것에 대한 답이 있었던 것... 문제를 잘 읽고, 이해하는 연습부터 해야겠다. 

 

반응형
반응형

https://school.programmers.co.kr/learn/courses/30/lessons/161990

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

[문제 설명]

 

코딩테스트를 준비하는 머쓱이는 프로그래머스에서 문제를 풀고 나중에 다시 코드를 보면서 공부하려고 작성한 코드를 컴퓨터 바탕화면에 아무 위치에나 저장해 둡니다.....이하 생략

 


우선 알고리즘 문제를 풀면서, 내가 가장 중요하게 생각하는 건 '복잡하게 생각하지 말자'이다. 물론 복잡한 알고리즘 문제도 있지만, 되려 복잡하게 생각하여 단순한 문제를 어렵게 접근하는 경우가 많았기 때문이다.

 

1. 주어진 wallpaper 배열의 length는 행(row)를, wallpaper 배열의 원소의 길이는 열(col)을 나타낸다.

 

 문제 특성상, String[] wallpaper의 원소 길이는 모두 같기 때문에 wallpaper[0]을 임의로 잡았다. 그리고 #이 존재하는 위치의 행과 열의 최소값과 최대값의 유무가 문제를 푸는데 키워드라는 것을 인지한다.

 

2. #이 들어가는 (최소 행, 최소 열), (최대 행 + 1, 최대 열 + 1)을 구한다.  

class Solution {
    public int[] solution(String[] wallpaper) {
        int minCol, maxCol;
        int minRow, maxRow;

        int row = wallpaper.length;
        int col = wallpaper[0].length();    //배열의 원소 길이는 같기에 wallpaper[0] 임의로 지정

        minCol = minRow = Integer.MAX_VALUE;
        maxCol = maxRow = Integer.MIN_VALUE;

        for(int i = 0; i < row; i++){
            for(int j = 0; j < col; j++){
                if(wallpaper[i].charAt(j) == '#'){
                    minRow = Math.min(minRow, i);
                    maxRow = Math.max(maxRow, i);
                    minCol = Math.min(minCol, j);
                    maxCol = Math.max(maxCol, j);
                }
            }
        }

        return new int[]{minRow, minCol, maxRow + 1, maxCol + 1};
    }
}

 

반응형
반응형

프로그래머스에서 문제를 풀다가 오름차순으로 정렬할 알고리즘이 있었다.

2중 for문에 익숙한 나는, 2중 for문으로만 하려고 했는데 알고리즘을 공부하기 위해선 다양한 방법을 시도해야 했다.

그래서 Arrays.sort() 메쏘드를 사용했다.

 

 


1. 2중 for문을 사용한 오름차순 정렬
import java.util.*;

public class HelloJava {
    public static void main(String args[]) {
        
        int[] a = new int[]{1,5,4,3,2};
        int k;

        for(int i = 0; i < a.length - 1; i++){
            for(int j = i + 1; j < a.length; j++){
                if(a[i] > a[j]){
                    k = a[i];
                    a[i] = a[j];
                    a[j] = k;       
                }
            }
        }
        System.out.println(Arrays.toString(a));
    }
}

 

 

2. Arrays.sort()를 사용하여 오름차순 정렬
import java.util.*;

public class HelloJava {
    public static void main(String args[]) {
        
        int[] a = new int[]{1,5,4,3,2};
        
       	Arrays.sort(a);
        
        System.out.println(Arrays.toString(a));
    }
}

여기서 만약에

System.out.println(a);

로 값을 출력한다면 [I@24d46ca6 와 같은 배열 a의 주소값이 나올 것이다.

배열은 참조변수이므로, 배열의 원소값을 나타내기 위해서는 toString 메소드를 사용한다면 파라미터를 통해 원소 값을 문자열로 변환 후, 원소를 출력할 수 있다.

반응형
반응형

 

적용 알고리즘 : 1~6 사이의 수 중에서 나올 수를 예측하고, 실제로 나온 수와 비교하는 것이다.

 

간단하게 해결!!

 

 

//주사위 값 예측하기

import java.util.*;

class DiceGame {    // DiceGame 클래스를 생성
    
    int diceFace;
    int userGuess;

    private void RollDice() {
        diceFace = (int)(Math.random() * 6) + 1;
    }

    private int getUserInput(String prompt) {
        System.out.println(prompt);
        Scanner s = new Scanner(System.in);
        return s.nextInt();
    }

    private void checkUserGuess() {
        if (diceFace == userGuess){
            
            System.out.println("주사위 값은 " + diceFace + "이고,");
            System.out.println("내가 예측한 값은 " + userGuess + "이다.");
            System.out.println("예측 값이 맞았다!!");
        }
        else{
            System.out.println("주사위 값은 " + diceFace + "이고,");
            System.out.println("내가 예측한 값은 " + userGuess + "이다.");
            System.out.println("예측 값이 틀렸다!!");
        }
    }

    public void startPlaying() {
        userGuess = getUserInput("예상값을 입력하시오.");       //getUserInput
        RollDice();     //RollDice 메써드 실행
        checkUserGuess();       //checkUserGuess 메써드 실행
    }
}

public class DiceGameTest {
    public static void main(String[] args) {
        DiceGame game = new DiceGame();     //DiceGame 객체 생성
        game.startPlaying();
    }
}
반응형
반응형

# for문

for문은 C, Java, javascript 등등 절차지향, 객체지향, 스크립트 언어 모든 곳에서 자주 쓰인다. 오늘은 html, css, javascript를 이용해서 간단하게 구구단을 화면에 출력해보자.

 

<HTML, javascript>

<!DOCTYPE html>
<html lang="ko">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>구구단 - for문</title>
	<link rel="stylesheet" href="css/gugudan-table.css">  <!-- 아래 css파일이 위치한 경로를 지정-->
<body>
	<h1>구구단</h1>
	<script>
		var i, j;

		for (i = 1; i <= 9; i++) {
			document.write("<table>");
			document.write("<tr><th>" + i + "단</th></tr>");
			for (j = 1; j <= 9; j++) {
				document.write("<tr><td>" + i +" X " + j + " = " + i*j + "</td></tr>");
			}
			document.write("</table>");
		}
	</script>
</body>
</html>

구구단 알고리즘은 이중for문을 사용하여 간단하게 구현할 수 있다. 그리고 나머지는, 입맛에 맞게 꾸미면 된다!

 

<CSS>

div{
    display: inline-block;
    padding: 0 20px 30px 20px;
    margin: 15px;
    border: 1px solid #ccc;
    line-height: 2;
}

div h3 {
    text-align: center;
    font-weight: bold;
}

 

위 코드는, Do it html/css, javascript의 책을 인용했습니다!

반응형
반응형

Javascript뿐만 아니라, if와 switch 제어문은 다른 언어를 공부할 때도 항상 배우는 요소이다. 각 제어문은 기능은 비슷하나, 장단점을 지니고 있다. switch는 case를 나눠서 하기 때문에 '정확하고, case가 적은 경우'에 효율적이다. if문은 '좀 더 큰 범위의 case(?)'에 장점을 지닌다. 

 

운영체제 측면에서 if와 switch를 비교하면, switch문을 사용했을 때 cpu가 명령을 수행하기 위해 메모리에 접근하는 횟수가 현저히 적다. 왜냐하면, if문을 사용했을 때는 if문을 만날 때마다 cpu가 메모리에 접근하지만, switch는 한번만 접근하면 여러 case에 값을 비교할 수 있기 때문이다.


#switch문

 

switch문은 하나 이상의 case와 break, default로 이루어져있다. 코드 예시를 보면 쉽게 이해가 될 것이다.

 

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Javascript 배우기</title>
    </head>
    <body>
        <h1>Javascript</h1>
        <script>
            var session = prompt("숫자를 선택하세요");

            switch(session) {
                case "1" : 
                document.write("숫자 1을 입력했습니다.");
                alert("1");
                break;

                case "2" : 
                document.write("숫자 2를 입력했습니다.")
                alert("2");
                break;

                case 3 : 
                document.write("숫자 3을 입력했습니다.")
                alert(3);
                break;

                default : alert("숫자를 잘못 입력하셨습니다.");
            }

        </script>
    </body>
</html>

중요한 것은 switch문의 case에는 항상 break가 있어야 한다는 것..!


# if문

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">

    <title>Document</title>
</head>
<body>
    <h1>Javascript 연습하기</h1>
    <script>
        var memNum = prompt("입장하는 관객의 수를 입력하세요.");
        var colNum = prompt("한 줄에 몇 명씩 앉을지 입력하세요.");
        var rowNum;

        if(memNum % colNum === 0){
            rowNum = memNum / colNum;
            document.write("총 " + colNum + "명씩 "+ rowNum + "줄로 앉으면 됩니다.");
        }

        else{
            rowNum = (memNum % colNum) + 1;
            document.write("총 " + colNum + "명씩 "+ rowNum + "줄로 앉으면 됩니다.");
        }
    </script>
</body>
</html>

 


# prompt와 parseInt, parsedouble 등등..

 

프롬프트(prompt)란 사용자에게 창을 띄워서 데이터를 받아올 수 있는 함수이다. 

위 switch문 예제를 실행하면 이렇게 나올텐데, 이것이 바로 prompt이다. alert과 비슷하게 생겼지만, alert은 사용자에게 말 그대로 값을 보여주는 주의와 같은 개념이기에 데이터를 받아오지는 못한다.

prompt는 데이터를 받으면 자동으로 문자열로 변환한다.

 

그렇기 때문에, parseInt()로 감싸주면, 프롬프트창으로 받은 데이터가 정수형으로 저장된다.

마찬가지로, parsedouble(), parsefloat()으로 감싸주면 실수형으로 데이터가 저장된다.

 

위의 switch예제에서 숫자 3을 입력한다면, 어떤 뜻인지 이해가 빠를 것이다.

반응형

'프로그래밍 > HTML_CSS_Javascript' 카테고리의 다른 글

[HTML/CSS?Javascript] 구구단 출력하기  (0) 2023.04.04

+ Recent posts