Java_OOP1

ChoRong0824·2023년 5월 8일
0

Java

목록 보기
15/31
post-thumbnail

Java_OOP1
클래스, (게더,세터), 상속, 오버라이딩, 반복문 포스팅할 예정입니다.
문제 위주로 정리했습니다.
각 문제를 풀어보시고, 테스트해보시면 좋을 것 같습니다.

클래스란 무엇이고, 어떤 역할을 하는지 설명

  • 필요한 이유

    여러사람이 협업을 하는 과정에서 좀더 체계적이고, 분업화된 시스템으로 개발하기 위해 필요합니다.

  • 클래스란 ?
    -> 만들고자 하는 객체 특징,동작 -> (속성,기능) 을 설계
    객체(또는 인스턴스)를 생성하는 하나의 공장(=틀, 주문서)
    즉, 클래스는 마트이고, 객체는 각 상품들이다. 각 상품들은 속성과 데이터를 가진다.

  • 객체는 어떻게 만들지 ?
    원하는 속성과 기능을 생각하고 구현
    객체의 특징 --> 속성
    객체의 동작 --> 메서드 = 함수


FarmMachine의 속성과 동작들을 가지는 클래스를 코드로 구현하고 객체를 생성하여 동작

  • 출력을 보고 구현
1000000 // 가격
2020	// 년식
red		// 색상
Farm-machine is moving.
Fram-machine is digging.
Fram-machine is grinding.
  • 정답
class FarmMachine{
    // 속성
    int price;  //가격
    int date;   //연식
    String color;   //색상

    // 기능/동작/행동(메서드)
    // 메서드는 여러가지로 구현(구성)될 수 있음.
    void move(){
        System.out.println("FarmMachine is moving");
    }
    void dig(){
        System.out.println("FarmMachine is digging");
    }
    void grind(){
        System.out.println("FarmMachine is grinding");
    }
}
public class Main{
    public static void main(String[] args)  {
        // 객체 생성
        FarmMachine fm = new FarmMachine(); // new 키워드가 클래스의 주소를 반환하는 역할 해줌 (객체는 참조형타입)
        System.out.println(fm);

        // 생성된 객체에 속성 값 입력
        fm.price = 1000000000;
        fm.date = 2023;
        fm.color = "red";

        // 속성 값 출력
        System.out.println(fm.price);
        System.out.println(fm.date);
        System.out.println(fm.color);

        // 동작 수행하기
        fm.move(); // 호출
        fm.dig();
        fm.grind();
    }
}

천 단위 콤마찍기

1000000000원을 가진 변수를 천단위로 콤마를 찍어서 출력

  • 1번
String fm_price = String.format("%,d",1000000000);
System.out.println(fm_price);
  • 2번, 바로찍기 (필자가 추천하는 방법)
System.out.println(String.format("%,d",fm.price);
문제속에 문제, 자료형 타입이 double형인 경우 어떻게 해야하는지 ?
  • 3번, java.text.DecimalFormat 클래스 활용

    쉼표를 찍는다는건 int형을 string으로 바꾸겠다는 것입니다.
    이유 : 콤마( , )는 문자열이기 때문에 String타입에 저장해야 하기때문입니다.
    int형 숫자를 ###,### 포맷에 맞춰 문자열로 바꿔주는 함수를 만들어놓고 필요할때마다, 사용하는 것입니다.

	// 숫자-> 천단위 콤마 찍기
	public String Comma(int input) {
		DecimalFormat df = new DecimalFormat("###,###");
		String input_str = df.format(input);
		return input_str;
	}

문자열을 숫자로 바꿔서 연산

// 이때, 인자값으로 진수를 지정해서 출력
문자열을 숫자로 변환 시키는 방법 -- > Integer.parseInt() 사용
parseInt() --> Integer 클래스의 static으로 지정되어있음 --> 객체의 생성없이 바로 "클래스명.parseInt()"로 직접 호출해서 사용 가능

두 번째 인자 값으로 진수를 지정

-> 해당 진수에 맞는 값이 됨.
Integer.parseInt("1000", 2); --> 1000에 2진수로 지정한거임 --> 콘솔창에는 10진수 숫자를 출력하게해줌.
즉, 2번째 인자값에 진수를 입력하는거임.

System.out.println(Integer.parseInt("A",16));
System.out.println(Integer.parseInt("D",16));
System.out.println(Integer.parseInt("FF",16));

결과 값은 ?

10 , 13 , 255

출력보고 구현하기

1+2=3
1 + 2 = 12 -------------------------[진수 지정] 2022
2022
1
9
516
10
15
255
-------------------------[진수 지정]
정답 코드
public class Main{
    public static void main(String[] args) {

        int a =1;
        int b =2;
        int c = a + b;
        System.out.println("`a+b =" + c);

        // 2, 문자열끼리 연산
        String a1 = "1";
        String b1 = "2";
        String c1 = a1 + b1;
        System.out.println("a1+b1=" + c);
        // 문자열 끼리 연산은 바로 뒤에 붙어버림.

        // 클래스 타입 확인
        System.out.println(c1.getClass().getName());

        // 3, 문자열 --> 숫자로 변환 후 연산
        int a2 = Integer.parseInt(a1);
        int b2 = Integer.parseInt(b1);
        int c2 = Integer.parseInt(c1);
        System.out.println(a1); // 1
        System.out.println(b1); // 2
        System.out.println(a2+b2); // 3
        System.out.println("-----------진수 지정 ");
        System.out.println(Integer.parseInt("2022"));
        System.out.println(Integer.parseInt("2022", 10)); // 출력 값은 당연히 10진수로 보여지게 됨.
        System.out.println(Integer.parseInt("1", 2));
        System.out.println(Integer.parseInt("1001", 2)); // 문제속의 문제, 무엇이 출력될까 ?
        System.out.println(Integer.parseInt("1004", 8)); // 문제속의 문제, 무엇이 출력될까 ?
        System.out.println(Integer.parseInt("A",16)); // 문제속의 문제, 무엇이 출력될까 ?
        System.out.println(Integer.parseInt("D",16)); // 문제속의 문제, 무엇이 출력될까 ?
        System.out.println(Integer.parseInt("FF",16)); // 문제속의 문제, 무엇이 출력될까 ?
        System.out.println("-----------진수 지정 ");
    }
}


클래스 작성시 주의할 사항으로 틀린 것들은?

(1) 하나의 파일에 2개 이상의 클래스를 작성할 수 있다.
(2) 3개의 클래스가 있다면 자바 파일명이 될 수 있는 것은 public 키워드가 붙은 클래스이다.
(3) 하나의 파일에 있는 3개의 클래스에 모두 public 키워드를 붙일 수 있다.
(4) 한 파일내 3개 이상의 클래스에 모두 public 키워드를 안붙일 수 있다.
(5) 한 파일내 3개 이상의 클래스에 모두 public 키워드가 없다면 클래스중 어느 것이라도 파일명이 될 수 있다.
(6) 자바 파일에 클래스가 한개 있다면 클래스명이 곧 파일명이 되어야 한다.

정답 : 1,2,4,5,6번은 맞는 대답, 3번만 틀렸습니다.
  • 2번 예시

    파일명은, public 키워드가 붙은 클래스입니다. (아니면 위 사진처럼 에러뜸)

클래스에서 생성자란 무엇이고 어떤 특징

생성자란

  • new 키워드로 클래스의 객체(또는 인스턴스)가 생성될 때, 제일 먼저 자동적으로 호출되는 특별한 메서드
  • 따라서, 객체의 초기값을 설정하는 등의 용도로 많이 사용됩니다.
  • 자바에서는 생성자명은 클래스명과 동일하게 만듭니다.
  • 생성자는 리턴되는 반환 값이 없습니다. (호출만 가능) --> 객체가 생성될 때, 제일 먼저 호출만 가능
  • 생성자는 오버로딩이 가능
  • 생성자는 default 생성자 존재 --> 클래스 내에 생성자가 없다면 default 생성자가 자동 호출됨 --> 클래스명과 동일하고, 받는 인자값은 x

생성자 위치

  • 보통, 속성과 메서드 사이에 기술합니다.
  • 생성자도 메서드이므로, 메서드 그룹에 속하는데 제일 상단에 보통 위치합니다.

예시

class Person{
	// [1] : 속성 
    int age;
    String name;
    
    // [2] : 생성자
    Person(){  // 객체 생성시 자동으로 호출됨. (인자값=파라미터 없는 생성자)
    }
    
    // [3] : 메서드
    void move(){
    	System.out.print("Perosn is Move");
    }
}

객체 생성시 초깃값을 생성자 메서드에서 설정하는 클래스를 구현

  • 생성자의 차이는 파라미터(인자값)을 주문서로 생각하면 이해하기 쉬움.
    파라미터를 보고 구분해서 알맞은 생성자에 넣을 수 있음.
    즉, 객체가 생성될 때(예_ 공장에 주문서 넣을때) 구분되기 때문에, 생성자가 많아도 구분이 가능함

출력

나이 : 20, 이름 : 홍길동
나이 : 30, 이름 : 이순신
나이 : 40, 이름 : 을지문덕

코드

class Person{
    // 1. 속성
    int age;
    String name;
    // 2. 생성자
    Person(){}// 클래스명과 동일하게
    Person(int age,String name){ // 받는 인자값이 있음, 반환 값만 없음. 인자값은 마음대로 받을 수 있음
        this.age = age;
        this.name = name; // this 는 생성된 각 객체의 자기 자신(객체)을 가리킴 -> 이유 : 편하게 값을 넣기 위해서.
    }
    // 3. 메서드
    void printPerson(){
        System.out.println("name : " + name + "\t   age :  "+ age );
    }
}

public class Main{
    public static void main(String[] args) {
        // 객체 생성
        new Person();
        Person p1 = new Person(20, "홍길동"); // new 는 주소를 생성하고, 그 주소 값을 반환하는 것 까지가 하는 역할임
        System.out.println(p1); // 주소값 출력
        p1.printPerson();

        Person p2 = new Person(30, "이순신");
        p2.printPerson();

        Person p3 = new Person(40, "권율");
        p3.printPerson();
    }
}
  • 각객체가 가리키는 주소 느낌 (그림참고)

클래스에서 상속이란 무엇인지, 상속의 정의와 특징

상속이란 ?

  • 부모 클래스가 가지고 있는 속성(변수)들과 동작/기능 (메서드)들을 그대로 물려받아 새로운 클래스를 만드는 것.
  • 상속을 활용하면, 물렵다은 것들은 그대로 쓰면되고, 거기에 덧붙여 새로운 것만 만들면 되므로 그만큼 노력과 시간이 save됨.
  • 물려받게 되는 원본 클래스를 부모 || 슈퍼 클래스
  • 상속받아 새롭게 만들어진 클래스는 자식 || 서브클래스

장점

  1. 재활용성 (가장 큰 장점)
  2. 완전히 새로운 것을 만드는 것이 아니라, 기존 부모로 부터 상속을 받아 필요한 것만 추가로 더해서 만드는 것
  3. 부모 클래스에 정의되어져 있는 멤버필드(변수)나 메서드 들을 그대로 상속받아 사용하면 된다.
  4. 상속받은 메서드라 해도 필요에 따라서 자식 클래스에서 용도를 변경해서 사용하는 것도 가능.

사용

  • 기존 부모 클래스를 확장한다는 개념 --> extends 키워드 사용
  • 부모 클래스의 멤버 필드, 메서드는 상속이 가능하나 생성자는 상속이 안된다.
  • 부모 클래스의 접근 제한자 private인 경우에는 아무리 자식 클래스가 상속을 받았다 하더라도 접근 불가능.

클래스의 상속을 코드로 구현

  • 클래스 구현은 형상화가 포인트
  • 자식 클래스는 부모 클랙스에서 정의된 메서드 사용가능. but 부모는 자식클래스에 생성된 메서드 사용 불가능

출력

부모 클래스→걷는중~
이름 : 슈퍼맨, 나이 : 20, 성별 : 1, 파워 : 100
이름 : 원더우먼, 나이 : 30, 성별 : 1, 파워 : 100
이름 : 원더우먼, 나이 : 30, 성별 : 2, 파워 : 300
자식 클래스→2배로 빨리 걷는중~

code

class Person {
    //Field
    int gender;
    int power;

    //Constructor
    Person() {
        this.gender = 1; // 1 : 남성, 2 : 여성
        this.power = 100; // 기본 파워
    }

    //Method
    void walk() {
        System.out.println("walking");
    }

}

class Hero extends Person {
    // Field
    String name;
    int age;

    //Constructor
    Hero() {
    }

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

    //Method ,  오버라이딩||오버라이드 (재정의)
    void walk() {
        System.out.println("2.em walking");
    }

    void eat() {
        System.out.println("eating");
    }
    // 객체의 정보 출력
    void displayPerson(){
        System.out.println("성별: "+gender+"\t 나이: "+ age +"\t 파워: "+power);
    }
}
class Villain extends Person {

}
public class Inheritance {
    public static void main(String[] args) {
        // 객체 생성
        Person kim = new Person();
        // kim.eat(); // Err :: Hero 에 있는 메서드라서 에러뜸. Person 클래스에는 해당 메서드가 없음.
        kim.walk();

        // 상속 객체 생성
        Hero man = new Hero("슈퍼맨", 20);
        System.out.println(man.name);
        System.out.println(man.age);
        System.out.println(man.gender); // walk 메서드 정의 안했으면, 부모 클래스 필드(변수) 호출함
        System.out.println(man.power); // 부모 클래스 필드(변수) 호출함
        
        man.walk();
        man.eat();
        man.displayPerson();
    }
}

상속에서 초기화가 되는 순서

(But, 출력은 열순서에 의해서 출력됨)


  • new 하는 동시에 객체가 생성되고, Hero 의 파라미터 2개가 넘어가는 생성자가 생성되고 호출되지만,
Hero(String name, int age) {
        // 1 
        this.name = name; // 2
        this.age = age; // 3
    }

-> 2~3 이 수행되기 이전에, 1번 위치에 부모 클래스의 생성자를 호출하는 부분이 있음 (지금은 생략됨).
즉, 1번줄에서 부모 클래스의 생성자를 호출하러 가서 초기화됨.
즉, 컴파일러는 부모클래스(gender,power)를 먼저 초기화하고, 자식클래스에서 생성한 부분(name,age)을 초기화함.
--> 이렇게 해서 총 4개를 초기화됨.

  • super() 써서 부모클래스 표현 가능함.
    --> 1번 줄에는 super()이 생략되어있음

클래스 상속에서 메서드 오버라이딩에 대해서 설명하고 구현

  • 상속받아서 재정의해서 사용하고 싶을 때, 사용하는 것이 오버라이딩
    (앞에서 사용한 코드 재활용)
	//Method ,  오버라이딩||오버라이드 (재정의)
    void walk() {
        System.out.println("2.em walking");
    }
  • 객체생성
		Hero h2 = new Hero("원더우먼",30);
        h2.displayPerson();
        h2.gender = 2;
        h2.power = 300;
        h2.displayPerson();
        h2.walk(); // 자식클래스가 재정의해놓았기 떄문에, 오버라이딩 부분 사용함. 없으면 부모클래스꺼 사용함.

getter, setter가 포함된 클래스의 상속을 코드로 구현

  • 부모 클래스 --> Person, 자식 클래스 --> Villain, Hero

해당 문제는 계속 반복하는 것이 좋음.
여기서 중요한 문법을 다룸과 동시에 기본이 되기 때문에, 빠르게 다루는 것이 키포인트
이해하고, 시간을 단축시키는 것이 중요함. (자동화된 툴을 사용하지 않고 작성하기)

  • 이정도의 클래스는 10분 내에 작성 가능해야함.
  • 공부를 하는 과정에서는 직접 구현하는 방법을 사용하고 나중에 툴을 사용해야합니다.

중요한 부분을 정말 많이 담고있는 코드입니다.
자주 연습하고, 코드를 일일이 설명할 수 있어야합니다.

정답 코드

// 부모클래스
class Person {
    // Field
    private String name; // private 로 지정해줘서, 이 멤버에 접근할 수 없음
    private int age;    // but, 해당 클래스 내에서만 사용할 수 있음. --> 외부에서 변경 및 수정이 불가능함, 근데 부모클래스의 멤버는 private 으로 하지만 지양함.
    private int height; // private 타입을 getter, setter 를 통해서 외부에서 접근하려고 존재함.
    private int weight;

    //Constructor 생성자
    Person(){}
    Person(String name, int age, int height, int weight) {
        this.name = name;
        this.age = age;
        this.height = height;
        this.weight = weight;
    }

    //Method
    public String getName() { // 값 세팅했으니까, 값을 가져와야함 (getter)
        return name;
    }
    // 값 세팅 = 반환 값 필요 x = void 사용
    public void setName (String name){ this.name = name; } // 전달된 p1 세팅 (setter)

    public int getAge(){return age;}
    // 전달받은 메서드의 인자값을, 멤버 내 필드에 세팅해주는거임.
    public void setAge(int age){this.age = age;}

    public int getHeight(){return height;}
    public void setHeight(int height){this.height=height;}

    public int getWeight(){return weight;}
    public void setWeight(int weight){this.weight=weight;}

    //추가
    public void move(){
        System.out.println("Moving,,");
    }
}

class Villain extends Person {
    // Field
    String unique_key;
    int weapon; // 1~9 숫자로 무기 분류  -- > 1:창, 2:방패, 3:총 ...
    double power;

    //Constructor
    Villain(){}
    // 파라미터에 부모클래스 멤버필드까지 추가해서 받아줌
    Villain(String name, int age, int height, int weight,String unique_key, int weapon, double power){ // 객체가 생성될 때, 해당 생성자가 제일 먼저 호출되니까,
//  이 생성자를 통해서 객체의 초기값(멤버필드)을 초기화해줘야함. 
// 따라서, 인자값을 7개 받아줌. but 부모 클래스에 초기화된 것이 있음.

		// 부모 클래스 가리켜서, 부모클래스의 생성자 가져옴.
        super(name,age,height,weight); 
        
        // 해당 부분을 안가져와서 초기값만 나왔음.
		// 나머지 값 3개를 세팅해줌.
        this.unique_key = unique_key;
        this.weapon = weapon;
        this.power = power;
    }
    //Method
    public String getUnique_key(){return unique_key;}  // 호출만 하면됨.
    public void setUnique_key(String unique_key){this.unique_key = unique_key;}

    public int getWeapon(){return weapon;} //  호출만 하기때문에, 인자값이 없고, 멤버변수의 weapon 을 사용해줌
    public void setWeapon(int weapon){this.weapon=weapon;}

    public double getPower(){return power;} // 파워의 값을 리턴해서 가져 오기만 하면되니까 
    public void setPower(double power){this.power=power;}

    // 정보 출력, printPerson()
    public void printPerson(){
        System.out.println("===============================");
        System.out.println("악당 name : " + getName()); // private 이니까 get 메소드만 이용해서 가져와줌
        System.out.println("악당 age : "+getAge());
        System.out.println("악당 height : "+getHeight());
        System.out.println("악당 weight : "+getWeight());
        System.out.println("악당 number : "+getUnique_key());
        System.out.println("악당 weapon : "+getWeaponName(getWeapon())); // getWeapon() :: 정수 값(1~9)으로 가져옴. 따라서 별도의 조건문을 사용해줌
		// 윗 행부분에서 getWeapon(숫자1~9)이  getWeaponName 메서드로 전달되어서, 만약 2이면 방패가 출력된다는거임.
        System.out.println("악당 power : "+getPower());
        System.out.println("===============================");
    }
    //getWeaponName()
    public String getWeaponName(int a){ // 반환되는 타입이 문자열로 반환되기 때문에, 타입은 String으로 반환해줌. 
    // 전달되는 인자값은 int로 전달되서 인자값의 타입은 int
    
        String weapon;
        switch (a){
            case 1:
                weapon = "창";
                break;
            case 2:
                weapon = "방패";
                break;
            case 3:
                weapon = "총";
                break;
            default:
                weapon = "===";
                break;
        }
        return weapon; // 리턴을 해줌과 동시에, 이 함수를 호출한 호출부로 다시 전달해줌.
        
        // 즉, getWeaponName(getWeapon())); 이 부분에서 getWeapon(숫자1~9)이  getWeaponName 메서드로 전달되어서, 만약 2이면 방패가 출력된다는거임.
    }
}

class Hero extends Person{

}

public class Inheritance{
    public static void main(String[] args) {
        // 1, 객체 생성
        Villain v1 = new Villain("좀비",20,180,80, "15001231",2,99.5); //
        v1.printPerson();
        System.out.print(v1.getName()+" ");
        v1.move(); // 부모 클래스의 move() 메서드를 호출

        // 2, 객체생성
        Villain v2 = new Villain("도깨비",30,175,70, "11001231",1,77.5);
        v1.printPerson();
        System.out.print(v2.getName() + " ");
        v2.move();

        // 3, 객체생성
        Villain v3 = new Villain("몽달귀신", 40, 150, 40, "101111234", 3, 25.5);
        v3.printPerson();
        System.out.print(v3.getName() + " ");
        v3.move();
    }
}

해당 코드의 빌런클래스의 Constructor 로직


private

  • private 로 지정해주면, 해당 멤버에 접근할 수 없음
    but, 해당 클래스 내에서만 사용할 수 있음. --> 외부에서 변경 및 수정이 불가능함, 근데 부모클래스의 멤버는 private으로 하지않는 것을 지양함.
  • private 타입을 getter, setter 를 통해서 외부에서 접근하려고 존재함.

getter, setter 로직

  • 병원에 전염병에 감염된 환자를 격리(private)해서 간호사(get,set) 외 접근 불가능해서,
    해당 환자의 가족이, 환자가 필요한 물건들을 대신 전달해주는 간호사에게 줌.
    이때, 간호사가 병실에 들어가서 환자에게 물건들을 전해줌
  • 즉, 간호사를 통해서만 접근 가능함. ( 간호사 = getter, setter )

getter 메서드에 인자값이 없는 이유

(위 전체 코드를 기반으로 설명)
내가 물건을 전달해 줄때는, 메인메서드의 set의 값을 set메서드의 인자값으로 전달해줘야 하지만, 내가 받는 것은 필요가 없음. --> 가만히 서 있다가, 간호사가 주는거 받으면 되니까. (예시임) --> 밑(메인메서드)에서 get메서드를 호출만 하면 되는거임. --> 호출만 하면, set의 인자값을 받아서 setting이 되었으니, 가져오는거임. --> 이러한 이유때문에, 따로 인자값을 넣어서 호출할 필요가 없음.

setter 메서드

set 메서드는 전달 받은 인자 값을 멤버 Field내에 세팅(초기화)함.


부모 클래스의 Method 간단한 예시

	//Method
	public String getName() { // 값 세팅했으니까, 값을 가져와야함 (getter)
        return name;
    }
    // 값 세팅 = 반환 값 필요 x = void 사용
    public void setName (String name){ this.name = name; } // 전달된 p1 세팅 (setter)
  • getName(): 이 메서드는 name 필드의 값을 가져와서 반환하는 getter입니다.
  • setName(String name): 이 메서드는 name 필드에 값을 설정하는 setter입니다. 파라미터로 전달된 name 값을 name 필드에 할당합니다.

따라서, getName()은 값을 반환하기 위해 return 키워드를 사용하고,
setName(String name)은 반환 값이 필요 없으므로 void 키워드를 사용합니다.

보통 set (setter, 값 설정)을 먼저 작성하고, get (getter, 값 호출) 작성하면 더 쉬움.


생성순서


객체에 대한 참조값을 요소로 가지는 객체 배열을 생성하는 코드를 구현

class Person{
    //Field
    private String name;
    private int age;
    //Constructor
    Person(){}
    Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    //Method
    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;
    }

}
    public class Array {
    public static void main(String[] args) {
        // 1. 객체배열 생성
        Person[] PA = new Person[5]; // 타입 [] 배열명 = 객체생성 --> 타입은 어느 출신인지 묻는거.(저장할 수 있는 객체배열 공간을 만들어줌)
        PA[0] = new Person("홍길동", 20);
        PA[1] = new Person("김길동",21);
        PA[2] = new Person("성길동",22);
        PA[3] = new Person("준길동",23);
        PA[4] = new Person("문길동",24);

        for (int i = 0; i < PA.length; i++) {
            System.out.print(PA[i].getName()+" "+PA[i].getAge());   // private 로 되어있어서 PA[i].name 로 바로 접근 못함 -> 게터,세터 이용해야함 (간호사 이용)
            System.out.println();
        }
    }
}

해당 코드를 print() 메서드를 생성해서 출력하는 방법 및 필자의 풀이해설

class Person{
    //Field
    private String name;
    private int age;

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

    //Method
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
    public void setAge(int age){
        this.age = age;
    }
    public int getAge(){
        return age;
    }

    public void print(){
        System.out.println(getName()+"\t"+getAge());
    }

}

public class Inheritance{
    public static void main(String[] args) {
        Person[] PA = new Person[5];
        PA[0] = new Person("ㅎ", 1);
        PA[1] = new Person("ㅎd", 2);
        PA[2] = new Person("ㅎ2", 3);
        PA[3] = new Person("ㅎ3123", 4);
        PA[4] = new Person("ㅎasd", 5);
        for (int i = 0; i < PA.length; i++) {
            PA[i].print();
        }
    }
}

반복문(for)을 사용하여 객체 배열을 생성하고 출력

  • 코드는 위 코드랑 거의 똑같음. 객체생성 부분만 다름
import java.util.*;
class Person{
    //Field
     String name;
     int age;
    //Constructor
    Person(){}
    Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    //Method
    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;
    }

}
    public class Array {
    public static void main(String[] args) {
        // 객체배열 생성
        Person[] PersonArray;  // Person 타입의 객체 배열 변수 선언
        PersonArray = new Person[10]; // Person 객체의 참조값을 원소로 가지는 배열 공간 5개 생성 -- > 5명 객체 생성할테니 주소 저장해라.

        // loop 돌면서 Person() 객체생성
        for (int i = 0; i < PersonArray.length; i++) {
            PersonArray[i] = new Person(i+"번쨰 후보자 --> 나이 :", 20+i); //만약 new Person(i, i+20); 하면 에러 나는 이유 ? --> 파라미터로 문자열, 정수를 받는데, 여기선 두개 다 정수로 해서 에러남

            // [2-1] :: 게더, 세터 메서드 사용해서 출력
            // System.out.println(PersonArray[i].getName()+" "+ PersonArray[i].getAge());

            // [2-2] :: 배열 인덱스 사용해서 출력 --> 단, 이렇게 쓰려면 private 선언을 삭제하고 써야함
            // System.out.println(PersonArray[i].name+"의 나이는 "+PersonArray[i].age+" 살 입니다."); // 이렇게 해주려면 Field 부분에서 private 삭제하고 사용해야함.

            // [2-3] :: printf
            // System.out.printf("%s %d살 입니다.\n", PersonArray[i].name, PersonArray[i].age);
        }
    }
}

참고

필자는 슈퍼클래스의 멤버는 private로 설정해주고, getter , setter를 사용하는 것을 매우 권장합니다.

오버로딩 vs 오버라이딩

  • 오버로딩(overloading)과 오버라이딩(overriding)은 둘 다 다형성의 특징을 나타내는 객체 지향 프로그래밍의 개념입니다.

오버로딩

같은 이름의 메서드(Method)나 생성자(Constructor)를 여러 개 정의하여 매개변수의 유형과 수에 따라 다른 구현이 가능하게 하는 것을 의미합니다.
즉, 같은 이름으로 다양한 매개변수를 받아 처리할 수 있도록 하는 것입니다.


반면,

오버라이딩

상위 클래스에서 정의된 메서드를 하위 클래스에서 재정의하여 사용하는 것을 의미합니다. 즉, 상위 클래스의 메서드를 하위 클래스에서 수정하여 자신의 필요에 맞게 재정의할 수 있도록 해주는 것입니다.

오버로딩과 오버라이딩의 대표적인 차이

  1. 정의하는 객체 : 오버로딩은 같은 클래스 내에 메서드나 생성자를 다시 정의하는 것을 의미합니다.
    반면, 오버라이딩은 상위 클래스의 메서드를 하위 클래스에서 재정의하여 사용하는 것을 의미합니다.

  2. 제어 시점 : 오버로딩은 컴파일 시점에서 결정됩니다.
    반면, 오버라이딩은 런타임 시점에서 결정됩니다.

  3. 매개변수의 유무 : 오버로딩은 메서드나 생성자를 호출할 때 인자의 유무에 따라 다른 동작을 할 수 있도록 해줍니다.
    반면, 오버라이딩은 메서드의 시그니처가 동일한 경우, 인자의 유무에 관계없이 오버라이딩된 메서드가 호출됩니다.

  4. 반환형 : 오버로딩은 호출할 메서드의 반환형이 다르더라도 메서드 오버로딩을 할 수 있습니다.
    반면, 오버라이딩은 상위 클래스의 메서드와 동일한 반환형을 가져야 합니다.

  5. 상속과 관계 : 오버로딩은 상속과 직접적인 관련이 없습니다.
    반면, 오버라이딩은 상위 클래스의 메서드를 하위 클래스에서 재정의하기 때문에 상속과 관계가 있습니다.

profile
컴퓨터공학과에 재학중이며, 백엔드를 지향하고 있습니다. 많이 부족하지만 열심히 노력해서 실력을 갈고 닦겠습니다. 부족하고 틀린 부분이 있을 수도 있지만 이쁘게 봐주시면 감사하겠습니다. 틀린 부분은 댓글 남겨주시면 제가 따로 학습 및 자료를 찾아봐서 제 것으로 만들도록 하겠습니다. 귀중한 시간 방문해주셔서 감사합니다.

0개의 댓글