자바(JAVA)/미니 프로젝트 & 기초 공부

Java 기초 다시 공부하기 6주차 - 클래스와 객체, 상속, 다형성, 추상 클래스

개발학생 2024. 8. 18. 15:17
반응형

1. 클래스와 객체

1) 클래스

  • 객체를 정의하는 설계도
  • 객체 변수(멤버 변수)와 메서드로 이루어짐
public class 클래스명 {
	// 객체 변수
	// 메서드
	// +접근제어자
	// +static
}

클래스명 객체명 = new 클래스명(); 

2) 객체/인스턴스

(1) 객체(Object)

  • 실체

(2) 인스턴스(Instance)

  • 클래스와 객체의 관계
  • 인스턴스화: 클래스로부터 객체 선언
  • 어떤 객체는 어떤 클래스의 인스턴스일 수 있음

3) 생성자(Constructor)

  • 객체가 생성될 때 자동으로 호출
  • 생성자 규칙
    - 클래스명과 이름 맞추기
    - 리턴 타입 없음
public class 클래스명 {
	클래스명(){}
}

4) this, this()

(1) this

  • 객체 자신을 의미

(2) this()

  • 생성자

5) 오버로딩(Overloading)

  • 한 클래스 내에서 같은 이름의 메서드를 여러개 정의 가능
  • 조건: 메서드의 이름이 같으면서, 매개변수의 개수 또는 타입이 달라야 함(리턴타입과는 관련 없음)

6) 접근제어자

  • 클래스의 변수나 메서드의 접근에 제한을 두는 키워드
  • 종류 
private 해당 클래스에서만 접근
public 어디서나 접근
default 해당 패키지 내에서만 접근
protected 해당 패키지 및 상속받은 클래스에서 접근

출처: https://www.tcpschool.com/java/java_modifier_accessModifier

7) Static

  • 변수나 메서드의 특성을 바꿈
    → 메모리에 한 번만 할당되며, Static 변수와 메서드는 공유됨
  • Static 클래스 변수: 해당 클래스의 각 객체들이 값을 공유
  • Static 클래스 메서드: 객체를 생성하지 않아도 호출 가능

* 예제 실습

// Java 프로그래밍 - 클래스와 객체

// Car 클래스 - 객체변수, 메서드
class Car {
	String name;
	String type;
	
	// 기본생성자(생략가능)
	// Car(){}
	
	public void printCarInfo() {
		System.out.println("== Car Info ==");
		System.out.println("name = " + name);
		System.out.println("type = " + type);
	}
	
	public void move() {
		System.out.println("이동!");
	}
	
	public void brake() {
		System.out.println("정지!");
	}
}

// Car2 클래스 - 생성자, this
class Car2 {
	String name;
	String type;
	
	// 기본생성자(생략가능)
	// Car2(){}
	
	// 생성자
	Car2(String name, String type) {
		this.name = name;
		this.type = type;
		System.out.println("생성자 출력!");
	}
	
	public void printCarInfo() {
		System.out.println("== Car2 Info ==");
		System.out.println("name = " + name);
		System.out.println("type = " + type);
	}
	
	public void load() {
		System.out.println("짐을 주세요!");
	}
	
	public void horn() {
		System.out.println("빵빵!");
	}
}

public class ClassAndObject {
	public static void main(String[] args) {
		// Car 클래스 사용
		Car car1 = new Car();
		car1.name = "a";
		car1.type = "suv";
		car1.printCarInfo();
		car1.move();
		car1.brake();
		
		// Car2 클래스 사용
		Car2 car2 = new Car2("b", "sedan");
		car2.printCarInfo();
		car2.load();
		car2.horn();
	}
}

** ClassAndObject.java 수정, Car2.java 생성

// Java 프로그래밍 - 클래스와 객체
import car.Car2;

// Car 클래스 - 객체변수, 메서드
class Car {
    String name;
    String type;

    // 기본생성자(생략가능)
    // Car(){}
    Car(String name, String type) {
        this.name = name;
        this.type = type;
    }

    public void printCarInfo() {
        System.out.println("== Car Info ==");
        System.out.println("name = " + name);
        System.out.println("type = " + type);
    }

    // 오버로딩 구현
    public void printCarInfo(String date) {
        this.printCarInfo();
        System.out.println("date: " + date);
    }
    public void printCarInfo(int number) {
        this.printCarInfo();
        System.out.println("number: " + number);
    }
    public void printCarInfo(String date, int number) {
        this.printCarInfo();
        System.out.println("date: " + date + "," + "number: " + number);
    }
}

// Car2 클래스 - 생성자, this
class Car3 {
    // 스태틱 변수
    static String name = "None";
    String type;

    // 기본생성자(생략가능)
    // Car2(){}

    // 생성자
    Car3(String name, String type) {
        this.name = name;
        this.type = type;
    }

    public void printCarInfo() {
        System.out.println("== Car2 Info ==");
        System.out.println("name = " + name);
        System.out.println("type = " + type);
    }

    // 스태틱 메서드
    public static void getName() {
        System.out.println("Car name: " + name);
    }

}

public class ClassAndObject {
    public static void main(String[] args) {
        Car car1 = new Car("a", "sedan");
        car1.printCarInfo();

        // 1. 오버로딩 사용
        System.out.println(("=== 오버로딩 사용 ==="));
        car1.printCarInfo("2022");
        car1.printCarInfo(1234);
        car1.printCarInfo("2022", 1234);

        // 2. 접근 제어자
        System.out.println("\\n=== 접근 제어자 ===");
        Car2 car2 = new Car2("a", "b", "c", "d");
        System.out.println(car2.name1);
//        System.out.println(car2.name2);
//        System.out.println(car2.name3);
//        System.out.println(car2.name4);

        // 3. static;
        System.out.println("\\n=== static ===");
        Car3.getName();
        Car3 car3_1 = new Car3("a", "sedan");
        Car3 car3_2 = new Car3("b", "suv");
        Car3 car3_3 = new Car3("c", "rv");
        car3_1.printCarInfo();
        car3_2.printCarInfo();
        car3_3.printCarInfo();
    }
}

// Car2.java
package car;

public class Car2 {
    public String name1;
    private String name2;    // private: getter, setter가 없으면 다른 클래스에서 접근 불가능
    protected String name3;  // protected: 해당 패키지를 상속받지 않아 접근 불가능
    String name4;    // default: 해당 패키지 내에서만 접근 가능

    public Car2(String name1, String name2, String name3, String name4) {
        this.name1 = name1;
        this.name2 = name2;
        this.name3 = name3;
        this.name4 = name4;
    }
}

*** 출력 결과

2. 상속

  • 기존 클래스에 기능 추가 및 재정의하여 새로운 클래스 정의
    • 부모 클래스: 상속 대상이 되는 기존 클래스 (=상위 클래스, 기초클래스)
    • 자식 클래스: 기존 클래스를 상속하는 클래스 (=하위 클래스, 파생 클래스)
  • 부모 클래스의 필드와 메소드가 상속됨 (생성자/초기화 블록은 상속 x)
  • 다중 상속은 불가능
  • private는 자식 클래스에서 접근 불가, default는 내부 패키지의 자식 클래스에서는 접근 가능

출처: https://www.tcpschool.com/java/java_inheritance_concept

1)  super, super()

(1) super

  • 부모 클래스와 자식 클래스의 멤버 이름이 같을 때 구분하는 키워드

(2) super()

  • 부모 클래스의 생성자 호출

2) 오버라이딩(Overriding)

  • 부모 클래스의 메서드를 자식 클래스에서 재정의
  • 조건
    - 메서드의 선언부가 부모 클래스의 메서드와 동일해야 함
    - 반환 타입에 한해, 부모 클래스의 반환 타입으로 형변환할 수 있는 타입으로 변경 가능
    - 부모 클래스의 메서드보다 접근제어자를 더 좁은 범위로 변경 불가
    - 부모 클래스의 메서드보다 더 큰 범위의 예외 선언 불가

3) 예제 실습

// Java 기초 - 상속

// Person 클래스 - Student 클래스의 부모
class Person {
    String name;
    int age;
    public int a1;
    private int a2;

    // 기본 생성자(생략가능)
    Person() {}
    // 생성자
    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public void printInfo() {
        System.out.println("=== Person.printInfo ===");
        System.out.println("name: " + name);
        System.out.println("age: " + age);
    }
}

// Student 클래스 - Person 클래스 상속, 접근제어자 확인
class Student extends Person {
    Student() {
        a1 = 1;
        //a2 = 1;   //오류
    }
}

// Student2 클래스 - Person 클래스 상속, super 사용, 오버라이딩
class Student2 extends Person {
    String name;
    int stdId;

    Student2(String name, int age, int stdId) {
        //this.name = name;
        //super.name = name;
        //super(name, age);
        this.age = age;
        this.stdId = stdId;
    }

    public void printInfo() {
        System.out.println("=== Student2.printInfo ===");
        System.out.println("name: " + name);
        System.out.println("age: " + age);
        System.out.println("stdId: " + stdId);
    }
}

public class Inheritance {
    public static void main(String args[]) {
        // 1. 상속
        System.out.println("=== 상속 ===");
        Student s1 = new Student();
        s1.name = "a";
        s1.age = 25;
        s1.printInfo();

        // 2. super, super(), 오버라이딩
        System.out.println("=== super, super(), 오버라이딩 ===");
        Student2 s2 = new Student2("b", 32, 1);
        s2.printInfo();
    }
}

3. 다형성(Polymorphism)

  • 한 객체가 여러 가지 타입을 가질 수 있는 것
  • 부모클래스 타입의 참조 변수로 자식클래스 인스턴스 참조
    class Person {}
    class Student extends Person {}
    
    Person p1 = new Student();
    // Student s1 = new Person();    // 오류
    ​

1) instanceof

  • 실제 참조하고 있는 인스턴스의 타입 확인
class Person {}
class Student extends Person {}

Person p1 = new Student();
// Student s1 = new Person();    // 오류
System.out.println(p1 instanceof Person); 

2) 예제 실습

// Java 프로그래밍 - 다형성

class PersonPo {
    public void print() {
        System.out.println("PersonPo.print");
    }
}

class StudentPo extends PersonPo {
    public void print() {
        System.out.println("StudentPo.print");
    }
    public void print2() {
        System.out.println("StudentPo.print2");
    }
}

class CollegeStudent extends PersonPo {
    public void print() {
        System.out.println("CollegeStudent.print");
    }
}

public class Polymorphism {
    public static void main(String[] args) {
        // 1. 다형성
        System.out.println("=== 다형성 ===");
        PersonPo p1 = new PersonPo();
        StudentPo s1 = new StudentPo();
        PersonPo p2 = new StudentPo();
//        StudentPo sp2 = new PersonPo();

        p1.print();
        s1.print();
        s1.print2();
        p2.print();
//        p2.print2();

        PersonPo p3 = new CollegeStudent();
//        CollegeStudent c1 = new StudentPo();
        p3.print();

        // 2. 타입 변환
        System.out.println("=== 타입 변환 ===");
        PersonPo pp1 = null;
        StudentPo ss1 = null;

        PersonPo pp2 = new PersonPo();
        StudentPo ss2 = new StudentPo();
        PersonPo pp3 = new StudentPo();    // 업캐스팅

        pp1 = pp2;
        pp1 = ss2;

        ss1 = ss2;
//        ss1 = pp2;
        ss1 = (StudentPo)pp3;    // 다운캐스팅

        // 3. instanceof
        System.out.println("=== instanceof ===");
        PersonPo pe1 = new PersonPo();
        StudentPo st1 = new StudentPo();
        PersonPo pe2 = new StudentPo();
        PersonPo pe3 = new CollegeStudent();

        System.out.println(pe1 instanceof PersonPo);
        System.out.println(pe1 instanceof StudentPo);

        System.out.println(st1 instanceof StudentPo);
        System.out.println(st1 instanceof PersonPo);

        System.out.println(pe2 instanceof PersonPo);
        System.out.println(pe2 instanceof StudentPo);

        System.out.println(pe3 instanceof PersonPo);
        System.out.println(pe3 instanceof CollegeStudent);

        if (pe1 instanceof StudentPo) {
            StudentPo stu1 = (StudentPo) pe1;
        }
        if (st1 instanceof PersonPo) {
            PersonPo per1 = (PersonPo) st1;
        }
    }
}

4. 추상 클래스 

1) 추상 메서드 (Abstract Method)

  • 자식클래스에서 반드시 오버라이딩 해야 하는 메서드
  • 선언만 하고 구현 내용은 없음
abstract void print();

2) 추상 클래스 (Abstract Class)

  • 하나 이상의 추상 메서드를 포함하는 클래스
  • 반드시 구현해야 하는 부분에 대해 명시적으로 표현
  • 추상 클래스 자체는 객체 생성 불가
abstract class 클래스명 {
	...
	abstract void print();
}

3) 예제 실습

// Java 기초 - 추상 클래스

// 추상 클래스 Person1
abstract class Person1 {
    abstract void printInfo();
}
// 추상 클래스 상속
class Student1 extends Person1 {
    public void printInfo(){
        System.out.println("Student1.printInfo");
    };
}

public class Abstract {
    public static void main(String[] args) {
        // 추상 클래스의 사용
//        Person1 p1 = new Person1();
        Person1 p1 = new Person1() {
            @Override
            void printInfo() {
                System.out.println("Abstarct.printInfo");
            }
        };
        p1.printInfo();

        Student1 s1 = new Student1();
        s1.printInfo();
    }
}

반응형