지난 시간에 배웠던 것
-> 캡슐화 != 은닉성
-> 접근 지정자 private , public
캡슐화, 상속성, 다형성 <_ 정석적 표현
은닉성 상속성 다형성 <_ 실용적 표현
상속성 (inheritance)
부모 클래스와 자식 클래스를 생성하기
부모 클래스에 있는 내용들을 자식 클래스로 가져온 후 자식 클래스에서 보강해서 사용하는 것
클래스 생성시 부모 클래스 를 자식 클래스에 상속되게 하려면? 아래처럼 설정하기 SuperClass -> 브라우저 클릭

sample39-MainClass
package Sample39;
import Child.ChildClass;
public class MainClass {
public static void main(String[] args) {
/*
상속성 (inheritance)
정의: 부모 클래스로부터 기능을 상속하는 것을 의미한다
기능: variabe(변수) , method(함수)-> 물려 받는 것
부모클래스의 인스턴스 : Super -> 부모 객체의 주소(reference)를 가리킨다
형식:
class 부모 클래스 {
(부모) 변수
(부모) 메소드
}
class 자식 클래스 extends 부모클래스 {
* 자식 로봇을 만들 때 뒤에 extends ParentClass라고만 적어주면 끝!
* 우리 눈에 보이지는 않지만 부모 클래스에서 지정한 변수와 메소드가 상속되어 저장되어 있다
(자식) 변수
(자식 ) 메소드
}
접근지정자:
아주 중요한 규칙이 있어. 바로 접근 지정자(자물쇠) 규칙
- private: 비밀번호가 걸려 있어서 부모 클래스에만 쓸 수 있어. 자식 로봇도 못 열어봐! (그래서 number = 12; 가 접근 불가였던 거야.)
- protected: 외부에선 못 열지만, 핏줄인 클래스에서는 열어주는 특별한 자물쇠야!
- public: 누구나 다 쓸 수 있는 오픈된 공간이야.
*/
ChildClass cc = new ChildClass(); // 메인 클래스에서 new ChildClass();를 호출
cc.name = "홍길동";
// cc.height = 172.1; -> protected 로 부모 클래스에서 설정 되어 있음으로 자식클래스에서는 호출이 가능하나 외부 클래스에서는 접근이 불가하다
cc.parentMthod();
//cc.info();
Sample39 - ParentClass
package Sample39;
public class ParentClass {
private int number;
public String name;
protected double height;
public void parentMthod () {
System.out.println("parenClass parentMethod()");
}
protected void info() {
}
}
Sample39-Child
package Child;
import Sample39.ParentClass;
public class ChildClass extends ParentClass { // ChildClass 생성자
// super(); 맨 첫 줄에 눈에 보이지 않는 super(); 문장을 자동으로 실행
public void func() {
// number = 12; -> 접근 불가한 이유 부모 클래스에서 private 으로 선언되어 있기 때문
name = "성춘향";
height= 152.1;
info();
1. [Sample 39] super() : "자식 클래스가 태어날 때의 대원칙"이 샘플에서 가장 기억해야 하는 정석 용어는 super()야.
|
Sample40 -MainClass
package sample40;
import java.security.PublicKey;
import Child.ChildClass;
public class MainClass {
public static void main(String[] args) {
ChildClass cc = new ChildClass();
}
}
Sample40 -ParentClass
package Parent;
public class ParentClass {
private String name;
public ParentClass() {
System.out.println("ParentClass ParentClass()");
}
public ParentClass(String name) {
System.out.println("ParentClass ParentClass(String name)");
}
/*
* * 기본 모양(ChildClass())으로만 생성자를 만들지 말고, 옵션(숫자)을 넣어서 생성자를 만들고 싶을 땐!
* 1번이 아니라 2번처럼 써야 된다 ! 1번 처럼 쓰면 오류 난다
1) private void child(int num ) {
System.out.println("childClass childClass()");
}
2) public ChildClass(int n ) { // 👈 void가 없고 public인 진짜 생성자!
System.out.println("ChildClass ChildClass(int n)" );
1번의 오류 이유
일반 메서드: 이름이 클래스명(ChildClass)과 다르고 앞에 void가 붙어 있기 때문에,
이는 생성자가 아니라 일반 메서드(함수)야.
게다가 접근 제어자가 private이라 외부 클래스에서 호출할 수 없어.
2번의 성공 이유
매개변수를 가진 생성자: 반환 타입(void 등)이 없고
이름이 클래스명과 완벽히 일치하므로 진짜 생성자가 맞아!
접근 제어자가 public이라 외부에서 이 생성자를 통해 인스턴스(객체)를 생성할 수 있게 되지.
*/
}
Sample40 -ChildClass
package Child;
import Parent.ParentClass;
public class ChildClass extends ParentClass {
public ChildClass() { // 기본 생성자
super("홍길동"); 👈 "부모님! '홍길동'이라는 이름 들고 먼저 태어나세요!" 하는 명령!
System.out.println("ChildClass ChildClass()");
}
public ChildClass(int n) {
// this();
System.out.println("ChildClass ChildClass(int n)");
}
}
출력결과
ParentClass ParentClass(String name)
ChildClass ChildClass()
핵심! super()와 생성자의 비밀 (출력 결과의 이유)블로그 맨 밑에 출력 결과 적어둔 거 기억나?"어? 나는 ChildClass만 만들었는데 왜 부모 클래스 글자가 먼저 찍히지?" 하고 놓쳤을 수 있어. 자바의 대원칙: "자식 로봇이 태어날 때는, 무조건 부모 로봇이 먼저 조립되어야 한다!" 그래서 ChildClass 내부를 보면 이렇게 적혀있지? public ChildClass () {
super("홍길동" ); // 👈 "부모님! '홍길동'이라는 이름 들고 먼저 태어나세요!" 하는 명령! System.out.println("ChildClass ChildClass()" ); super(...)는 부모의 생성자를 강제로 깨우는 마법 주문이야. 그래서 부모 로봇이 "나 홍길동이라는 이름으로 태어났다!" 하고 먼저 출력하고, 그 다음에 자식 로봇이 태어난 거야. 🧠 재미니의 요약 노트!
|
Sample41-MainClass
package Sample41;
import child.Pitcher;
public class MainClass {
public static void main(String[] args) {
// 자식 클래스를 생성하고 값을 저장하면
// 부모 클래스와 자식 클래스로 접근하여 멤버변수에 넣을수 있다
Pitcher pit = new Pitcher("홍길동", 24, 172.1, 10, 3, 1.23);
}
}
Sample41-Human
package parent;
//설명을 위한거라 주석처리
public class Human /*extends Object*/{
private String name;
private int age;
private double height;
public Human(String name, int age, double height) {
super();
this.name = name;
this.age = age;
this.height = height;
}
@Override // namespace (이름 공간 : 주석문에 해당한다)
public String toString() {
return "Human [name=" + name + ", age=" + age + ", height=" + height + "]";
}
}
Sample41
package child;
import parent.Human;
public class Pitcher extends Human {
private int win;
private int lose;
private double defence;
public Pitcher(String name, int age, double height, int win, int lose, double defence) {
super(name, age, height); //using 했더니 바로 super 로 접근 = 부모 클래스에 자식 클래스 데이터 들어가게 된다
this.win = win;
this.lose = lose;
this.defence = defence;
}
@Override
public String toString() {
return "Pitcher [win=" + win + ", lose=" + lose + ", defence=" + defence + "]";
}
}
Sample41-parent
package parent;
//설명을 위한거라 주석처리
public class Human /*extends Object*/{
private String name;
private int age;
private double height;
public Human(String name, int age, double height) {
super();
this.name = name;
this.age = age;
this.height = height;
}
@Override // namespace (이름 공간 : 주석문에 해당한다)
public String toString() {
return "Human [name=" + name + ", age=" + age + ", height=" + height + "]";
}
}
Sample41-child
package child;
import parent.Human;
public class Pitcher extends Human {
private int win;
private int lose;
private double defence;
public Pitcher(String name, int age, double height, int win, int lose, double defence) {
super(name, age, height); //using 했더니 바로 super 로 접근 = 부모 클래스에 자식 클래스 데이터 들어가게 된다
this.win = win;
this.lose = lose;
this.defence = defence;
}
@Override
public String toString() {
return "Pitcher [win=" + win + ", lose=" + lose + ", defence=" + defence + "]";
}
}
ChildClass method()
Sample 42-MainClass
package Sample42;
import child.ChildClass;
public class MainClass {
public static void main(String[] args) {
/*
Over Ride : 부모 클래스의 메서드를 자식 클래스가 엎어치기(재정의)했기 때문에, 재정의(Override)한 자식 클래스의 메서드가 호출된다!
*/
// ChildClass cc = new ChildClass();
// cc.method();
ChildClass pc = new ChildClass();//이렇게 되는 이유? ->
pc.method(); //-> 위에 있는 것이 아닌 재정의(Override)한 자식 클래스의 메서드가 호출된다 모 클래스의 메서드를 자식 클래스가 엎어치기(재정의)했기 때문에 자식의 기능이 실행되는 것이니까
// pc.func(); // 출력 안 되는 이유 -> overRide 된 메소드가 아니기 때문에 호출할 수 없다
}
}
Sample 42-parentClass
package parent;
public class ParentClass {
public void method() {
System.out.println("ParentClass method()");
}
}
Sample 42-childClass
package child;
import parent.ParentClass;
public class ChildClass extends ParentClass {
public void method() {
System.out.println("ChildClass method()");
}
public void func() {
}
}
Sample 42- 출력
ChildClass method()
다형성 (Polymorphism)과 강제 형변환 (Cast)의 핵심 원리
Sample43-MainClass
package Sample43;
import child.Cat;
import child.Dog;
import parent.Animal;
public class MainClass {
public static void main(String[] args) {
//다형성 (Ploymorphism )
//하나의 instance에 여러개의 객체를 저장하는 것
// Animal ani1 = new Cat();
// Animal ani2 =new Dog();
Object ani1 = new Cat();
Object ani2 = new Dog();
//Animal ani1 = new Cat();
// Animal ani2 =new Dog();
//대신 Object를 활용해서 이렇게 쓸 수도 있다.
String stt = new String("Hello");
Integer in =12;
Object obj = new String("Hello");
//String stt = new String("Hello"); ,Integer in =12;
//를 같이 담고 싶다면 이렇게 쓸 수도 있다.
//고양이, 멍멍이
Cat catArray [] = new Cat [10];
Dog dogArrat [] = new Dog[10];
Animal animal [] = new Animal [5];
animal [0] =new Dog () ;
animal [1] = new Cat ();
animal [2] =new Dog () ;
animal [3] =new Dog () ;
animal [4] = new Cat ();
//부모 클래스 타입의 배열(Animal[]) 하나로 자식 클래스인 Dog와 Cat 인스턴스들을 한 번에 관리(다형성)하기 위해서입니다.
for (int i = 0; i < animal.length; i++) {
animal[i].speech();
}
//animal[0].dog_method(); -> 에러
//- 에러 이유: 부모 타입(Animal) 상자 상태일 때는 자식 클래스만의 전용 메서드(dog_method)가 보이지 않음.
//- 해결 방법: instanceof로 진짜 Dog가 맞는지 확인한 후, (Dog) 키워드로 강제 형변환(Cast)을 해줘야 자식 전용 메서드를 깨워서 쓸 수 있음!
//부모 클래스 객체 (instance)를 자식 클래스의 객체로 변환하는 방법
//cast 변환으로 가능하다
// Dog dog = (Dog)animal[0];
// dog.dog_method();
//
// ((Cat)animal[1]).cat_method();
//instandeof
//생성된 객체가 무엇인지 알 수 있는 키워드
//
if(animal[0] instanceof Dog) {
System.out.println("animal[0]는 Dog 클래스로 생성됨 ");
}
for (int i= 0; i< animal.length; i++) {
if(animal[i]instanceof Dog) {
Dog d= (Dog)animal[i];
d.dog_method();
}
else if(animal[i]instanceof Cat) {
Cat c = (Cat)animal[i];
c.cat_method();
}
Sample43-parentClass
package parent;
public class Animal {
public void speech() {
System.out.println("Animal speech()");
}
}
Sample43-DogClass
package child;
import parent.Animal;
public class Dog extends Animal {
@Override
public void speech() {
System.out.println("멍멍");
}
public void dog_method() {
System.out.println("저는 멍멍이");
}
}
Sample 43-CatClass
package child;
import parent.Animal;
public class Cat extends Animal {
@Override
public void speech() {
System.out.println("야옹야옹");
}
public void cat_method() {
System.out.println("나는 고양이");
}
}
출력
멍멍
야옹야옹
멍멍
멍멍
야옹야옹
animal[0]는 Dog 클래스로 생성됨
저는 멍멍이
나는 고양이
저는 멍멍이
저는 멍멍이
나는 고양이
질문: 메소드와 생성자를 어떻게 구분해? 형식이 같아서 헷갈려!
질문자님이 말씀하신 모양 중에서, 접근 제어자와 () {}가 붙는 것은 공통점이지만 그 사이에 void 같은 반환 타입이 들어가면 '메서드', 반환 타입이 완전히 생략되고 클래스 이름과 똑같으면 '생성자'라고 부릅니다. |
🔍 재미니의 꼼꼼 피드백 & 보완 포인트1. [Sample 41] "Pitcher에 있는 내용이 Human에도 넘어가는 거지?"에 대한 명확한 해답블로그 맨 밑에 질문으로 남겨두신 이 부분! 아주 날카로운 의문입니다. 정답은 "반대"입니다!
|
질문: pitcher 에 있는 내용이 Human 에도 넘어가는 거지?
1. [Sample 41] "Pitcher에 있는 내용이 Human에도 넘어가는 거지?"에 대한 명확한 해답블로그 맨 밑에 질문으로 남겨두신 이 부분! 아주 날카로운 의문입니다. 정답은 "반대"입니다!
|
'Java > Java 수강일지' 카테고리의 다른 글
| [수강일지_17] Generic , list (0) | 2026.06.02 |
|---|---|
| [수강일지_16] 복습, 추상클래스 , interface , variavle, static, staticmethod, final (0) | 2026.06.01 |
| [수강일지_14] 학생정보 관리 프로그램 만들기 (1) | 2026.05.28 |
| [수강일지_13] , hiding, constructor,objectArray, work13 풀이,OOP 3대 특성 (0) | 2026.05.27 |
| [수강일지_12] 객체지향 프로그래밍 void,cal (0) | 2026.05.26 |