이전 글에서 작성한 글을 이어서 작성하도록 하겠습니다!!
안보신 분들은 이전 게시글을 보고 와주세요.😊😊
다형성이란 부모 클래스 타입의 참조 변수로 자식 클래스 객체를 다룰 수 있는 능력을 의미합니다. 다형성은 메서드 오버로딩이나 메서드 오버라이딩을 통해 구현됩니다. 예를 들어, 동물 클래스에서 울다라는 메서드를 정의하고, 이를 상속받은 개와 고양이 클래스에서 각각 다르게 구현할 수 있습니다.
부모 클래스의 배열에 자식 클래스 객체를 담아 관리할 수 있습니다.
예를 들어, PersonVO[] 배열에 StudentVO, TeacherVO, EmployeeVO 객체를 담아 공통적으로 처리합니다.
PersonVO perAry[] = new PersonVO[10];
// 부모 타입 배열에 자식 객체를 저장
perAry[0] = new StudentVO("섭섭이", 20, "서울", "2000");
perAry[1] = new TeacherVO("김교사", 35, "부산", "JAVA");
perAry[2] = new EmployeeVO("박직원", 40, "인천", "교육팀");
배열에 저장된 객체가 실제 어떤 타입인지 확인하려면 instanceof 연산자를 사용.
이를 통해 적절한 다운캐스팅을 수행하여 객체의 고유한 메서드를 호출할 수 있다.
📢 형변환이된 값을 보기 위해서는 다운캐스팅(명시적 형변환)이 필요하다.
📢 다형성에서 객체의런타입시점의 타입을 확인할 수 있도록 instanceof를 사용한다.
// 다운캐스팅을 통해 각 객체의 고유 메서드 호출
for (PersonVO per : perAry) {
if (per instanceof StudentVO) {
System.out.println(((StudentVO) per).stuInfo());
} else if (per instanceof TeacherVO) {
System.out.println(((TeacherVO) per).teaInfo());
} else if (per instanceof EmployeeVO) {
System.out.println(((EmployeeVO) per).empInfo());
}
}
캡슐화는 객체의 속성(필드)을 외부에서 직접 접근하지 못하도록 숨기고, 대신 접근 메서드(getter/setter)를 통해 제어하는 것을 의미합니다. 이를 통해 데이터의 무결성을 유지하고 외부의 불필요한 접근이나 변경을 방지할 수 있습니다.
private으로 설정하여 외부에서 직접 접근을 차단합니다.getter와 setter 메서드를 public으로 제공하여 간접적으로 접근합니다.public class Student {
private String name;
private int age;
// 생성자
public Student(String name, int age) {
this.name = name;
setAge(age); // 유효성 검사를 위해 setter 사용
}
// getter
public String getName() {
return name;
}
// setter
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age > 0) { // 나이는 0 이상이어야 한다는 조건 추가
this.age = age;
} else {
System.out.println("나이는 0보다 커야 합니다.");
}
}
}
public class Main {
public static void main(String[] args) {
Student student = new Student("shimssung", 20);
System.out.println("이름: " + student.getName());
System.out.println("나이: " + student.getAge());
student.setAge(-5); // 유효성 검사로 인해 값 변경 실패
System.out.println("변경된 나이: " + student.getAge());
}
}
이름: shimssung
나이: 20
나이는 0보다 커야 합니다.
변경된 나이: 20
추상화란 객체가 제공하는 중요한 기능만을 노출하고, 그 이면의 복잡한 구현을 숨기는 것입니다.
예를 들어, 차량이라는 추상 클래스를 만들고, 운전이라는 공통 기능을 정의할 수 있습니다.
// 추상 클래스 정의
public abstract class Animal {
public void eating(String food) {
System.out.printf("%s 를(을) 먹습니다.\n", food);
}
public abstract void fly(); // 추상 메서드
}
// 추상 클래스를 상속받는 클래스
public class SuperMan extends Animal {
@Override
public void fly() {
System.out.println("망토로 중력을 이용해서 날아다닙니다.");
}
}
public class Bird extends Animal {
@Override
public void fly() {
System.out.println("날개로 중력을 이용해서 날아다닙니다.");
}
}
// 메인 클래스
public class AbstractApp {
public static void main(String[] args) {
// 추상 클래스는 타입으로 사용 가능
Animal[] ary = new Animal[2];
ary[0] = new SuperMan();
ary[1] = new Bird();
for (Animal animal : ary) {
animal.fly(); // 오버라이딩된 메서드 호출
animal.eating("쌀");
}
}
}
// 인터페이스 정의
public interface Flyer {
void fly();
}
// 추상 클래스와 인터페이스를 함께 구현
public class SuperMan extends Animal implements Flyer {
@Override
public void fly() {
System.out.println("망토로 중력을 이용해서 날아다닙니다.");
}
}
public class Bird extends Animal implements Flyer {
@Override
public void fly() {
System.out.println("날개로 중력을 이용해서 날아다닙니다.");
}
}
// 메인 클래스에서 인터페이스 활용
public class AbstractApp {
public static void main(String[] args) {
Flyer[] ary = new Flyer[2];
ary[0] = new SuperMan();
ary[1] = new Bird();
for (Flyer flyer : ary) {
flyer.fly();
// 인터페이스 타입을 통해 Animal의 메서드 호출
((Animal) flyer).eating("쌀");
}
}
}