1.  객체 타입 확인

boolean result = 객체 instance of 타입;

 

🚀  매개변수의 다형성에서 실제로 어떤 객체가 매개값으로 제공되었는지 확인할 때 사용

🚀  꼭 매개변수가 아니더라도 변수가 참조하는 객체의 타입을 확인하고자 할 때 instance of 연산자를 사용할 수 있다

  • 좌항에는 객체가 오고 우항에는 타입이 위치
  • 좌항의 객체가 우항의 타입이 일치하면 true를 산출하고 그렇지 않으면 false를 산출
if(parent instance of Child child) {
    // child 변수 사용
}

 

사용 예제

 

public class Person {
	//필드 선언
	public String name;

	//생성자 선언
	public Person(String name) {
		this.name = name;
	}

	//메소드 선언
	public void walk() {
		System.out.println("걷습니다.");
	}
}
public class Student extends Person {
	//필드 선언
	public int studentNo;

	//생성자 선언
	public Student(String name, int studentNo) {
		super(name);
		this.studentNo = studentNo;
	}

	//메소드 선언
	public void study() {
		System.out.println("공부를 합니다.");
	}
}

 

public class InstanceofExample {

	//main() 메소드에서 바로 호출하기 위해 정적 메소드 선언
	public static void personInfo(Person person) {
		System.out.println("name: " + person.name);
		person.walk();

		//person이 참조하는 객체가 Student 타입인지 확인
		/*if (person instanceof Student) {
        
 			//Student 객체일 경우 강제 타입 변환
 			Student student = (Student) person;
            
 			//Student 객체만 가지고 있는 필드 및 메소드 사용
 			System.out.println("studentNo: " + student.studentNo);
 			student.study();
            
 		}*/

		// person이 참조하는 객체가 Student 타입일 경우
		// student 변수에 대입(타입 변환 발생)- java 12~
		if(person instanceof Student student) {
			System.out.println("studentNo: " + student.studentNo);
			student.study();
		}
	}

	public static void main(String[] args) {
		//Person 객체를 매개값으로 제공하고 personInfo() 메소드 호출
		Person p1 = new Person("홍길동");
		personInfo(p1);
		
		System.out.println();

		//Student 객체를 매개값으로 제공하고 personInfo() 메소드 호출
		Person p2 = new Student("김길동", 10);
		personInfo(p2);
	}
    
}

 

 

 

* 내용 참고 - 책 '이것이 자바다'

'Programming Language > JAVA' 카테고리의 다른 글

[Java] 다형성  (0) 2024.08.24
[Java] 타입 변환  (0) 2024.08.24
[Java] final 클래스와 final 메소드 · protected 접근 제한자  (0) 2024.08.23
[Java] 오버라이딩 Overriding  (0) 2024.08.11
[Java] 상속 Inheritance  (0) 2024.08.11


 

1.  다형성  polymorphism

🚀  사용 방법은 동일하지만 실행 결과가 다양하게 나오는 성질을 말함

🚀  객체는 부품과 같아서 프로그램을 구성하는 객체를 바꾸면 프로그램의 실행 성능이 다르게 나올 수 있다.

 

  • 객체 사용 방법이 동일하다는 것은 동일한 메소드를 가지고 있다는 뜻
  • 한국 타이어와 금호 타이어는 모두 타이어를 상속하고 있으므로 부모의 메소드를 동일하게 가지고 있다고 말할 수 있다.
  • 타이어 메소드 호출 시 오버라이딩 된 메소드가 호출되는데, 오버라이딩 된 내용은 두 타이어가 다르기 때문에 실행 결과가 다르게 나옴
  • 이것을 '다형성' 이라고 하는데 다형성을 구현하기 위해서는 자동 타입 변환과 메소드 재정의가 필요하다.


1)  필드 다형성

  👾  필드 타입은 동일하지만(사용 방법은 동일하지만) 대입되는 객체가 달라져서 실행 결과가 다양하게 나올 수 있는 것을 말한다.

 

public class Car {
	//필드 선언
	public Tire tire;

	//메소드 선언
	public void run() {
		//tire 필드에 대입된 객체의 roll() 메소드 호출
		tire.roll();
	}
}
public class Tire {
	//메소드 선언
	public void roll() {
		System.out.println("회전합니다.");
	}
}

 

public class HankookTire extends Tire {
	//메소드 재정의(오버라이딩)
	@Override
	public void roll() {
		System.out.println("한국 타이어가 회전합니다.");
	}
}
public class KumhoTire extends Tire {
	//메소드 재정의(오버라이딩)
	@Override
	public void roll() {
		System.out.println("금호 타이어가 회전합니다.");
	}
}

 

public class CarExample {
	public static void main(String[] args) {
		//Car 객체 생성
		Car myCar = new Car();

		//Tire 객체 장착
		myCar.tire = new Tire();
		myCar.run();

		//HankookTire 객체 장착
		myCar.tire = new HankookTire();
		myCar.run();

		//KumhoTire 객체 장착
		myCar.tire = new KumhoTire();
		myCar.run();
	}
}

 

  • Car 클래스의 run() 메소드는 tire 필드에 대입된 객체의 roll() 메소드를 호출한다.
  • 어떤 타이어를 장착했는지에 따라 roll() 메소드의 실행 결과는 달라지게 된다. 이것이 바로 '필드의 다형성'이라고 함

 

2)  매개변수 다형성

  👾  다형성은 필드보다는 메소드를 호출할 때 많이 발생함

  👾  메소드가 클래스 타입의 매개변수를 가지고 있을 경우, 호출할 때 동일한 타입의 객체를 제공하는 것이 정석이지만 자식 객체를 제공할 수도 있다.

 

public class Driver {
    public void drive(Vehicle vehicle) {
      vehicle.run();
    }
}
  • drive() 메소드는 매개값으로 전달받은 vehicle의 run() 메소드를 호출함
Driver driver = new Driver();
Vehicle vehicle = new Vehicle();
driver.drive(vehicle);

 

  • 일반적으로 drive() 메소드를 호출한다면 위와 같이 Vehicle의 객체를 제공
  • but, 자동 타입 변환으로 인해 매개값으로 Vehicle의 자식 객체도 제공할 수 있음!

  ⚡️  drive() 메소드는 매개변수 vehicle이 참조하는 객체의 run() 메소드를 호출하는데, 자식 객체가 run() 메소드를 재정의하고 있다면 재정의된 run() 메소드가 호출된다.

      ☑️  어떤 자식 객체가 제공하느냐에 따라 drive() 실행 결과는 달라진다. 이것이 '매개변수의 다형성'

 

public class Vehicle {
	//메소드 선언
	public void run() {
		System.out.println("차량이 달립니다.");
	}
}
public class Bus extends Vehicle {
	//메소드 재정의(오버라이딩)
	@Override
	public void run() {
		System.out.println("버스가 달립니다.");
	}
}
public class Taxi extends Vehicle {
	//메소드 재정의(오버라이딩)
	@Override
	public void run() {
		System.out.println("택시가 달립니다.");
	}
}
public class Driver {
	//메소드 선언(클래스 타입의 매개변수를 가지고 있음)
	public void drive(Vehicle vehicle) {
		vehicle.run();
	}
}
public class DriverExample {
	public static void main(String[] args) {
		//Driver 객체 생성
		Driver driver = new Driver();

		//매개값으로 Bus 객체를 제공하고 driver() 메소드 호출
		Bus bus = new Bus();
		driver.drive(bus);

		//매개값으로 Taxi 객체를 제공하고 driver() 메소드 호출
		Taxi taxi = new Taxi();
		driver.drive(taxi);
	}
}

 

 

응용 예제
public class Product {
    int price; // 제품의 가격
    int bonusPoint; // 제품구매 시 제공하는 보너스 점수

    Product(int price){
        this.price = price;
        this.bonusPoint = (int)(price / 10.0); // 보너스점수는 제품가격의 10%
    }
}

 

public class Tv extends Product{
    Tv () {
        // 부모클래스의 생성자 Product(int price)를 호출한다.
        super(100); // Tv의 가격을 100만원으로 한다.
    }

    @Override
    public String toString() {
        return "Tv";
    }
}
public class Audio extends Product{
    Audio() {
        super(50);
    }

    @Override
    public String toString() {
        return "Audio";
    }
}
public class Computer extends Product{
    Computer () {
        super(200);
    }

    @Override
    public String toString() {
        return "Computer";
    }
}

 

1. Object 클래스 상속:
    -  모든 Java 클래스는 자동으로 Object 클래스를 상속받는다. Object 클래스는 모든 클래스의 최상위 부모 클래스이고, 이 클래스에서 제공하는 여러 메서드들이 모든 클래스에서 사용할 수 있게 된다. 그 중 하나가 toString() 메서드

2. toString() 메서드:
    -  Object 클래스에는 이미 toString() 메서드가 정의되어 있기 때문에, 어떤 클래스든 toString() 메서드를 오버라이딩할 수 있다. 따라서, Product 클래스에 따로 toString() 메서드를 정의하지 않더라도, Tv 클래스에서 이 메서드를 오버라이딩하는 것이 가능

 

public class Buyer { // 고객, 물건을 사는 사람
        int money = 1000; // 소유금액
        int bonusPoint = 0; // 보너스점수

        /* Product[] products = new Product[10]; // 구입한 제품을 저장하기 위한 배열
        int i = 0; // Product 배열에 사용될 카운터 */
        
        ArrayList<Product> products = new ArrayList<>();

        void buy (Product product){ // 부모클래스 타입으로 매개변수 받음.
            // 부모 클래스의 필드 사용. price, bonusPoint
            if (money < product.price) {
                System.out.println("잔액이 부족하여 물건을 살 수 없습니다.");
                return;
            }
            money -= product.price;  // 가진 돈에서 구입한 제품의 가격을 뺀다.
            bonusPoint += product.bonusPoint; // 제품의 보너스 점수를 추가한다.
            products.add(product); // 구입한 제품을 ArrayList에 저장한다.
            System.out.println(product + " 을/를 구입하셨습니다.");
        }
        
        void summary () { // 구매한 물품에 대한 정보를 요약해서 보여 준다.
            int sum = 0; // 구입한 물품의 가격합계
            String itemList = ""; // 구입한 물품목록

            if(products.isEmpty()) { // ArrayList가 비어있는지 확인한다.
                System.out.println("구입하신 제품이 없습니다.");
                return;
            }
            // ArrayList의 i번째에 있는 객체를 얻어 온다.
            for(int i =0; i < products.size(); i++) {
                Product product = products.get(i);
                sum += product.price;
                itemList += (i==0) ? "" + product : ", " + product;
            }


          /*  // 반복문을 이용해서 구입한 물품의 총 가격과 목록을 만든다.
            // 1) for 이용
            for (int i = 0; i < products.length; i++) {
                if (products[i] == null)
                    break;
                sum += products[i].price;
                itemList += products[i] + ", ";
            }
            // 2) foreach 사용
            // for(각 요소의 타입과 요소를 담을 변수 : 배열 또는 컬렉션)
            for (Product product : products) {
                if (product == null)
                    break;
                sum += product.price;
                itemList += product + ", ";
            }

            // 3) 반복을 줄이기 위해 인스턴스 변수 사용
            for (int i = 0; i < this.i; i++) {
                sum += products[i].price;
                itemList += products[i] + ", ";
            } */

            System.out.println("구입하신 물품의 총금액은 " + sum + "만원입니다.");
            System.out.println("구입하신 제품은 " + itemList + "입니다.");
        }

        void refund(Product product) { // 구입한 제품을 환불한다.
            if (products.remove(product)) { // 제품을 ArrayList에서 제거한다.
                money += product.price;
                bonusPoint -= product.bonusPoint;
                System.out.println(product + "을/를 반품하셨습니다.");
            } else { // 제거에 실패한 경우
                System.out.println("구입하신 제품 중 해당 제품이 없습니다.");
            }
        }
        
}
public class Test {
    /*
    코딩 순서 : Product -> Tv -> Computer -> Buyer -> Test
     */
    public static void main(String[] args) {
        Buyer b = new Buyer();
        Tv tv = new Tv();
        Computer com = new Computer();
        Audio audio = new Audio();

        b.buy(tv); // Tv 을/를 구입하셨습니다.
        b.buy(com); // Computer 을/를 구입하셨습니다.
        b.buy(audio); // Audio 을/를 구입하셨습니다.
        b.summary(); // 구입하신 물품의 총금액은 350만원입니다. 구입하신 제품은 Tv, Computer, Audio입니다.
        System.out.println(); 
        b.refund(com); // Computer을/를 반품하셨습니다.
        b.summary(); // 구입하신 물품의 총금액은 150만원입니다. 구입하신 제품은 Tv, Audio입니다.
    }
}

 

 

 

 

* 내용 참고 - 책 '이것이 자바다' 및 학원 강의 자료


1.  타입 변환

⚒️  타입을 다른 타입으로 변환하는 것을 말함

⚒️  클래스의 타입 변환은 상속 관계에 있는 클래스 사이에서 발생

 

 

1)  자동 타입 변환  Promotion

부모타입 변수 = 자식타입객체;

 

  📍 자식은 부모의 특징과 기능을 상속받기 때문에 부모와 동일하게 취급될 수 있다.

Cat cat = new Cat();
Animal animal = cat;

  📍  cat과 animal 변수는 타입만 다를 뿐, 동일한 Cat 객체를 참조

cat == animal  // true

class A {
}

class B extends A {
}

class C extends A {
}

class D extends B {
}

class E extends C {
}

public class PromotionExample {
	public static void main(String[] args) {
		B b = new B();
		C c = new C();
		D d = new D();
		E e = new E();

		A a1 = b;
		A a2 = c;
		A a3 = d;
		A a4 = e;
		
		B b1 = d;
		C c1 = e;
		
		// B b3 = e;
		// C c2 = d;
	}
}

 

  • 부모 타입으로 자동 타입 변환된 이후에는 부모 클래스에 선언된 필드와 메소드만 접근이 가능
  • 변수는 자식 객체를 참조하지만 변수로 접근 가능한 멤버는 부모 클래스 멤버로 한정
  • 자식 클래스에서 오버라이딩된 메소드가 있다면 부모 메소드 대신 오버라이딩된 메소드가 호출됨


 

2)  강제 타입 변환  Casting

자식타입 변수 = (자식타입) 부모타입객체;
Parent parent = new Child();   // 자동 타입 변환
Child child = (Child) parent;  // 강제 타입 변환

 

⚒️  부모 타입은 자식 타입으로 자동 변환되지 않는다. 대신 캐스팅 연산자로 강제 타입 변환을 할 수 있다.

⚒️  자식 객체가 부모 타입으로 자동 변환하면 부모 타입에 선언된 필드와 메소드만 사용 가능  

       ➡️  만약 자식 타입에 선언된 필드와 메소드를 꼭 사용해야 한다면 강제 타입 변환을 해서 다시 자식타입으로 변환해야 함

 

 

 

 

 

 

* 내용 참고 - 책 '이것이 자바다'

 


 

1.  final 클래스와 final 메소드

1)  final 클래스

public final class 클래스 { ... }

 

🚀  클래스를 선언할 때 final 키워드를 class 앞에 붙이면 최종적인 클래스이므로 더 이상 상속할 수 없는 클래스가 됨

 

 

2)  final 메소드 

public final 리턴타입 메소드( 매개변수, ...) { ... }

 

🚀  메소드를 선언할 때 final 키워드를 붙이면 이 메소드는 최종적인 메소드이므로 오버라이딩할 수 없는 메소드가 됨

 

 


2.  protected 접근 제한자

 

🚀  같은 패키지에서는 default처럼 접근이 가능하나, 다른 패키지에서는 자식 클래스만 접근을 허용

package package1;

public class A {
	//필드 선언
	protected String field;

	//생성자 선언
	protected A() {
	}

	//메소드 선언
	protected void method() {
	}
}

 

같은 패키지
package package1;

public class B {
	//메소드 선언
	public void method() {
		A a = new A();		//o
		a.field = "value"; 	//o
		a.method(); 			//o
	}
}

 

다른 패키지
package package2;

import package1.A;

public class C {
	//메소드 선언
	public void method() {
		//A a = new A();		//x
		//a.field = "value"; 		//x
		//a.method(); 			//x
	}
}

 

다른 패키지 & 자식 클래스
package package2;

import package1.A;

public class D extends A {
	//생성자 선언
	public D() {
		//A() 생성자 호출
		super();				//o
	}
	
	//메소드 선언
	public void method1() {
		//A 필드값 변경
		this.field = "value"; 	//o
		//A 메소드 호출
		this.method(); 			//o
	}
	
	//메소드 선언
	public void method2() {
		//A a = new A();		//x
		//a.field = "value"; 	//x
		//a.method(); 			//x
	}	
}

 

  ⚡️  new 연산자를 사용해서 생성자를 직접 호출할 수는 없고, 자식 생성자에서 super()로 A 생성자를 호출할 수 있다.

 

 

 

 

 

* 내용 참고 : 책 '이것이 자바다'

'Programming Language > JAVA' 카테고리의 다른 글

[Java] 다형성  (0) 2024.08.24
[Java] 타입 변환  (0) 2024.08.24
[Java] 오버라이딩 Overriding  (0) 2024.08.11
[Java] 상속 Inheritance  (0) 2024.08.11
[Java] Getter와 Setter · 싱글톤 패턴  (0) 2024.08.11


1.  메소드 재정의

👩🏻‍💻  부모 클래스의 어떤 메소드는 자식 클래스가 사용하기에 적합하지 않을 수 있다.

        ➡️  이러한 메소드는 자식 클래스에서 재정의해서 사용해야한다. 이것을 메소드 오버라이딩이라고 함

 

1)  메소드 오버라이딩

  👾  상속된 메소드를 자식 클래스에서 재정의하는 것을 말함

  👾  메소드가 오버라이딩되었다면 해당 부모 메소드는 숨겨지고, 자식 메소드가 우선적으로 사용됨

 

💡  오버라이딩 규칙
       1.  부모 메소드의 선언부(리턴 타입, 메소드 이름, 매개 변수)와 동일해야 한다
       2.  접근 제한을 더 강하게 오버라이딩 할 수 없다. ( public → private 변경 불가 )
       3.  새로운 예외를 throws 할 수 없다.

 

public class Calculator {
	//메소드 선언
	public double areaCircle(double r) {
		System.out.println("Calculator 객체의 areaCircle() 실행");
		return 3.14159 * r * r;
	}
}
public class Computer extends Calculator {
	//메소드 오버라이딩
	@Override
	public double areaCircle(double r) {
		System.out.println("Computer 객체의 areaCircle() 실행");
		return Math.PI * r * r;
	}
}
public class ComputerExample {
	public static void main(String[] args) {
		int r = 10;

		Calculator calculator = new Calculator();
		System.out.println("원 면적: " + calculator.areaCircle(r));
		System.out.println();

		Computer computer = new Computer();
		System.out.println("원 면적: " + computer.areaCircle(r));
	}
}
// 실행 결과
Calculator 객체의 areaCircle() 실행
원 면적: 314.159

Computer 객체의 areaCircle() 실행
원 면적: 314.1592653589793

 

  📍  자바는 개발자의 실수를 줄여주기 위해 정확히 오버라이딩 되었는지 체크해주는 @Override 어노테이션을 제공한다.

         ➡️  문제가 있다면 컴파일 에러를 출력함

 


2)  부모 메소드 호출

  👾  메소드를 재정의하면 부모 메소드는 숨겨지고 자식 메소드만 사용되기 때문에 비록 부모 메소드의 일부만 변경된다 하더라도 중복된 내용을 자식 메소드도 가지고 있어야 한다.

  👾  이 문제는 자식 메소드와 부모 메소드의 공동 작업 처리 기법을 이용하면 해결됨

  • super.method()의 위치는 작업 처리2 전후에 어디든지 올 수 있다. 우선 처리가 되어야 할 내용을 먼저 작성하면 됨.
  • 이 방법은 부모 메소드를 재사용함으로써 자식 메소드의 중복 작업 내용을 없애는 효과를 가져옴
public class Airplane {
	//메소드 선언
	public void land() {
		System.out.println("착륙합니다.");
}

	public void fly() {
		System.out.println("일반 비행합니다.");
	}

	public void takeOff() {
		System.out.println("이륙합니다.");
	}
}
public class SupersonicAirplane extends Airplane {
	//상수 선언
	public static final int NORMAL = 1;
	public static final int SUPERSONIC = 2;
	//상태 필드 선언
	public int flyMode = NORMAL;

	//메소드 재정의
	@Override
	public void fly() {
		if(flyMode == SUPERSONIC) {
			System.out.println("초음속 비행합니다.");
		} else {
			//Airplane 객체의 fly() 메소드 호출
			super.fly();
		}
	}
}
public class SupersonicAirplaneExample {
	public static void main(String[] args) {
		SupersonicAirplane sa = new SupersonicAirplane();
		sa.takeOff();
		sa.fly();
		sa.flyMode = SupersonicAirplane.SUPERSONIC;
		sa.fly();
		sa.flyMode = SupersonicAirplane.NORMAL;
		sa.fly();
		sa.land();
	}
}
// 실행결과
이륙합니다.
일반 비행합니다.
초음속 비행합니다.
일반 비행합니다.
착륙합니다.

 

 

 

* 내용 참고 - 책 '이것이 자바다'


1.  상속  inheritance

✏️  부모가 자식에게 물려주는 행위를 말함

  

  👾  상속은 이미 잘 개발된 클래스를 재사용해서 새로운 클래스를 만들기 때문에 중복되는 코드를 줄여 개발 시간을 단축시킨다.

  👾  자식 클래스에 새로운 코드가 추가되어도 부모 클래스는 아무런 영향을 받지 않는다.

         but, 조상클래스가 변경되면 자손클래스는 자동적으로 영향을 받게 됨. ( = 조상 클래스의 모든 멤버를 상속 받음 )

  👾  부모 클래스를 확장(extend) 한다는 의미로 상속에 사용되는 키워드가 'extends'이다.

  👾  자식 클래스의 인스턴스를 생성하면 부모 클래스의 멤버와 자손 클래스의 멤버가 합쳐진 하나의 인스턴스로 생성됨

class Person { // 사람 클래스
    void breath() {
        System.out.println("숨쉬기");
    }

    void eat() {
        System.out.println("밥먹기");
    }

    void say() {
        System.out.println("말하기");
    }
}

class Student extends Person{ // 사람 클래스를 상속한 학생 클래스
    void learn(){
        System.out.println("배우기");
    }
}

class Teacher extends Person{ // 사람 클래스를 상속한 선생 클래스
    void teach(){
        System.out.println("가르치기");
    }
}
public class Test {
    public static void main(String[] args) {
        Student student = new Student(); // 학생 인스턴스 student 생성
        student.breath(); // 사람 클래스의 breath 메서드를 상속 받았음.
        student.learn();
        student.say();

        Teacher teacher = new Teacher(); // 선생 인스턴스 teacher 생성
        teacher.eat(); // 사람 클래스의 eat 메서드를 상속 받았음
        teacher.teach();
        teacher.say();

        Person person = new Person();
        person.breath();
   //     person.learn(); // 자식 클래스의 메서드나 멤버 변수는 사용하지 못함.
    }
}

 


1)  클래스 상속

  ⚒️  자식 클래스를 선언할 때 어떤 부모로부터 상속받을 것인지를 결정하고, 부모 클래스를 extends 뒤에 기술

  ⚒️  다른 언어와 달리 자바는 다중 상속 허용 X. 단 하나의 부모 클래스만 상속 받을 수 있다!

public class Phone {
	//필드 선언
	public String model;
	public String color;

	//메소드 선언
	public void bell() {
		System.out.println("벨이 울립니다.");
	}

	public void sendVoice(String message) {
		System.out.println("자기: " + message);
	}
	
	public void receiveVoice(String message) {
		System.out.println("상대방: " + message);
	}

	public void hangUp() {
		System.out.println("전화를 끊습니다.");
	}
}
public class SmartPhone extends Phone {
	//필드 선언
	public boolean wifi;

	//생성자 선언
	public SmartPhone(String model, String color) {
		this.model = model;
		this.color = color;
	}

	//메소드 선언
	public void setWifi(boolean wifi) {
		this.wifi = wifi;
		System.out.println("와이파이 상태를 변경했습니다.");
	}

	public void internet() {
		System.out.println("인터넷에 연결합니다.");
	}
}
public class SmartPhoneExample {

	public static void main(String[] args) {
		//SmartPhone 객체 생성
		SmartPhone myPhone = new SmartPhone("갤럭시", "은색");

		//Phone으로부터 상속받은 필드 읽기
		System.out.println("모델: " + myPhone.model);
		System.out.println("색상: " + myPhone.color);

		//SmartPhone의 필드 읽기
		System.out.println("와이파이 상태: " + myPhone.wifi);

		//Phone으로부터 상속받은 메소드 호출
		myPhone.bell();
		myPhone.sendVoice("여보세요.");
		myPhone.receiveVoice("안녕하세요! 저는 홍길동인데요.");
		myPhone.sendVoice("아~ 네, 반갑습니다.");
		myPhone.hangUp();
		
		//SmartPhone의 메소드 호출
		myPhone.setWifi(true);
		myPhone.internet();
	}
}

 


2)  부모 생성자 호출

  ⚒️  자식 객체를 생성하면 부모 객체가 먼저 생성된 다음에 자식 객체가 생성된다.

 

  ⚡️ 부모 생성자는 자식 생성자의 맨 첫 줄에 숨겨져 있는 super()에 의해 호출된다.

  ⚡️ super()는 컴파일 과정에서 자동 추가되는데, 이것은 부모의 기본 생성자를 호출한다.

         ➡️  만약 부모 클래스에 기본 생성자가 없다면 자식 생성자 선언에서 컴파일 에러가 발생

         ➡️  기본 생성자는 없고 매개변수를 갖는 생성자만 있다면 super(매개값, ...) 코드를 직접 넣어야 함

// 자식 생성자 선언
public 자식클래스(...) {
  super(); // 생략 가능
  ...
}

public 자식클래스(...) {
  super(매개값, ...); // 생략 불가
  ...
}

 

기본 생성자를 가지고 있는 경우
public class Phone {
	//필드 선언
	public String model;
	public String color;

	//기본 생성자 선언
	public Phone() {
		System.out.println("Phone() 생성자 실행");
	}
}
public class SmartPhone extends Phone {
	//자식 생성자 선언
	public SmartPhone(String model, String color) {
		super();
		this.model = model;
		this.color = color;
		System.out.println("SmartPhone(String model, String color) 생성자 실행됨");
	}
}
public class SmartPhoneExample {

	public static void main(String[] args) {
		//SmartPhone 객체 생성
		SmartPhone myPhone = new SmartPhone("갤럭시", "은색");
			
		//Phone으로부터 상속 받은 필드 읽기
		System.out.println("모델: " + myPhone.model);
		System.out.println("색상: " + myPhone.color);
	}
}
// 실행 결과
Phone() 생성자 실행
SmartPhone(String model, String color) 생성자 실행됨
모델: 갤럭시
색상: 은색

 

매개변수를 갖는 생성자가 있는 경우
public class Phone {
	//필드 선언
	public String model;
	public String color;

	//매개변수를 갖는 생성자 선언
	public Phone(String model, String color) {
		this.model = model;
		this.color = color;
		System.out.println("Phone(String model, String color) 생성자 실행");
	}
}
public class SmartPhone extends Phone {
	//자식 생성자 선언
	public SmartPhone(String model, String color) {
		super(model, color);
		System.out.println("SmartPhone(String model, String color) 생성자 실행됨");
	}
}
public class SmartPhoneExample {
	
	public static void main(String[] args) {
		//SmartPhone 객체 생성
		SmartPhone myPhone = new SmartPhone("갤럭시", "은색");
		
		//Phone으로부터 상속 받은 필드 읽기
		System.out.println("모델: " + myPhone.model);
		System.out.println("색상: " + myPhone.color);
	}
}
// 실행 결과
Phone(String model, String color) 생성자 실행
SmartPhone(String model, String color) 생성자 실행됨
모델: 갤럭시
색상: 은색

 

 

 

* 내용 참고 - 책 '이것이 자바다'

+ Recent posts