-
[Java] 객체지향 - 상속java/[이론] 2022. 4. 7. 23:31
코드의 재활용과 다형성: 객체 지향의 꽃
컴포넌트 베이스 개발. interface 기반
상속
부모 클래스로부터 멤버변수나 메서드를 물려받음
상속 해주는 클래스: 부모, 베이스, 상위 클래스
상속 받는 클래스: 자식, 파생, 하위 클래스
상속 키워드 extends
class 클래스명 extends 부모클래스{
}
1. 코드 중복을 줄이기 위해 공통 코드를 분리하여 부모 클래스를 만들고
이를 상속받도록 구현
<학사관리>
학생 교수 교직원
번호 번호 번호
이름 이름 이름
학과 학과 부서
수강과목 개설과목 직무
class Student{
String num;
String name;
String dept;
String[] sugang;
}
class Prof{
String num;
String name;
String dept;
String[] open_subj;
}
class Staff{
String num;
String name;
String dept;
String job;
}
=> 공통 코드를 Person 으로 분리
class Person{
String num;
String name;
String dept;
}
=> 원래 클래스들을 Person을 상속받아 구현
=> 상속에서 자식클래스는 부모클래스의 확장
class Student extends Person{
String[] sugang;
}
class Prof extends Person{
String[] open_subj;
}
class Staff extends Person{
String job;
}
============================================
상속
멤버변수/메서드
생성자, private => 상속 못받음.
상속 키워드: extends
부모클래스
상속 주는 클래스
자식클래스
상속 받는 클래스
상속 사용 이유
1. 코드 재 사용성 높임
2. 다형성: 하나의 코드가 변신 로봇처럼 때에 따라서 다양한 모양으로 실행
재정의, 업캐스팅, 다운캐스팅
3. 컴포넌트 베이스 개발. 인터페이스 기반.
=> 속도 빠름. 코드의 신뢰성 높다.
================================
객체 지향 기법
1. 메서드 오버로딩
동일한 이름의 메서드 여러 개 정의 가능. 파라메터 개수 나 타입 다르게.
2. 생성자
객체 초기화. 함수 타입이 없고 이름은 클래스와 동일한 함수
호출은 객체 생성시에만 가능
3. this
클래스 정의할때 사용하는 참조 변수
현재 객체를 부르는 이름
무명씨 참조변수. 즉 현재 객체를 아직 객체 생성 전이므로 이름이 없어서 그냥 this라 부름
파라메터(지역변수)랑 멤버변수랑 이름이 같을때 구분할라고 사용.
4. 상속
부모의 멤버변수나 메서드를 물려받음. 여러 클래스에 반복되는 멤버를 한번만 작성하려고.
자바 상속의 특징
여러 단계 상속해 내려오는 것 가능
하나의 클래스를 상속받는 여러 개의 클래스 만들 수 있음
다중상속 안됨. extends 다음에 부모클래스는 하나만 와야 함.
5. 객체 사이의 관계
1) 포함관계(has a) - 소유. 다른 클래스를 멤버변수로 정의.
2) 상속관계(is a) - 본질. extends로 상속
6. 다형성
1) 메서드 재정의
상속받은 메서드를 하위 클래스에서 다시 정의해서 사용.
물려받은 메서드를 그냥 사용하기에는 현재 하위 클래스에 적합치가 않음.
현재 클래스에 맞게 수정하여 사용.
주의: 메서드 프로토타입(함수 껍데기)는 바꾸지 말고 함수 안의 내용만 바꿔라
=> 업캐스팅, 다운캐스팅과 함께 사용하여 다형성을 만들어줄수 있다.
2) 업캐스팅
상속관계에서 객체의 타입을 위로 올림
상속 관계에서 자식 클래스 객체를 생성하고 이 객체를 부모 타입의 변숭에 담는 것.
특징: 객체는 부모 노릇(부모 클래스에 정의된 멤버변수나 메서드만 사용가능)을 하지만 재정의 된 메서드를 호출하면 자식 클래스에 재정의한 메서드가 실행됨.
부모 클래스를 상속받은 모든 자식클래스들을 부모 타입의 변수에 담을 수 있고, 상속받은 메서드 이름들이 같으므로 동일하게 취급할 수 있음.
3) 다운 캐스팅
한번 업캐스팅 된 객체를 원래 타입으로 내림.
업캐스팅된 객체를 사용하면 자식클래스에 추가된 멤버변수나 메서드를 사용할 수 없음. 이렇게 추가된 요소를 사용하려면 원래 타입으로 내려야 함 => 다운 캐스팅
6. super
상속관계에서 부모 객체를 가리키는 참조변수
부모 객체의 멤버변수나 메서드 접근
7. super()
상속관계의 부모 클래스의 생성자 호출
부모 클래스가 디폴트 생성자 없이 파라메터 있는 생성자만 존재할때 자식 클래스에서 부모 생성자에 파라메터 전달하는 역할package p1118; class Person { String num; String name; String dept; public Person() { System.out.println("Person 생성자"); num = "없음"; name = "parent"; dept = "없음"; } public void print() { System.out.println("num:" + num); System.out.println("name:" + name); System.out.println("dept:" + dept); } } class Student extends Person { String[] sugang; public Student() { System.out.println("Student 생성자"); num = "s213467"; name = "stud1"; dept = "컴퓨터공학과"; sugang = new String[] { "국어", "영어" }; } public void print2() { System.out.println("Student sugang 출력"); for (String s : sugang) { System.out.println(s); } } } class Prof extends Person { String[] open_subj; public Prof() { System.out.println("Prof 생성자"); num = "p216723"; name = "prof1"; dept = "전자공학과"; open_subj = new String[] { "전자실습", "전자기초" }; } public void printInfo() { System.out.println("prof open_subj 출력"); for (String s : open_subj) { System.out.println(s); } } } class Staff extends Person { String job; public Staff() { System.out.println("Staff 생성자"); num = "st218956"; name = "staff1"; dept = "hr"; job = "인재개발"; } public void printJob() { System.out.println("staff job 출력: " + job); } } public class 상속테스트1 { public static void main(String[] args) { // TODO Auto-generated method stub System.out.println("부모 객체 생성"); Person p = new Person(); p.print(); System.out.println("Student 객체 생성"); Student s = new Student(); s.print(); s.print2(); System.out.println("Prof 객체 생성"); Prof pf = new Prof(); pf.print(); pf.printInfo(); System.out.println("Staff 객체 생성"); Staff sf = new Staff(); sf.print(); sf.printJob(); } }package p1122; class Product { public int price; public int point; } class Tv extends Product { public Tv() { price = 100; point = 10; } } class Audio extends Product { public Audio() { price = 200; point = 20; } } class Computer extends Product { public Computer() { price = 300; point = 30; } } class Buyer { public int money = 1000; public int points = 0; //메서드 오버로딩 public void buy(Tv tv) { if (money >= tv.price) { money -= tv.price; points += tv.point; } else { System.out.println("잔액부족"); } System.out.println("tv구매. 잔액:" + money + " / " + points); } public void buy(Audio a) { if (money >= a.price) { money -= a.price; points += a.point; } else { System.out.println("잔액부족"); } System.out.println("Audio구매. 잔액:" + money + " / " + points); } public void buy(Computer c) { if (money >= c.price) { money -= c.price; points += c.point; } else { System.out.println("잔액부족"); } System.out.println("Computer구매. 잔액:" + money + " / " + points); } } public class BuyMain { public static void main(String[] args) { // TODO Auto-generated method stub Buyer b = new Buyer(); // Product[] p = {new Tv(), new Audio(), new Computer(), new Tv(), // new Audio(), new Computer(), new Tv(), new Audio(), new Computer()}; b.buy(new Tv()); b.buy(new Audio()); b.buy(new Computer()); b.buy(new Tv()); b.buy(new Audio()); b.buy(new Computer()); b.buy(new Tv()); b.buy(new Audio()); b.buy(new Computer()); } }package p1122; //super: 상속관계에서 부모 객체를 나타내는 참조변수 class Father { public int num = 1; public String name = "aaa"; public Father(int num, String name) { this.num = num; this.name = name; } public void test1() { System.out.println("Father 클래스 메서드"); System.out.println("num:" + num); System.out.println("name:" + name); } } class Son extends Father { public String hobby; public Son(int num, String name, String hobby) { super(num, name); this.hobby = hobby; } @Override public void test1() { // TODO Auto-generated method stub System.out.println("Son 클래스 메서드"); super.test1();// 클래스 정의 시에만 사용가능. super:부모 객체 System.out.println("hobby:" + hobby); } } public class SuperTest { public static void main(String[] args) { // TODO Auto-generated method stub Son s = new Son(10, "aaa", "낚시"); s.test1();// 정적결합: 재정의된 메서드 호출시 데이터 타입을 따라 선택함 Father f = new Father(30, "bbb"); f.test1();// 정적결합: 재정의된 메서드 호출시 데이터 타입을 따라 선택함 Father fs = new Son(50, "ccc", "피아노");// 업캐스팅 fs.test1();// 동적결합. 타입이 부모이지만 재정의된 메서드 호출 } }'java > [이론]' 카테고리의 다른 글
[Java] lang 패키지 (0) 2022.04.08 [Java] final과 추상클래스 & 인터페이스 (0) 2022.04.07 [Java] 객체지향 - static과 접근 제어자 (0) 2022.04.07 [Java] 객체지향 - 오버로딩과 생성자 (0) 2022.04.07 [Java] 함수와 메서드 (0) 2022.04.07