/////
Search

220926

작성자
김지영
김희정
이현주
날짜
2022/09/26
학습 내용
상속,오버로딩,오버라이딩,다형성
텍스트

11. 상속_김희정

상속이란?

부모 클래스로부터 자식클래스가 필드와 메소드 등을 물려받는 것
대개 부모 클래스는 추상적이고, 서브 클래스는 구체적
UML에서 자식 클래스 → 부모 클래스
상속은 is-a 관계
ex) 자동차는 탈것이다. (Car is a Vehicle)
ex) 대학원생, 학부생은 학생이다.
has-a 관계는 상속x (ex. 도서관은 책을 가지고 있다. 직선은 양 끝점을 가지고 있다.)

상속 문법

extends 키워드
클래스 정의 다음에 extends 를 써주고 부모 클래스 이름을 적음.
class Car{ int speed; public void setSpeed(int speed){ this.speed = speed; } } class SportsCar extends Car{ boolean turbo; public setTurbo(boolean newValue){ turbo = newValue; } }
Java
복사

상속에서의 접근 지정자 protected

자식 클래스는 부모 클래스의 private를 제외한 모든 멤버들을 전부 상속받음.

protected

protected는 자식 클래스에서만 접근 가능
상속 시, 다른 패키지에 있는 자식클래스에서도 접근 가능

상속을 사용하는 이유

1.
상속은 중복을 줄인다.
2.
이미 존재하는, 검증된 클래스의 필드와 메소드를 재사용할 수 있어 신뢰성 있는 SW 개발, 유지 보수 가능

super

부모 클래스의 메소드나 필드를 명시적으로 참조하기 위해 사용
메소드 재정의 시, 부모 클래스 메소드에 내용 추가하는 경우 주로 사용
class Employee { private String name; private int age; private String addr; private String team; protected int salary; public Employee(String name, int age, String addr, String team) { this.name = name; this.age = age; this.addr = addr; this.team = team; } public void printInfo(){ System.out.println("이름 : " + name); System.out.println("나이 : " + age); System.out.println("주소 : " + addr); System.out.println("부서 : " + team); } } class Regular extends Employee{ public Regular(String name, int age, String addr, String team) { super(name, age, addr, team); } public void setSalary(int salary) { this.salary = salary; } @Override public void printInfo(){ super.printInfo(); System.out.println("정규직"); System.out.println("월급 : " + salary); } }
Java
복사

상속과 생성자

생성자 호출 순서

부모 클래스 생성자→자식 클래스 생성자
>> 부모 클래스가 먼저 메모리에 올라가기 때문에 부모 클래스 생성자가 먼저 실행

생성자 호출 방식

1.
명시적인 호출 - super()
부모 클래스 생성자 호출은 반드시 생성자의 첫 줄이어야 함.
class Parent{ public Parent(){ System.out.println("부모 생성자"); } } class Child extends Parent{ public Child(){ super(); System.out.println("자식 생성자"); } }
Java
복사
2.
묵시적인 호출
부모 클래스 생성자를 super() 같이 명시적으로 호출하지 않아도 컴파일러가 자동으로 호출해줌.
class Parent{ public Parent(){ System.out.println("부모 생성자"); } } class Child extends Parent{ public Child(){ System.out.println("자식 생성자"); } }
Java
복사

파라미터에 따른 부모 클래스 생성자

파라미터에 따라 생성자가 선택됨.
오류 Case
class Shape{ public Shape(String msg){ System.out.println("shape 생성자" + msg); } } class Rectangle extends Shape{ public Rectangle() { System.out.println("Rectangle 생성자"); } }
Java
복사
1.
Rectangle에서 부모 클래스인 Shape의 생성자 묵시적인 호출 시도
2.
자바가 자동적으로 디폴트 생성자를 추가하고 호출하려는데, 이미 Shape의 생성자가 정의되어 있기 때문에 디폴트 생성자가 자동 생성x >> 오류!
디폴트 생성자를 습관적으로 생성해야함!

12. 메소드오버라이딩

메소드 재정의(@Override)

메소드 오버라이딩은 상속된 메소드의 내용을 재정의하는 것을 말한다.
class Shape { public void shape() { System.out.println("도형입니다."); } public void draw() { System.out.println("도형을 그립니다."); } } //상속관계에서 부모의 함수을 재정의하는것(바디만 달리하는것) class Rectangle extends Shape { public Rectangle() { System.out.println("사각형 생성자"); } @Override public void draw() { System.out.println("사각형을 그립니다."); } } class Trangle extends Shape { public Trangle() { System.out.println("삼각형 생성자"); } @Override public void draw() { System.out.println("삼각형을 그립니다."); } } public class OverrideTest { public static void main(String[] args) { // 1번 Shape shape = new Shape(); shape.draw(); Rectangle rc = new Rectangle(); rc.draw(); Shape shape2 = new Rectangle(); shape2.draw(); } }
Java
복사
메소드가 재정의되었다면 부모 객체의 메소드는 숨겨지기 때문에 자식 객체에서 메소드를 호출하면 재정의된 자식 메소드가 호출된다.

메소드 오버라이딩 할 때에 주의점

부모의 메소드와 동일한 리턴타입,메소드 이름, 매개 변수 리스트)를 가져야한다.
접근 제한을 더 강하게 오버라이딩 할 수 없다.
접근 제한을 더 강하게 오버라이딩 할 수 없다는 것은 부모 메소드가 public 접근 제한을 가지고 있을 경우 오버라이딩하는 자식 메소드는 default나 private 접근 제한으로 수정할 수 없다는 뜻이다.
반대는 가능하다. 부모 메소드가 default 접근 제한을 가지면 재정의되는 자식 메소드는 default 또는 public 접근 제한을 가질 수 있다.

오버로딩(Overloading)

1.
메서드 이름이 같아야 한다.
2.
매개변수의 개수 또는 타입이 달라야 한다.
메서드의 이름이 같다 하더라도 매개변수가 다르면 서로 구별될 수 있기 때문에 오버로딩이 가능한 것이다.
위의 조건을 만족시키지 못하는 메서드는 중복 정의로 간주되어 컴파일 시에 에러가 발생한다. 그리고 오버로딩된 메서드들은 매개변수에 의해서만 구별될 수 있으므로 반환타입은 오버로딩을 구현하는데 아무런 영향을 주지 못한다는 것에 주의
(이름이 cat인 메서드가 총 3개 있지만 매개변수의 유형과 개수가 다름)
오버로딩의 가장 대표적인 예가 자주 사용하는 println메서드이다. 지금까지 println메서드의 괄호 안에 값만 지정해주면 화면에 출력하는데 아무런 어려움이 없었다. 하지만, 실제로는 println메서드를 호출할 때 매개변수로 지정하는 값의 타입에 따라서 호출되는 println메서드가 달라진다.
PrintStream클래스에서는 어떤 종류의 매개변수를 지정해도 출력할 수 있도록 아래와 같이 10개의 오버로딩 된 println 메서드를정의해놓고 있다.
void println(); void println(boolean x); void println(char x); void println(char[] x); void println(double x); void println(float x); void println(int x); void println(long x); void println(object x); void println(String x);
Java
복사
println메서드를 호출할 때 매개변수로 넘겨주는 값의 타입에 따라서 위의 오버로딩된 메서드들 중의 하나가 선택되어 실행되는 것이다.

13. 다형성

객체 지향의 원리: 다형성 (Polymorphism)

1. 개념

하나의 부모 타입”의 참조 변수가 “여러 개의 자식 타입”의 인스턴스(객체)를 가질 수 있는 성질을 의미한다.
프로그램 언어의 다형성은 그 프로그래밍 언어의 자료형 체계의 성질을 나타내는 것으로, 프로그램 언어의 각 요소들(상수, 변수, 식, 오브젝트, 함수, 메소드 등)이 다양한 자료형(type)에 속하는 것이 허가되는 성질을 가리킨다.  [위키백과]

2. 구현방식

자바 문법에서 다형성은 부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조하는 방식으로 구현된다. 이것을 업캐스팅(upcasting, 상형 형변환)이라고 한다.
Shape s1 = new Shape(); Shape s2 = new Circle();
Java
복사

3. 필수 조건

상속 관계
부모-자식 클래스 간 상속 관계가 이루어져야 한다.
메소드 오버라이딩
하위 클래스 내 메소드 함수가 재정의되어야 한다.
업캐스팅
부모 클래스 타입으로 자식 클래스 객체를 생성하여 형변환하여야 한다.

4. PPT 예제

class MobilePhone { protected String number; public MobilePhone(String num) { number = num; } public void answer(){ System.out.println("Hi~from " + number); } } class SmartPhone extends MobilePhone{ private String androidVer; public SmartPhone(String num, String ver) { super(num); androidVer = ver; } public void playApp() { System.out.println("App is running in " + androidVer); } } public class Phone { public static void main(String[] args) { SmartPhone ph1 = new SmartPhone("010-555-7777", "Nougat"); MobilePhone ph2 = new SmartPhone("010-999-3333", "Nougat"); ph1.answer(); //Hi~from 010-555-7777 ph1.playApp(); //App is running in Nougat System.out.println(); ph2.answer(); //Hi~from 010-999-3333 ph2.playApp(); //컴파일 에러 } }
Java
복사

5. 다형성의 장점

코드 작성 시 다형성을 고려하여 작성하면 유연하고 확장성 있으며 유지보수가 간편해진다.
다형성을 적용하는 것이 코드 설계의 효율성을 가져온다.
부모 클래스 타입으로 선언할 경우, 훨씬 넓은 범위의 객체를 받을 수 있고 자식 클래스 객체를 일일히 생성해야 하는 수고를 덜어준다.

+ instanceof 연산자

//문법 객체 instanceof 타입 //사용 예 if (ph1 instanceof SmartPhone) { System.out.println("TRUE"); } else { System.out.println("FALSE"); } // "TRUE" 출력 if (ph2 instanceof SmartPhone) { System.out.println("TRUE"); } else { System.out.println("FALSE"); } // "TRUE" 출력 if (ph2 instanceof MobilePhone) { System.out.println("TRUE"); } else { System.out.println("FALSE"); } // "TRUE" 출력
Java
복사
참조 변수가 실제 참조하고 있는 인스턴스 객체의 타입을 확인할 수 있다.