
수평적 구조일 때 모두 사원들이므로 이름, 나이, 전화번호, 주소, 입사일, 근무부서 요소들이 겹친다. 이는 중복된 코드가 많아 효율적인 코드가 아니다. 또한 추가요소들이 달라 유지보수가 힘들다. 수직적 구조일 때의 구조를 보자.

수직적 구조로 설계하면 코드의 중복화를 최소화 할 수 있다. 사원을 확장(extends)시켜서 일반사원, 관리사원, 비서, 일용직 등으로 늘릴 수 있다.
//부모 클래스
public class Employee {
protected String name;
protected int age;
protected String phone;
protected String empDate;
protected String dept;
protected boolean marriage;
public Employee(){ // 생략 가능
super();
}
}
//자식 클래스
public class RempVO extends Employee{
public RempVO(){ // 생략 가능
super();
}
RempVO vo=new RempVO();
vo.name="홍길동";
vo.age=33;
vo.phone="010-1111-1111";
vo.empDate="2010.01.01";
vo.dept="홍보부";
vo.marriage=true;
}

하지만 위의 접근방법은 문제가 있다. 자식이 부모의 상태정보를 마음대로 접근하는 것은 protected라고 하지만 정보은닉에 위배된다. 어떻게 해야 해결할 수 있을까?
//부모 클래스
public class Employee {
protected String name;
protected int age;
protected String phone;
protected String empDate;
protected String dept;
protected boolean marriage;
public Employee(){
super(); // 생략
}
}
//자식 클래스
public class RempVO extends Employee{
public RempVO(String name, int age, String phone, String empDate, String dept, boolean marriage) {
super();
this.name=name;
this.age=age;
this.phone=phone;
this.empDate=empDate;
this.dept=dept;
this.marriage=marriage;
}
}
//메인함수
public class EmployeeInitTest {
public static void main(String[] args) {
RempVO vo = new RempVO("홍길동", 33, "010-1111-1111", "2022-2222-2222", "홍보부", true);
System.out.println(vo.toString());
}
}
RempVo 클래스는 상속받기 때문에 Employee클래스의 상태정보들을 선언하지 않고 사용할 수 있다. RempVo클래스의 객체 초기화를 하여 다음과 같다.
RempVO vo=new RempVO("홍길동",33,"010-1111-1111","2010.01.01","홍보부",true);

이러한 방식으로도 자식이 부모의 상태정보에 마음대로 접근하기 때문에 정보은닉에 위배된다. 초기화는 해당 객체에서 하는것이 바람직하다.
부모의 상태변수를 private로 바꾸고 부모의 생성자에서 초기화 하는것이 바람직하다. 자식 클래스에서 부모의 생성자를 호출한다.
//부모 클래스
public class Employee {
private String name;
private int age;
private String phone;
private String empDate;
private String dept;
private boolean marriage;
public Employee(){
}
public Employee(String name, int age, String phone, String empDate, String dept, boolean marriage) {
this.name = name;
this.age = age;
this.phone = phone;
this.empDate = empDate;
this.dept = dept;
this.marriage = marriage;
}
}
//자식 클래스
public class RempVO extends Employee{
public RempVO(String name, int age, String phone, String empDate, String dept, boolean marriage) {
super(name, age, phone, empDate, dept, marriage); //부모의 생성자 호출
}
}
//메인함수
RempVO vo=new RempVO("홍길동",33,"010-1111-1111","2010.01.01","홍보부",true);
System.out.println(vo);
부모의 생성자에서 상태변수를 초기화 하면 정보은닉을 지킬 수 있다. 즉 자식이 부모에게 부탁을 한 후 상태정보를 이용하는 것이다.

public class Dog{
public void eat(){
System.out.println(“개처럼 먹다.”);
}
}
public class Cat{
public void eat(){
System.out.println(“고양이처럼 먹다.”);
}
public void night(){
System.out.println(“밤에 눈에서 빛이 난다.”);
}
}
//메인 클래스
public static void main(String[] args) {
//Dog 객체를 생성하고 eat()
Dog d = new Dog();
d.eat();
//Cat 객체를 생성하고 eat(), night()
Cat c = new Cat();
c.eat();
c.night();
}
수평적 구조로 설계하면 코드의 유지보수, 중복 등 여러 문제가 발생한다.

//부모 클래스
public class Animal {
public Animal(){
super(); //new Object();
}
public void eat(){
System.out.println("동물처럼 먹다");
}
}
//자식 클래스
public class Dog extends Animal {
public Dog() {
super(); // new Animal();
}
}
//자식 클래스
public class Cat extends Animal {
public Cat() {
super(); //new Animal()
}
public void night(){
System.out.println("밤에 눈에서 빛이 난다");
}
}
//메인함수
public class DogCatTest {
public static void main(String[] args) {
//Dog 객체를 생성하고 eat()
Dog d = new Dog();
d.eat();
//Cat 객체를 생성하고 eat(), night()
Cat c = new Cat();
c.eat();
c.night();
}
}
다음과 같이 객체를 생성 후 메인함수에서 출력했을 때 Dog 객체의 eat와 Cat객체의 eat가 모두 "동물처럼 먹다"가 출력될 것이다. 우리는 Dog와 Cat이 같은 이름의 eat( ) 메서드를 쓰지만 각자 원하는 값을 출력하고 싶다.