본문 바로가기

멘토링

[Java] OOP 개념과 특징

대부분의 상용 시스템들 JAVA 언어로 만들어졌다. 무겁지만 응용이 뛰어남

 

Java 기본 구성 (클래스, 멤버변수, 메서드, 접근지정자, 인스턴스, 객체 정의와 생성)

더보기

1. 클래스

객체가 가지는 여러개의 속성들, 메서드(연산) 들로 구조를 정의

 

class 사람{

   속성 (입, 코, 눈)  // 멤버 변수

   연산 (~한다)       // 메서드

}

더보기

2. 멤버 변수

 객체의 속성 정의

 해당 객체가 가진 고유한 값

더보기

3. 메서드

 특정 작업을 수행하기 위한 명령문의 집합

 멤버 변수의 값이나 상태를 변경할 수 있는 명령

더보기

4. 접근지정자

 변수, 메서드에 누가 접근 할 수 있냐? (메서드를 외부에서 접근할 수 있는 범위 지정)

 

종류 접근범위 클래스 패키지 상속 전체
public 접근 제한 없음 (아무나 접근 가능) o o o o
protected 동일 패키지 (같은 폴더 안에) 와 상속받은 클래스 o o o  
default 동일 패키지 o o    
private 동일 클래스만 o      

 

더보기

5. 인스턴스 (객체)

 클래스 자체는 데이터 자체 (아직 아무 상호작용 안됨)

    ex) 붕어빵 틀 -> 클래스 / 틀에서 만들어진 붕어빵들 -> 인스턴스 

 실제로 메모리에 할당된 상태

더보기

6. 객체 정의와 생성

 - 정의 (구조, 아직 뭘 할 수 있는건 아님)

public calss Person{

  String name = "홍길동";

  int age = 40;

  public void setName(String n)

  {

      name  = n;

  }

  public void setAge (int i){

      age = 1;

  }

 

 - 생성 (이때부터 메모리에 올라가게 된다.)

 public static void main(String[] args) {

   Person p1 = new Person();

              // p1 이라는 인스턴스 생성

   p1.set_name("홍길동");

   p1.set_age(40);

}

}


객체지향 특징 (생성자, 예외처리, 상속, 메서드 오버라이딩, 메서드 오버로딩)

더보기

1. 생성자

  • 인스턴스가 만들어질 때, 초기값 등을 지정하는 역할
  • 생성자는 해당 클래스의 이름과 같아야 함.
  • 인자를 다르게 하여 여러 개를 가질 수 있다. -> 오버로딩

public calss Person{ 

  String name = "홍길동";

  int age = 40;

  

  public Person() {                  ----> 이게 생성자 (인자 없는 Default 생성자)

       this.name = "사람";

       this.age = 1;

  }

  public Person(String name, int age) {  ---> name과 age를 받아와서 정보를 넣는 생성자

       this.name = name;

       this.age = age;

  }

 

  public void toPrint(){              ------> 출력하라고 지시하는 메서드

       System.out.println(this.name + "님의 나이는" + this.age + "살입니다.");

  }

}

 

    public static void main(String[] args)

    {

        Person p1 = new Person();     ----> 인자 없는 Default 생성자 호출

        p1.toPrint();  // 사람님의 나이는 1살입니다.  --> 공유 메서드

    

        Person p2 = new Person("이순신", 40);       ------> 인자 name, age가 있는 생성자 호출

        p2.toPrint();  // 이순신님의 나이는 40살입니다.  --> 공유 메서드

     }

}

더보기

2. 예외처리

  • 프로그램 실행 중에 발생하는 예외를 처리해주는 방법
  • 예외 상황 발생 -> 프로그램을 자연스럽게 종료 처리
  • syntax error(문법 오류) 와는 전혀 관계없음. 

   try{ } catch ( ) { } catch() { } finally{ }  --> catch는 여러번 사용 가능

   try : 예외 발생 가능성 있는 모든 코드들 정리 (접속 오류, ...)

   

   catch : 수행 중 해당 예외를 만나면 해당 중괄호안의 코드로 빠짐

        catch(ArithmeticException e) --> 산술계산 오류 발생시 실행

        catch(Exception e)  --> 최상위 예외, 모든 오류 발생시 실행

   

   finally : 마지막에 예외를 만나든 안만나든 무조건 수행되어야 함. (안써도 된다.) - 자원 정리나 연결 종료에 많이 쓰임

       ex) 파일을 열었으면 마지막에는 무조건 닫아야 함.

더보기

3. 상속 (Inheritance)

  • 부모클래스의 멤버를 자식클래스에서 그대로 쓸 수 있음
  • 클래스 재사용 가능 -> 효율, 개발기간 단축
  • 부모의 private 한 멤버는 상속 불가능 (private은 내 클래스 안에서만 사용할수 있기 때문)
  • extends 라는 키워드 사용
  • class C extends P // JAVA는 단일 상속만 지원한다. class C extends P, A (x)

calss Parent { 

  String name;

  int age;  

  public void set_name(String param_n) {    

       name = param_n;

  }

  public void set_age(int param_i) {    

       age= param_i;

  }

}

 

class Child extends Parent {

    int height;

    public void set_height (int param_h) {

           height = param_h;

    }

}

 

public static void main (Stirng[] args) {

    Child c = new Child();

    c.set_name("홍길동");  // print 결과 홍길동       ----> 부모로부터 물려받은 메서드

    c.set_age(40);             // print 결과 40             -----> 부모로부터 물려받은 메서드

    c.set_height(170);       // print 결과 170           -----> 내 클래스(Child)에서 정의된 메서드

}

더보기

4. 메서드 오버라이딩

  • 상속 관계에서(만 존재하는 개념) 부모 클래스에서 물려받은 메서드를 다시 재정의
  • 추상 클래스나 인터페이스를 상속 받을 때 사용되는 개념
     ->  ex) A 공장이 있는데 리모컨의 버튼 세 개의 틀을 짰다. (부모클래스)
                 TV에 맞게, 라디오에 맞게, 에어컨에 맞게 쓰려면 구조는 같을지라도 각각의 기능은 달라야 한다.                 
  • 부모 메서드의 이름, 리턴 타입, 매개변수의 개수와 유형이 완전히 동일해야 함.

calss Parent { 

  public void set_name(String param_n) {    

       System.out.println("부모의 이름 변경");

  }

  public void set_age(int param_i) {    

        System.out.println("부모의 나이 변경");

  }

}

 

calss Child extends Parent{ 

  public void set_name(String param_n) {    

       System.out.println("자식의 이름 변경");  --> 부모의 메서드에 있었던 기능 재정의
                                                                          원래 기능은 System.out.println("부모의 이름 변경"); 이었다.

  }

  public void set_height (int param_i) {    

       System.out.println("자식의 키 변경");

  }

}

 

   public static void main(String[] args) {

       Child c = new Child();

       c.set_name("홍길동");   // 자식의 이름 변경   ----> 부모가 가지고 있는걸 자식 클래스에서 오버라이딩 했다.

       c.set_age(40); // 부모의 나이 변경                -----> 부모만 가지고 있다. (자식은 그대로 쓴다.)

       c.set_height(170);  // 자식의 키 변경             -----> 자식만 가지고 있다.

   }

}

더보기

5. 메서드 오버로딩

  다형성 - 오버라이딩, 오버로딩

  • 같은 이름의 메서드를 인자만 다르게 하여 중복 정의
  • 메서드의 이름이 같아야하고, 인자의 개수나 타입이 달라야함.

calss Person { 

  String name;

  int age;

  int height;  

  public void set_data(String p_name) {    

       name = p_name ;

  }

  public void set_data( String p_name , int p_age) {    

       name = p_name;

       age = p_age;

  }

}

 

public static void main(String[] args) {

       Person p1 = new Person();

       p1.set_data("홍길동");  --> 첫번째 set_data 함수를 가져옴

       

       Person p2 = new Person();

       p2.set_data("홍길동", 40); --> 두번째 set_data 함수를 가져옴.

   }

}

// 멤버마다 변수값을 따로 갖고 있다. p1의 name, age, height 가 있는거고, p2의 name, age, height가 있는것

추상클래스와 인터페이스

더보기

1. 추상클래스

  • 반드시 오버라이딩해서 사용할 미완성의 메서드를 하나 이상 가진 미완성 클래스
  • 추상클래스를 상속받은 자식 클래스에서 추상 메서드를 구현해서 사용
    ex) 리모컨 버튼 세개 중 하나는 기능이 완전 똑같다. (전원 off, on)
          나머지 버튼 두개는 TV, 라디오, 에어컨에 맞게 알아서 구현해라
    ------------------------------------------------------------------------------------
    인터페이스와 차이점 : 리모컨 버튼 세 개 모두 기능 구현 x, 전부 원형의 상태
     추상클래스는 상속을 한다고 하고, 인터페이스는 '구현' 을 한다고 한다. (아무것도 생성되어있지 않기 때문에)
  • 객체 생성 못한다. -> 미완성이기에 new ~ 로 메모리에 올릴수가 없음.

abstract calss Remote{ 

  public int volume = 10;

  public int channel = 1;

  public void volume_up() {     ---> 볼륨 올라가는것 구현됨.

        this.volume++;

  }

  abstract void channel_change(int i);     ----> 추상메서드, { } 가없다.  { } 안에 코드가 들어가버리면 구현이 된거다.
                                                                        이걸 상속받을 시 이부분은 구현을 해야 사용 가능함.

}

 

class TV_Remote extends Remote{

     void channel_change(int i) {

          channel = i;

     }

}

 

public static void main(String[] args) {

       TV_Remote tv = new TV_Remote();

       tv.volume_up();   //부모 클래스인 Remote에서 가져온 함수

       tv.volume_up();  //부모 클래스인 Remote에서 가져온 함수

       System.out.println("볼륨:"+tv.volume);  //볼륨 : 12

       tv. channel_change(5);  // 상속 받은 추상 메서드를 정의했기 때문에 자식에서 쓸 수 있는 메서드가 되었다.

       System.out.println("채널:"+tv.channel);  //채널 : 5

   }

}

더보기

2. 인터페이스

  • 추상클래스의 극단으로 모든 메서드가 추상적인 형태이다. (즉, 아무것도 구현하면 안됌)

interface Remote{           ----> 중괄호{} 있으면 에러 발생, 아아무것도 구현하지 마라.

   public void volume_up();

   public void channel_change(int i);

}

class TV_Remote implements Remote{

   public int volume = 10;

   public int channel = 1;

   public void channel_change(int i){

      this channel = i;

   }

   public void volume_up() { 

        this.volume++;

    }

}

implements --> 두 메서드 모두 구현해야 한다.

 

main은 생략한다.

https://youtu.be/vEi-qgeIaRs?si=FkGzB9ox153OT4Tu