관리 메뉴

IT journey

JAVA - 클래스 본문

개인공부공간/JAVA

JAVA - 클래스

step 2021. 6. 8. 22:22
728x90
반응형

직접 내용 정리하고 만든 예이니 퍼가실 때는 출처를 남겨주세요 :)

클래스

○객체를 만드는 기능을 합니다.

○ 클래스는 객체의 틀이 되는 추상적인 개념이고 객체는 클래스에 정의된 요소들의 실체입니다.

○ 흔히 클래스는 붕어빵틀로, 객체는 붕어빵으로 생각합니다.

○ 예

public class Zoo{
  String name; //객체 변수
  int age;
  String feed;

  public void setName(String name){ //메소드
    this.name= name;
  }
  public void setAge(int age){ 
    this.age = age;
  }

  public static void main(String[] args){
    Zoo monkey = new Zoo(); //monkey는 객체(=monkey는 Zoo의 객체) 생성
    monkey.setName("원숭이"); //메소드 호출
    monkey.setAge(20);
    
    Zoo turtle = new Zoo();
    turtle.setName("거북이");
    turtle.setAge(200);

    System.out.println("저는 "+monkey.name+"이고 나이는 "+monkey.age+"살입니다");
    System.out.println("저는 "+turtle.name+"이고 나이는 "+turtle.age+"살입니다");
    }
}

○ 객체 변수

    • 클래스에 선언된 변수를 말합니다.
    • 인스턴스(멤버) 변수, 속성이라고도 부릅니다.
    • 이를 출력하기 위해서는 객체.객체변수를 이용해야 합니다.
    • 위 예에서의 객체변수는 setName,setAge입니다.
    • 공유되지 않습니다. (즉, 독립적입니다.) 이를 통해 자바가 객체 지향 프로그래밍 언어라는 것을 알 수 있습니다.
    • 참고로, 객체 지향 프로그래밍 언어에 대해서 알고 싶으신 분들은 클래스 1편 에서 봐주시길 부탁드립니다.

○  메소드

  • 클래스 내에 구현된 함수를 말합니다.
  • 호출할 떄는 객체.메소드로 호출
  • 메소드의 구조 4가지
//기본 구조
//리턴자료형이 void인 경우에는 return문 생략 가능
public 리턴자료형 메소드명(입력자료형1 입력변수1, 입력자료형2, 입력변수2,...){
	...
    return 리턴값;
}

// 입력과 출력이 모두 있는 메소드
public class Main{
    public int subtract(int a,int b){
        return a-b;
    }
    
    public static void main(String[] args){
        int a = 10;
        int b = 5;
        Main inout = new Main();
        int c = inout.subtract(a,b); //리턴값받을변수 = 객체.메소드명(입력변수1,입력변수2,...)
        
        System.out.printf("%d-%d은 %d입니다.",a,b,c);
    }
}
// 입력과 출력이 모두 없는 메소드
public class Main{
    public void Option(){
        System.out.println("1.Python,2.C,3.JAVA,4.DBMS,5.C#,6.R");
    }
    
    public static void main(String[] args){
        Main no = new Main();
        no.Option(); //객체.메소드명()
    }
}
// 입력은 없고 출력은 있는 메소드
public class Main{
    public String Here (){
        return "IT journey";
    }
    
    public static void main(String[] args){
        Main out1 = new Main();
        String here = out1.Here(); // 리턴값받을변수 = 객체.메소드명()
        System.out.println(here);
    }
}
// 입력은 있고 출력은 없는 메소드
public class Main{
    public void subtract(int a,int b){
        System.out.printf("%d-%d는 %d입니다.",a,b,a-b); 
    }
    
    public static void main(String[] args){
        Main in1 = new Main();
        in1.subtract(25,20); //객체.메소드명(입력인수1,입력인수2,...)
    }
}
  • 위에 나온 클래스의 예의 경우 입력값은 setName과 setAge로, 출력값은 void로 리턴값이 없는 상태입니다.
  • return은 리턴 자료형이 void형인 메소드의 특정 조건에 따라 메소드를 즉시 빠져자가고 싶을 경우에 return 값을 씁니다.
  • 메소드 내에서만 쓰이는 변수를 로컬 변수로 불리며, 이는 메소드 밖 변수이름과 상관없습니다. 반면 객체의 경우에는 메소드 밖 객체와 상관있으니 주의해야 합니다.

상속

○ 자식 클래스가 부모클래스를 물려받는 것을 말합니다. (즉, 자식 클래스는 부모클래스의 하위개념이라고 봅니다.) 이런 경우에는 자식클래스는 부모클래스이다(자식클래스 is a 부코클래스)라고 표현할 수 있습니다. 

○ extends라는 키워드를 사용하여 클래스를 상속합니다.

○ 예

//부모클래스(Zoo.java)
public class Zoo{
  String name;
  int age;

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

  public static void main(String[] args){
  }
}

//자식클래스(MainZoo.java)
public class MainZoo extends Zoo{
  public void Feed(){
    System.out.println(this.name+" 바나나 먹이기");
  }
  public static void main(String[] args){
    MainZoo monkey = new MainZoo();
    monkey.setName("원숭이");
    monkey.setAge(20);

    System.out.println("저는 "+monkey.name+"를 맡았고 그의 나이는 "+monkey.age+"살입니다.");
    monkey.Feed();
  }
}

○ 메소드 오버라이딩

[예]

//Zoo.java
public class Zoo{
  String name;
  int age;

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

  public static void main(String[] args){
  }
}

//MainZoo.java
public class MainZoo extends Zoo{
  public void Feed(){
    System.out.println(this.name+" 바나나 먹이기");
  }
  public static void main(String[] args){
  }
}

//Zookeeper.java
public class Zookeeper extends MainZoo{
  public void Feed(){
    System.out.println(this.name+"에게 바나나껍질 까서 먹이기");
  }
  public static void main(String[] args){
    Zookeeper monkey = new Zookeeper();
    monkey.setName("원숭이");
    monkey.setAge(20);
    monkey.Feed();

  }
}

간략히 메소드 오버라이딩의 예에 대해 설명해보겠습니다.

Zookeeper 클래스에 MainZoo 클래스와 입출력이 동일한 형태의 Feed 메소드를 구현한 메소드 오버라이딩의 한 예로, Zookeeper 클래스의 Feed 메소드가 MainZoo 클래스의 Feed 메소드보다 더 높은 우선순위를 가지므로 Zookeeper 클래스의 Feed 메소드가 호출됩니다.

이처럼 부모클래스의 메소드를 자식클래스가 동일한 형태로 또 다시 구현하는 행위를 메소드 오버라이딩이라고 부릅니다. 쉽게 말해, 자식 클래스인 Zookeeper가 메소드 덮어쓰기를 했다고 생각하면 됩니다.

 메소드 오버로딩

Zookeeper 클래스에 입력항목이 다른 동일한 Feed라는 메소드를 만든 것을 메소드 오버로딩이라고 부릅니다.

[예]

//Zoo.java
public class Zoo{
  String name;
  int age;

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

  public static void main(String[] args){
  }
}

//MainZoo.java
public class MainZoo extends Zoo{
  public void Feed(){
    System.out.println(this.name+" 바나나 먹이기");
  }
  public static void main(String[] args){
  }
}

//Zookeeper.java
public class Main extends MainZoo{
  public void Feed(){
    System.out.println(this.name+"에게 바나나껍질 까서 먹이기");
  }
  public void Feed(int number){
    System.out.println(this.name+"에게"+number+" 개의 바나나 껍질 까서 먹이기");
  }
  public static void main(String[] args){
    Zookeeper monkey = new Zookeeper();
    monkey.setName("원숭이");
    monkey.setAge(20);
    monkey.Feed(); //Feed() 메소드 호출
    monkey.Feed(2); //Feed(int number) 메소드 호출

  }
}

 

생성자

  • 메소드명이 클래스명과 동일하고 리턴 자료형이 없는 메소드를 말합니다.
  • 생성자는 객체가 생성될 때는 new라는 키워드로 사용될 때 호출됩니다.
//Zoo.java
public class Zoo{
  String name;
  int age;

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

  public static void main(String[] args){
  }
}

//MainZoo.java
public class MainZoo extends Zoo{
  public void Feed(){
    System.out.println(this.name+" 바나나 먹이기");
  }
  public static void main(String[] args){
  }
}

//Zookeeper.java
public class Zookeeper extends MainZoo{
  public Zookeeper(String name){ // 생성자
    this.setName(name);
  }
  public void Feed(){
    System.out.println(this.name+"에게 바나나껍질 까서 먹이기");
  }
  public void Feed(int number){
    System.out.println(this.name+"에게"+number+" 개의 바나나 껍질 까서 먹이기");
  }
  public static void main(String[] args){
    Zookeeper monkey = new Zookeeper("원숭이"); //생성자 호출
    System.out.println(monkey.name);
  }
}
  • 클래스에 생성자가 하나도 없다면, 자동으로 default 생성자를 추가합니다. 하지만 사용자가 작성한 생성자가 하나라도 구현되어 있다면 자동으로 디폴트 생성자를 추가하지 않습니다.

참고로, 하나의 클래스에 여러 개의 입력항목이 다른 생성자를 만들 수 있습니다. 그에 대한 예는 아래와 같습니다.

//Zoo.java
public class Zoo{
  String name;
  int age;

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

  public static void main(String[] args){
  }
}

//MainZoo.java
public class MainZoo extends Zoo{
  public void Feed(){
    System.out.println(this.name+" 바나나 먹이기");
  }
  public static void main(String[] args){
  }
}

//Zookeeper.java
public class Zookeeper extends MainZoo{
  public Zookeeper(String name){
    this.setName(name);
  }
  public Zookeeper(int number){
    if (number==1){
      this.setName("몽키");
    }else if(number==2){
      this.setName("원숭이");
    }
  }
  public void Feed(){
    System.out.println(this.name+"에게 바나나껍질 까서 먹이기");
  }
  public void Feed(int number){
    System.out.println(this.name+"에게"+number+" 개의 바나나 껍질 까서 먹이기");
  }
  public static void main(String[] args){
    Zookeeper monkey = new Zookeeper("원숭이");
    Zookeeper 몽키 = new Zookeeper(1);
    System.out.println(monkey.name);
    System.out.println(몽키.name);
  }
}

Zookeeper 클래스에는 두 개의 생성자가 있습니다. 하나는 String 자료형을 입력으로 받는 생성자 name이고 다른 하나는 int 자료형을 입력으로 받는 생성자입니다. 이 생성자들의 차이는 입력 항목입니다. 이처럼 입력 항목이 다른 생성자를 여러 개 만들 수 있는데 이것을 생성자 오버로딩이라고 부릅니다.

 

인터페이스

○ 예

//Zoo.java
public class Zoo{
  int age;

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

  public static void main(String[] args){
  }
}

//Predator.java
public interface Predator{
  public String getName();

  public static void main(String[] args){
  }
}

//Turtle.java 
public class Turtle extends Zoo implements Predator{
  public String getName(){
    return "거북이";
  }

  public static void main(String[] args){
  }
}
//turtle - Turtle 클래스의 객체, Predator 인터페이스의 객체

//Monkey.java
public class Monkey extends Zoo implements Predator{
  public String getName(){
    return "원숭이";
  }

  public static void main(String[] args){
  }
}
////monkey - Monkey 클래스의 객체, Predator 인터페이스의 객체

//Moderator.java
public class Moderator{
  public void Animal(Predator predator){
    System.out.println("이 동물의 이름은 "+predator.getName());
  }

  public static void main(String[] args){
    Moderator moderator = new Moderator();
    Monkey monkey = new Monkey();
    Turtle turtle = new Turtle();
    moderator.Animal(monkey);
    moderator.Animal(turtle);
  }
}

 

Moderator 클래스가 새로운 동물이 올 때 마다 동물 이름을 짓게되는 코드를 짜게되면 중복된 코드로 가득차게 될 것입니다. 중복된 코드를 없애기 위해 interface라는 키워드를 이용하여 인터페이스를 쓰기 시작합니다. 구현할 때는 implements라는 키워들 사용합니다. 그렇게 되면 Moderator는 독립적인 클래스로 사용할 수 있게 됩니다.

다형성

○ 하나의 객체가 여러 개의 자료형 타입을 가질 수 있는 것을 말합니다.

○ 일반 클래스는 단일 상속만 가능하지만, 인터페이스는 다중 상속이 가능합니다.

  예

//Zoo.java
public class Zoo{
  int age;

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

  public static void main(String[] args){
  }
}

//Predator.java
public interface Predator{
  public String getName();

  public static void main(String[] args){
  }
}

//Feedable.java
public interface Feedable{
  public void feed();

  public static void main(String[] args){

  }
}

//Turtle.java
public class Turtle extends Zoo implements Predator,Feedable{
  public String getName(){
    return "거북이";
  }

  public void feed(){
    System.out.println("잡식입니다.");
  }
  public static void main(String[] args){
  }
}

//Monkey.java
public class Monkey extends Zoo implements Predator,Feedable{
  public String getName(){
    return "원숭이";
  }
  public void feed(){
    System.out.println("바나나 좋아합니다");
  }
  
  public static void main(String[] args){

  }
}

//FeedablePredator.java
public interface FeedablePredator extends Feedable,Predator{

  public static void main(String[] args){

  }
}

//Main.java
public class Main{
  public void FeedZoo(Feedable feedable){
    feedable.feed();
  }

  public static void main(String[] args){
    Monkey monkey = new Monkey();
    Turtle turtle = new Turtle();

    Main main = new Main();
    main.FeedZoo(monkey);
    main.FeedZoo(turtle);
  }
}

 

추상클래스

○ 위의 예를 추상클래스로 변경한 예는 아래와 같습니다.

○ 추상클래스로 만들기 위해서는 class 앞에 키워드 abstract를 표기해야 합니다.

//Zoo.java
public class Zoo{
  int age;

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

  public static void main(String[] args){
  }
}

//Predator.java
public abstract class Predator extends Zoo{
  public abstract String getName();

//Predator 추상클래스에 추가하면 이 클래스를 상속받은 Turtle,Monkey도 사용가능합니다.
  public boolean isPredator(){
    return true;
  }
  public static void main(String[] args){
  }
}

//Feedable.java
public interface Feedable{
  public void feed();

  public static void main(String[] args){

  }
}

//Turtle.java
public class Turtle extends Predator implements Feedable{
  public String getName(){
    return "거북이";
  }

  public void feed(){
    System.out.println("잡식입니다.");
  }
  public static void main(String[] args){
  }
}

//Monkey.java
public class Monkey extends Predator implements Feedable{
  public String getName(){
    return "원숭이";
  }
  public void feed(){
    System.out.println("바나나 좋아합니다");
  }
  
  public static void main(String[] args){

  }
}

//FeedablePredator.java
public interface FeedablePredator extends Feedable{

  public static void main(String[] args){

  }
}

//Main.java
public class Main{
  public void FeedZoo(Feedable feedable){
    feedable.feed();
  }

  public static void main(String[] args){
    Monkey monkey = new Monkey();
    Turtle turtle = new Turtle();

    Main main = new Main();
    main.FeedZoo(monkey);
    main.FeedZoo(turtle);
  }
}

○ 인터페이스의 메소드와 같은 역할을 하는 메소드(getName 메소드)에 abstract를 붙여야 합니다. 

쉽게 말해, abstract 클래스를 상속하는 클래스에서 해당 abstrac 메소드를 구현해야한다는 의미입니다.

패키지

패키지란, 비슷한 성격을 가진 자바 클래스를 모아 놓은 디렉터리(파일)라고 생각하면 됩니다. 

그러므로 B라는 패키지에서 A라는 패키지를 쓰고 싶을 경우에는 import 패키지명 *;를 써주면 됩니다.

접근 제어자

private -> default -> protected -> public 순으로 많은 접근을 허용합니다.

1. private

private이 붙은 변수, 메소드는 현재 클래스 외부에서는 접근할 수 없습니다. 해당 클래스 내에서만 접근할 수 있습니다. 다시 말해, 상속이 불가능합니다.

2. default

접근제어자를 별도로 설정하지 않을 경우 변수, 메소드가 default가 되어 해당 패키지에서만 접근이 가능합니다.

3. protected

protected가 붙은 변수,  메소드는 동일 패키지 내의 클래스와 해당 클래스를 상속받은 자식 클래스만 접근가능합니다. 다시 말해, 상속이 가능합니다.

4. public

아무곳에서나 자유롭게 사용이 가능합니다. 다시 말해, 상속이 가능합니다.

 


예외 처리하기

//기본 구조
try{
   ...
}catch(예외 1){
   ...
}catch(예외 2){
   ...
...
}finally{ //반드시 실행해야할 경우만 실행되니 생략해도 됩니다.
  ...
}

//사용한 예
import java.io.BufferedReader; 
import java.io.FileReader; 
import java.io.IOException; 
public class Main{ 
  public void execute(){
    System.out.println("반드시 출력될 문장입니다");
  }

  public static void main(String[] args) throws IOException{ 
    Main main = new Main();
    try{
      BufferedReader br = new BufferedReader(new FileReader("example.txt"));
      while(true){ 
        String line = br.readLine(); 
        if(line == null) 
          break;
        System.out.println(line); 
      } 
      br.close(); 
      }catch(Exception e){
        BufferedReader br = new BufferedReader(new FileReader("example.txt"));
      }finally{
        main.execute();
      } 
    }
}

예외 발생시키기

//slashesException.java
public class slashesException extends RuntimeException{
    public static void main(String[] args){
    }
}

//Main.java
public class Main{
  public void ID(String id){
    if("//".equals(id)){
      throw new slashesException();
    }
    System.out.println("아이디는 "+id+"입니다");
  }
  public static void main(String[] args){
    Main main = new Main();
    main.ID("//");
    main.ID("step");
  }
}

예외 던지기

//slashesException.java
public class slashesException extends RuntimeException{
    public static void main(String[] args){
    }
}

// Main.java
public class Main{
  public void ID(String id){
    if("//".equals(id)){
      throw new slashesException();
    }
    System.out.println("아이디는 "+id+"입니다");
  }
  public static void main(String[] args){
    Main main = new Main();
    try{
      main.ID("//");
      main.ID("step");
    }catch(slashesException e) {
      System.err.println("slashesException이 발생합니다");
    }
  }
}

 


이전 발행 글

JAVA-제어문(feat.파일 입출력)

JAVA-자료형

728x90
반응형

'개인공부공간 > JAVA' 카테고리의 다른 글

JAVA-제어문(feat.파일 입출력)  (4) 2021.06.07
JAVA-자료형  (10) 2021.06.05
Comments