자바 문법 한눈에 정리 2편

메서드(static)


중복된 코드를 방지하기 위함

public class Main {
    public static void main(String[] args) {
        add(50,10);
        System.out.println(minus(40,10)); //return을 사용시 바깥에서도 출력가능
    }

    public static void add(int x, int y){ //(파라미터) void가 있다는 건 return 값이 없다는 것
        System.out.println(x+y);
    }

    public static int minus(int x, int y){
        return x-y;
    }
}

메소드 오버로드


public class Main {
    public static void main(String[] args) {
        System.out.println(add(50,10));
        System.out.println(add(40,10,12));

        System.out.println(add(10,12,13,14));
    }

    public static int add(int x, int y){ //메서드 이름이 같다면 변수의 개수가 달라야 함
        return x+y;
    }

    public static int add(int x, int y,int z){
        return x+y+z;
    }

    public static int add(int... numbers){ //...은 0개이상의 숫자
        int sum = 0;
        for(int i =0; i < numbers.length; i++){
            sum = sum + i;
        }
        return sum;
    }
}

static


static 메모리에 처음 프로그램 실행시 처음 로드가 되는 부분이라 별도의 영역의 메모리를 차지하기 때문에 public static void main(String[] args)는 상위인 public class Main과는 상관이 없음

클래스와 getter, setter와 생성자


클래스 : 속성과 기능으로 나눠짐

getter 와 setter : 굳이 private으로 변수를 생성하고 get/set을 이용해 데이터에 접근하는 이유는 데이터 무결성지키기 위함이다. 만약 음식의 가격, 갯수가 음수가 온다면 데이터 형식에 맞지 않기 때문에 getset 함수 내에서 무결성을 지켜주어야 한다.

private String name;
    private int age;

//private을 하는 대신 getter와 setter을 해줌
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

생성자


생성자의 규칙

  1. 클래스명과 메소드명이 동일하다.

  2. 리턴타입을 정의하지 않는다. (void도 사용하지 않는다.)

Person(String name, int age){ //필드를 전달받아 만드는 오버로드 된 생성자
        this.name = name; //초기화 this는 외부라는 변수에서 넘어온 값, 내가 가진 name이냐? 아니냐를 구분하기 위해
        this.age = age;
    }

to String


생성자를 이용하여 만들면 내가 모르는 언어로 출력돼서 오른쪽 마우스 해서 toString을 해주면 우리가 아는 언어로 출력됨

@Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\\'' +
                ", age=" + age +
                '}';
    } //오른쪽 마우스를 통해 toString을 클릭하여 만들어줌

클래스와 getter/setter와 생성자, toString, 모델 클래스 전체코드


public class Main {
    public static void main(String[] args) {
        System.out.println(add(50,10));
        System.out.println(add(40,10,12));

        System.out.println(add(10,12,13,14));

        Person person = new Person();
        Person person2 = new Person("홍길동", 10);

        System.out.println(person);
        System.out.println(person2);
    }

    public static int add(int x, int y){ //메서드 이름이 같다면 변수의 개수가 달라야 함
        return x+y;
    }

    public static int add(int x, int y,int z){
        return x+y+z;
    }

    public static int add(int... numbers){ //...은 0개이상의 숫자
        int sum = 0;
        for(int i =0; i < numbers.length; i++){
            sum = sum + i;
        }
        return sum;
    }
}

class Person{ //속성과 기능으로 나눠짐
    private String name;
    private int age;

    Person(){ //클래스와 이름이 같은 기본생성자

    }

    Person(String name, int age){ //필드를 전달받아 만드는 오버로드 된 생성자
        this.name = name; //초기화 this는 외부라는 변수에서 넘어온 값, 내가 가진 name이냐? 아니냐를 구분하기 위해
        this.age = age;
    }

    //private을 하는 대신 getter와 setter을 해줌
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\\'' +
                ", age=" + age +
                '}';
    } //오른쪽 마우스를 통해 toString을 클릭하여 만들어줌
}

패키지와 import


model 패키지에 Person.class를 넣어줌

package model;

public class Person{ //속성과 기능으로 나눠짐
    private String name;
    private int age;

    public Person(){ //public을 꼭 써줘야 함 안그러면 main에서 접근 불가

    }

    public Person(String name, int age){ 
        this.name = name; 
        this.age = age;
    }

    //private을 하는 대신 getter와 setter을 해줌
    public String getName() { //get은 값을 꺼내는 것
        return name;
    }

    public void setName(String name) { //set은 값을 넣는 것
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\\'' +
                ", age=" + age +
                '}';
    }
}

com.company 패키지 안에 Main 자바

package com.company;

import model.Person;

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

        Person person = new Person();
        Person person2 = new Person("홍길동", 10);

        System.out.println(person);
        System.out.println(person2);
    }
}

상속


자식(클래스)이 상속받고 싶은 부모(클래스)를 선택해서 물려받는다. 이때 상속받는 클래스를 자식 클래스, 하위 클래스 또는 서브 클래스 라고 부른다.

상속을 해주는 클래스를 부모 클래스, 상위 클래스 또는 슈퍼 클래스

  1. 상속 방법 : class 클래스(자식) extends 클래스(부모)

  2. 자식 클래스는 부모 클래스로부터 메소드와 필드를 물려받아 사용, 부모 클래스는 자식 클래스에서 정의한 메소드나 필드를 사용하지 못한다

  3. 자식 클래스는 여러 부모 클래스로부터 상속받지 못한다. 즉, 단일상속만 가능

  4. 부모 클래스는 여러 자식 클래스에게 상속이 가능

  5. 자식 클래스가 더 다양한 기능이 가능하므로 자식 클래스로 인스턴스를 생성하는 것이 효율적

hero.isFlying(); 
//get의 속성도 가지고 있고 boolean의 경우 is라는 이름으로 getter을 가짐

⇒ 이의 경우 어디서 알 수 있느냐? Hero의 getter를 보면 알 수 있음

💡 set = 설정, get = 값을 가져오는 것,

  • 돼지저금통을 만든다 > 변수 선언

  • 그 안에 돈을 저축한다 > set

  • 그 안에 돈이 얼마나 들어 있는지 본다 > get

  • 사용 이유 : SET, GET 메소드를 사용하는 이유는 외부로부터 변수값에 직접적으로 접근하는것을 막기 위해서다. 직접 접근하개 되면 값이 변하게 되고 그러면 데이터 무결성이 깨질 수 있기 때문이라고 함

추상클래스


추상 클래스는 문법보다는 무엇이고 왜 사용하는지 본질적인 개념을 알아야 함

🍀추상클래스란?

추상클래스는 A클래스, B클래스, C클래스들 간에 비슷한 필드와 메서드를 공통적으로 추출해 만들어진 클래스다.

실체클래스는 실체가 드러나는 클래스로 A클래스, B클래스, C클래스와 같은 것들이다.

추상클래스는 실체 클래스의 공통적인 부분을 추출해 어느정도 규격을 잡아놓은 추상적인 클래스, 그리고 실체클래스와는 상속관계

So, 실체클래스는 실제 객체를 생성할 정도의 구체성을 가진다. 하지만 추상클래스는 아직 메서드와 내용이 추상적이기 때문에 객체를 생성 불가

Charter charter = new Charter(); // Charter가 추상클래스인 경우 안됨!!!
  • 추상클래스는 클래스 앞에 abstract를 붙여주고 추상 필드나 메서드를 만든다!

  • {}없이 내용이 없기 떄문에 추상 메서드

public abstract class Character {
    //Magician 또한 싸움의 기능을 가지고 싶다는 전제에 캐릭터에 싸움의 기능을 강제화
    public abstract void attack(Hero hero);//{}없이 내용이 없기 떄문에 추상 메서드
}

추상 클래스를 상속하는 자식클래스의 경우 extends를 사용해서 추상클래스 상속

public class Magician extends Character {

    @Override
    public void attack(Hero hero) {
     //안에 내용을 적어줘야 함
    }
}

interface


추상클래스와 같은 역할

확장성유연성을 가짐, 다중상속 가능, 다형성

아래 두개는 같은 의미

public abstract class Character {
    //Magician 또한 싸움의 기능을 가지고 싶다는 전제에 캐릭터에 싸움의 기능을 강제화
    public abstract void attack(Hero hero);//{}없이 내용이 없기 떄문에 추상 메서드
}
interface Character{ //추살클래스와 똑같은 기능
    void attack(Hero hero);
}

but 추상클래스나 인터페이스 참조시

추상클래스 : extends 사용

public class Magician extends Character {

    @Override
    public void attack(Hero hero) {

    }
}

인터페이스 : implements 사용

public class Magician implements Character {

    @Override
    public void attack(Hero hero) {

    }
}

장점

ArrayList 사용시 여러가지 타입 사용가능

ArrayList<Character> characterArrayList = new ArrayList<>(); //<>안에 Charcter 대신 Magician 등 가능
        characterArrayList.add(magician);
        characterArrayList.add(magician2);
        characterArrayList.add(hero); //여러가지 타입을 담을 수 있다는 다형성

instanceof


참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위해 instanceof 연산자를 사용합니다. 주로 조건문에 사용

Magician.class

public class Magician extends Character implements ICharacter {

    @Override
    public void attack(Hero hero) {

    }

    @Override
    public void attack(Person person) {

    }
}

IChatacter 인터페이스

package model;

public interface ICharacter { //추살클래스와 똑같은 기능
    void attack(Person person);
}

Character.class

package model;

public abstract class Character extends Person{
    //Magician 또한 싸움의 기능을 가지고 싶다는 전제에 캐릭터에 싸움의 기능을 강제화
    public abstract void attack(Hero hero);//{}없이 내용이 없기 떄문에 추상 클래스
}

🍀 instanceof 사용처

  • 조상 참조변수 instanceof 자손 인스턴스 (무조건 O)

  • Object o instanceof 자손 인스턴스 (무조건 O)

  • 자손 참조변수 instanceof 조상 인스턴스 (가능함 O)

Magician magician = new Magician(); 
        Character magician2 = new Magician();
        ICharacter magician3 = new Magician();

        if(magician2 instanceof Magician){ //Magician인지 아닌지 체크하는 것이 instanceof

        }

제네릭


어떤 타입이 들어와도 된다의 의미

public class Main {
    public static void main(String[] args) {
        print("안녕");
        print(1);
        print(3L);
        print(true);
    }
    
    public static <T> void print(T type){ //어떤 타입이 들어와도 된다의 의미
        System.out.println(type);
    }
}

Thread(스레드)


여러가지 일을 동시에 할 때 사용

Runnable은 interface고, run은 추상메서드

public class Main {
    public static void main(String[] args) {
        System.out.println("1");

      new Thread(new Runnable() {
          @Override
          public void run() {
              for(int i = 0; i < 5; i++){ try {
                  Thread.sleep(1000); //1초후에
                  System.out.println(Thread.currentThread().getName() +":" + i);
              }
             catch (InterruptedException e){
                  e.printStackTrace();
              }
            }
              
          }
      }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i = 0; i < 5; i++){ try {
                    Thread.sleep(1000); //1초후에
                    System.out.println(Thread.currentThread().getName() +":" + i);
                }
                catch (InterruptedException e){
                    e.printStackTrace();
                }
                }
            }
        }).start();
        System.out.println("2");
    }
}

결과창

람다식


추상메서드가 1개이고 파라미터가 없을 때 사용 가능

위의 스레드에서 ctrl + shift + enter를 누르면 변경가능

new Thread(() -> {
          for(int i = 0; i < 5; i++){ try {
              Thread.sleep(1000); //1초후에
              System.out.println(Thread.currentThread().getName() +":" + i);
          }
         catch (InterruptedException e){
              e.printStackTrace();
          }
        }
      }).start();

느낌점 🤣


문법도 중요하지만 프레임워크의 이용도를 알면 문법을 크게 공부 안해도 될듯한 느낌

https://wikidocs.net/281 : 점프 투 자바

Last updated