BackEnd/JAVA
JAVA inherit 상속, private, super 생성자
H_Develop
2022. 7. 28. 08:15
extends (상속)
상속(inherit) 부모가 보유하고 있는 재산 (필드:맴버 메서드와 맴버 변수) 중 일부/전부를 자식이 물려받는 것.
클래스 상속은 객체의 재사용이라는 장점 뿐 아니라,
코드의 간결성을 제공해주는 객체지향 언어의 최고 장점이라 할 수 있다.
그러므로 잘 정의된 부모 클래스가 있다면 자식 클래스의 작성이 간편해진다는 장점이 있다.
객체의 재사용, 코드의 간결함이 있다.
잘 정의 된 부모 클래스(슈퍼 클래스)의 필드들을 자식 클래스(서브 클래스)에서 불러다 사용한다.
하지만 부모 클래스에서 private로 선언된 맴버는 자식 클래스에서 사용할 수 없다.
OOP(Object Oriented Programming : 객체지향언어)
java, C++, ... 클래스를 사용해서 객체를 만들고 이 객체로 모든 현상을 설명하는 프로그래밍 기법
Object가 최상위 객체이다.
상속 개념
class Parent {
private int money = 200;
private String str = "서울";
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money; // parent class 의 money
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str; // parent class 의 str
}
}
class Child extends Parent {
private String car = "Grandeur"; // 자식 클래스에서 변수 선언
public String getCar() { // 자식 클래스에서 두개의 메서드 정의
return car;
}
public void setCar(String car) {
this.car = car;
}
}
public class ex1 {
public static void main(String[] args) {
Child c1 = new Child(); // 인스턴스화 한다.
System.out.println(c1.getCar()); // Child가 자신의 맴버 메서드를 사용
System.out.println(c1.getMoney()); // Child가 Parent class의 메서드 사용
if(c1 instanceof Parent) {
// instance == 객체, instanceof 타입은 boolean, c1은 Parent의 자식인지 체크
// instanceof는 객체화 여부를 점검하는데, boolean으로 결과를 보인다.
System.out.println("c1은 Parent의 자식이다.");
}
System.out.println("-----------------------");
}
}
객체의 형변환
class Parent {
private int money = 200;
private String str = "서울";
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money; // parent class 의 money
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str; // parent class 의 str
}
}
class Child extends Parent {
private String car = "Grandeur"; // 자식 클래스에서 변수 선언
public String getCar() { // 자식 클래스에서 두개의 메서드 정의
return car;
}
public void setCar(String car) {
this.car = car;
}
}
public class ex1 {
public static void main(String[] args) {
Child c1 = new Child(); // 인스턴스화 한다.
System.out.println(c1.getCar()); // Child가 자신의 맴버 메서드를 사용
System.out.println(c1.getMoney()); // Child가 Parent class의 메서드 사용
if(c1 instanceof Parent) {
// instance == 객체, instanceof 타입은 boolean, c1은 Parent의 자식인지 체크
// instanceof는 객체화 여부를 점검하는데, boolean으로 결과를 보인다.
System.out.println("c1은 Parent의 자식이다.");
}
System.out.println("-----------------------");
Child ch = new Child();
Parent pr = new Parent();
pr = (Parent)ch; // casting 형변환,
ch = (Child)pr; // 자식을 부모/부모를 자식에게 형변환 함.
// 부모를 자식에 대입함으로써 자식은 자신의 모든 필드와 부모의 모든 필드를 사용할 수 있음.
// 클래스 캐스팅은 많이 사용하지 않는다.
System.out.println(ch.getCar()); // 자식이 자식 맴버 사용
System.out.println(ch.getMoney()); // 자식이 부모 맴버 사용
System.out.println(ch.getStr()); // 자식이 부모 맴버 사용
System.out.println(pr instanceof Child);
pr = ch;
// 자식을 부모에게 대입, 자식을 부모에게 대입해도 부모는 자신의 맴버들만 사용할 수 있다.
System.out.println(pr.getMoney()); // 부모는 자신의 맴버만 사용가능
System.out.println(pr.getStr());
// System.out.println(pr.getCar()); // 부모가 자식 맴버 사용 불가
// System.out.println((Child)pr.getCar()); // 부모를 형변환 하더라도 자식 맴버 사용 불가
}
}
매개변수 없는 메서드 사용
class Animal {
int leg; // 동물의 공통적인 부분은 부모 클래스에서 변수와 매서드를 정리.
String shout;
public int getLeg() {
return -1;
}
public String getShout() {
return shout;
}
public void setShout(String shout) {
this.shout = shout;
}
}
class Duck extends Animal { // 모든 동물에 속하지 않는 날개 같은 경우, 자식 클래서에서 따로 정의
private String wing = "날개가 있어요";
public String getWing() {
return wing;
}
public int getLeg() {
System.out.println("Duck의 메서드 오버라이딩");
return leg;
}
}
class Ant extends Animal {
private String legs = "다리가 많아요";
public String getLegs() {
return legs;
}
public int getLeg() { // 부모의 getLeg() 메서드를 가져와서 다음처럼 print 하는 메서드 오버라이딩
System.out.println("Ant의 메서드 오버라이딩 ");
return leg; // overriding을 따로 하지않으면, 부모클래스 getLeg()의 return값, -1이 반환된다.
// 부모의 매서드를 오버라이딩 했기에 return 값으로 Ant class의 legs를 사용할 수 없고,
// Animal class 의 leg를 사용해야 한다.
}
}
public class ex2 {
public static void main(String[] args) {
Duck duck = new Duck();
System.out.println("날개 : " + duck.getWing());
duck.leg = 2;
System.out.println("다리 : " + duck.getLeg());
duck.setShout("꽥꽥");
System.out.println("울음소리 : " + duck.getShout());
Ant ant = new Ant();
System.out.println("날개 : " + ant.getLegs());
ant.leg = 8;
System.out.println("다리 : " + ant.getLeg());
ant.setShout("슥..슥..");
System.out.println("울음소리 : " + ant.getShout());
}
}
private
변수, 메서드는 다른 오브젝트에서 사용할 수 없고, 서브 클래스로 상속될 수 없다.
class Person {
// private String name;
String name;
void setName(String n) {
this.name = n;
}
String getName() {
return name;
}
}
class Girl extends Person {
void print() {
System.out.println(getName() + " 양");
}
}
public class ex1 {
public static void main(String[] args) {
Girl nara = new Girl();
nara.setName("나라"); // 부모 메서드 호출하여 사용
nara.name = "나라";
// 바로 접근, Person class 에서 private로 변수를 생성했으면 변경불가.
nara.print();
}
}
super, 생성자
class Parent {
public Parent(int n) {
// Class와 동일한 이름으로 Method 생성 == 생성자(Construct : C프로그램에서 구조체)
// Class c = new Class(); 에서 뒤에 Class()가 생성자 호출한다는 의미이다.
// instance화 할 때, 제일 먼저 호출되어 실행되는 일종의 메서드이다.
// 생성자는 instance 필드 값들을 초기화 시킨다.
// public class_name(parameter) {...} 구문.
System.out.println("부모 클래스 " + n);
}
}
class Child extends Parent {
public Child() { // 생성자 메서드
super(1); // 부모 클래스 parent 생성자 호출
System.out.println("자식 클래스 ");
}
}
public class ex1 {
public static void main(String[] args) {
Child ch = new Child();
new Child();
// 자식 클래스에서 객체를 생성하면, 자식의 생성자가 호출되지만 먼저 super()로 부모의 생성자를 호출했기에,
// 부모 클래스의 생성자에 접근하게 된다.
}
}
부모 클래스 1
자식 클래스
부모 클래스 1
자식 클래스
객체 생성으로도 생성자를 호출한다.
자식 클래스에서 오버라이딩 된 부모 매서드 까지 호출
class Animalss {
String name;
int age;
void printPet() {
System.out.println("이름 : " + name );
System.out.println("나이 : " + age);
}
}
class Cat extends Animalss {
String variety;
@Override
void printPet() {
super.printPet(); // 객체 생성 없이, 부모 메서드 호출
System.out.println("종류 : " + variety); // 자신의 변수로 부모의 메서드를 호출
}
}
public class ex1 {
public static void main(String[] args) {
Cat cat = new Cat();
cat.name = "양순이";
cat.age = 5;
cat.variety = "페르시안";
cat.printPet();
}
}
이름 : 양순이
나이 : 5
종류 : 페르시안