2021. 04. 05(월) TIL

Dylan·2021년 4월 5일
0

Java

상속

  • 상속이란, 기존의 클래스(부모클래스)를 재사용해서 새로운 클래스(자식클래스)를 작성하는 것이다.
  • 상속을 이용해서 클래스를 작성하면 보다 적은 양의 코드로 새로운 클래스를 작성할 수 있다.
  • 새로 작성된 클래스들은 기존 클래스의 코드를 공통으로 가지게 되기 때문에, 공통코드의 관리가 쉬워진다.

상속의 장점

  • 코드의 재사용성을 높일 수 있다.
  • 코드의 중복을 제거할 수 있다.
  • 프로그램의 생산성과 유지보수성이 좋아진다.

상속을 이용해서 새로운 클래스 작성하기

  • 기존 클래스(상위클래스)를 상속받아서 새로운 클래스(하위클래스) 작성할 때는 extends 키워드를 사용한다.

      // 상위 클래스, 부모 클래스
      public class Parent {
        // 필드
        // 메소드
      }
    
      // 하위 클래스, 자식 클래스
      public class Child1 extends Parent {
        // Child1의 필드
        // Child1의 메소드
      }
      public class Child2 extends Parent {
        // Child2의 필드
        // Child2의 메소드
      }
  • 하위 클래스는 상위 클래스의 필드와 메소드를 상속받는다.

  • 상속은 상위 클래스를 확장시켜서 하위 클래스틀 만드는 것이다.

  • 하위 클래스는 추가적인 코드 작성 없이 상위클래스로부터 상속받은 필드와 메소드를 바로 사용할 수 있다.

  • 동일한 상위 클래스를 상속받아서 만들어진 하위 클래스는 상위 클래스로부터 상속받은 필드와 메소드가 동일하다.

  • 동일한 상위 클래스를 상속받은 하위 클래스로 만들어진 객체는 동일한 속성과 동일한 기능을 가지게 된다.

  • 각각의 하위 클래스에서는 자신만의 필드와 메소드를 추가할 수 있다.

상속을 활용해서 하위 클래스 만들기 예제

  • Phone, FeaturePhone, SmartPhone 클래스 정의하기

    • Phone클래스는 모든 Phone이 공통으로 가지는 필드와 메소드를 가지고 있다.
      • 전화번호 필드, 전화걸기 메소드, 전화받기 메소드
    • FeaturePhone 클래스
      • 전화번호 필드, 전화걸기 메소드, 전화받기 메소드는 Phone 클래스로부터 상속받는다.
      • FeaturePhone의 고유한 필드(픽셀 필드)와 고유한 메소드(사진찍기 기능)만 정의한다.
    • SmartPhone 클래스
      • 전화번호 필드, 전화걸기 메소드, 전화받기 메소드는 Phone 클래스로부터 상속받는다.
      • SmartPhone의 고유한 필드(ip주소필드, 이메일 필드)와 메소드(인터넷기능, 이메일 기능)만 정의한다.
      // 핸드폰 클래스
      public class Phone {
        // 전화번호 필드
        String tel;
        // 전화걸기 메소드
        void call() { ... }
        // 전화받기 메소드
        void receive() { ... }
      }
    
      // 카메라 기능 및 SMS 기능이 있는 핸드폰 
      public class FeaturePhone extends Phone {
        // 픽셀 필드
        int pixel;
        // 사진찍기 메소드
        void picture() { ... }
      }
    
      // 인터넷 기능이 있는 스마트폰
      public class SmartPhone extends Phone {
        // 아이피 주소 필드
        String ip;
        // 이메일 필드
        String email;
        // 인터넷 메소드
        void web() { ... }
        // 전자메일 메소드
        void mail() { ... }
      }
  • Phone, FeaturePhone, SmartPhone는 모두 전화번호 필드와 전화기능 메소드를 가지고 있는 Phone류 클래스다.

  • 따라서, 같은 상위클래스를 상속받은 클래스는 상속받은 상위 클래스와 같은 종류의 클래스가 된다.

  • FeaturePhone 클래스와 SmartPhone 클래스로 만들어진 객체는 전화번호 속성, 전화걸기 기능, 전화받기 기능을 가지고 있고, 자신들의 고유한 속성과 기능도 가지고 있다.

      public static void main(String[] args) {
        // Phone 객체 생성하기
        Phone p1 = new Phone();
        p1.tel = "010-1234-5678";
        p1.call();
        p1.receive();
    
        // FeaturePhone 객체 생성하기
        FeaturePhone p2 = new FeaturePhone();
        p2.tel = "010-4573-0985";   // Phone의 속성
        p2.pixel = 5000000;       
        p2.call();                  // Phone의 기능
        p2.receive();               // Phone의 기능
        p2.picture();
    
        // SmartPhone 객체 생성하기
        SmartPhone p3 = new SmartPhone();
        p3.tel = "010-3456-7584";   // Phone의 속성
        p3.ip = "211.10.46.109";
        p3.email = "hong@gmail.com";
        p3.call();                  // Phone의 기능
        p3.receive();
        p3.web();
        p3.mail();
      }

  • 상속관계에 있는 객체의 생성

    • 하위 객체를 생성하면 상위객체도 같이 생성된다.
    • 하위 객체는 상속받은 상위 객체를 포함하고 있다.
    • 하위 객체를 참조하는 참조변수로 하위 객체의 변수와 메소드를 사용할 수 있다.
    • 하위 객체를 참조하는 참조변수로 하위 객체 내부에 포함되어 있는 상위 객체의 변수와 메소드를 사용할 수 있다.
    • 단, 상위객체의 생성자 메소드와 상위 객체의 은닉화(숨겨진)된 변수나 은닉화된 메소드는 사용할 수 없다.
    • 동일한 상위 클래스를 상속받은 모든 하위클래스는 객체를 생성하면 모두 상위 객체를 내부에 포함하게 된다.

클래스의 상속

  • 단일 상속만 지원한다.

    • 하위 클래스는 한 개의 상위 클래스만 상속받을 수 있다.
    • 두 개 이상의 상위 클래스를 동시에 상속받을 수 없다.
      // 컴파일 오류
      // 하위 클래스는 오직 상위 클래스 하나만 상속받을 수 있다.
      public class Child extends Parent1, Parent2 {
    
      }
  • 동시에 상위 클래스를 두개 상속받을 수는 없지만, 여러 상위 클래스를 수직적으로 상속받을 수는 있다.

      // GrandParent 클래스
      public class GrandParent {
        // GrandParent 클래스의 필드와 메소드
      }
      // GrandParent 클래스를 상속받은 Parent 클래스
      public class Parent extends GrandParent {
        // Parent 클래스의 필드와 메소드
      }
      public class Me extends Parent {
        // Me 클래스의 필드와 메소드
      }

  • 상위클래스가 지정되지 않은 클래스는 항상 Object 클래스를 상속받는다.

    • Object 클래스는 자바의 최상위 클래스다.
    • Object 클래스는 배열을 포함한 모든 클래스의 최상위 클래스다.
    • 따라서, 자바의 모든 클래스는 Object 클래스의 하위 클래스다.
    • Object 클래스는 java.lang 패키지에 있다.
    • Object 클래스는 상위 클래스가 없는 유일한 클래스다.
    • Object 클래스에는 배열을 포함한 모든 객체가 꼭 포함해야할 메소드가 정의되어 있다.
    • 배열객체를 포함한 모든 객체는 Object객체를 내부에 포함하고 있다.
    • 배열객체를 포함한 모든 객체는 Object객체가 가진 기능을 사용할 수 있다.
package day1;

public class Phone extends Object {

	private String tel;
	
	public String getTel() {
		return tel;
	}
	
	public void setTel(String tel) {
		this.tel = tel;
	}
	
	public void call() {
		System.out.println("지정된 번호 [" + tel + "]로 전화를 겁니다.");
	}
	
	public void receive() {
		System.out.println("전화를 받습니다.");
	}
}
package day1;

public class FeaturePhone extends Phone {

	// 모든 전화기들의 공통 속성과 기능은 상위클래스인 Phone으로부터 상속받았다.
	// (전화번호, 전화걸기, 전화받기)
	// FEaturePhone 클래스를 작성할 때 전화관련 기능은 Phone으로 상속받기 떄문에
	// FeaturePhone의 고유한 속성과 고유한 기능의 구현에만 집중할 수 있다.
	// FeaturePhone 외 다른 전화기 관련 클래스를 작성할 때도 Phone을 상속받아서 작성
	// 하면 되기 때문에 전화기 관련 기능은 Phone 클래스에서만 작성하면 된다.
	// 따라서 코드의 중복을 제거할 수있다.
	
	// FeaturePhone의 고유한 속성
	private int pixel;
	
	public int getPixel() {
		return pixel;
	}

	public void setPixel(int pixel) {
		this.pixel = pixel;
	}

	// FeaturePhone의 고유한 기능
	public void takePicture() {
		System.out.println("[" + pixel + "]화소의 화질로 사진을 찍습니다.");
	}
}
package day1;

public class SmartPhone extends Phone {

	private String ip;
	private String emailAddress;
	

	public String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	public String getEmailAddress() {
		return emailAddress;
	}

	public void setEmailAddress(String emailAddress) {
		this.emailAddress = emailAddress;
	}
	
	public void web() {
		System.out.println("[" + ip + "] ip 주소로 인터넷을 사용합니다.");
	}
	
	public void mail() {
		System.out.println("[" + emailAddress + "] 이메일 계정으로 메일을 주고 받습니다.");
	}
}
package day1;

public class PhoneApp {

	public static void main(String[] args) {
		// Phone 객체 생성하기
		System.out.println("### Phone 객체 사용하기");
		Phone phone = new Phone();
		phone.setTel("010-1234-5678");
		phone.call();
		
		// FeatherPHone 객체 생성하기
		System.out.println("### FeaturePhone 객체 사용하기");
		FeaturePhone featurePhone = new FeaturePhone();
		featurePhone.setTel("010-3333-3333");
		featurePhone.setPixel(7000000);					// FeaturePhone의 고유한 속성
		featurePhone.call();							// phone객체로부터 물려받은 기능
		featurePhone.takePicture();						// FeaturePhone의 고유한 속성
		
		// SmartPhone 객체 생성하기
		System.out.println("### SmartPhone 객체 사용하기");
		SmartPhone smartPhone = new SmartPhone();
		smartPhone.setTel("010-4444-4444");
		smartPhone.call();
		smartPhone.setIp("192.168.0.1");
		smartPhone.setEmailAddress("hong@gmail.com");
		smartPhone.web();
		smartPhone.mail();
		
	}
}

메소드 재정의(overriding)

  • 상위클래스로부터 상속받은 메소드의 내용을 재정의하는 것이다.
  • 상속관계에 있는 상위클래스로부터 상속받은 메소드를 하위클래스에서 그대로 사용하지 않고, 하위클래스에 맞게 내용을 변경하는(메소드의 내용을 재정의하는) 것이다.

메소드 재정의의 예제

  • 상위 클래스 Printer로부터 상속받은 void print() 기능을 하위 클래스에서 그 클래스에 적합하게 void print() 메소드의 내용을 재정의 하기
  public class Printer {
    void print() {
      // 흑백으로 인쇄
    }
  }
  
  // Printer클래스의 하위 클래스
  public class ColorPrinter extends Printer {
    // 메소드 재정의
    void print() {
      컬러로 인쇄
    }
  }
  
  // Printer클래스의 하위 클래스
  public class LaserPrinter extends Printer {
    // 메소드 재정의
    void print() {
      레이저로 인쇄
    }
  }
  • Printer 및 Printer 클래스의 하위 클래스 사용하기
  public static void main(String[] args) {
    Printer p1 = new Printer();
    p1.print();   // 흑백인쇄
    
    ColorPrinter p2 = new ColorPrinter();
    p2.print();   // 컬러인쇄
    
    LaserPrinter p3 = new LaserPrinter();
    p3.print();   // 레이저인쇄
  }

this와 super

0개의 댓글