상속
자바는 단일 상속 : 오직 하나의 클래스만 상속 받을 수 있다.
때문에 상속클래스가 없으면 사실 최상위 클래스인 object를 상속하고 있는 것이다.
package com.bit.day08.am;
class Lec04{
int su = 1111;
void func01(){
System.out.println("부모 클래스의 기능");
}
}
public class Ex04 extends Lec04 {
public static void main(String[] args) {
Ex04 me=new Ex04();
System.out.println(me.su);
me.func01();
}
}
package com.bit.day08.am;
class Lec04 {
int su = 1111;
void func01() {
System.out.println("부모 클래스의 기능");
}
}
public class Ex04 extends Lec04 {
int su = 2222;
// 메소드 오버라이드- 부모기능을 재정의
void func01(){
System.out.println("자식 클래스의 기능");
}
public static void main(String[] args) {
Ex04 me = new Ex04();
System.out.println(me.su);
me.func01();
}
}
오버라이드시 주의점 : 접근제한자
열린 방향으로는 허용을 한다 --> public을 붙여도 된다.
하지만 private은 접근이 줄어드는 것으로 허용하지 않는다.
package com.bit.day08.am;
class Lec04 {
int su = 1111;
void func01() {
System.out.println("부모 클래스의 기능");
}
}
public class Ex04 extends Lec04 {
int su = 2222;
// 메소드 오버라이드- 부모기능을 재정의
private void func01(){ //오류. 덮어쓰기 위해서는 똑같아야 한다.
System.out.println("자식 클래스의 기능");
}
public static void main(String[] args) {
Ex04 me = new Ex04();
System.out.println(me.su);
me.func01();
}
}
오버라이드의 대상은 메소드이다.
package com.bit.day08.am;
class Lec04 {
int su = 1111;
void func01() {
System.out.println("부모 클래스의 기능");
}
}
public class Ex04 extends Lec04 {
private int su = 2222; //문제되지 않는다. 필드는 오버라이드의 대상이 아니기 때문이다.
// 메소드 오버라이드- 부모기능을 재정의
void func01(){
System.out.println("자식 클래스의 기능");
}
public static void main(String[] args) {
Ex04 me = new Ex04();
System.out.println(me.su); //2222 출력
}
}
오버로드는 인자의 유무,갯수,타입에 따라서 가능한 것이다. 덮어쓰는 것이 아니므로 오버라이드와 상관이 없다.
package com.bit.day08.am;
class Lec04 {
int su = 1111;
void func01() {
System.out.println("부모 클래스의 기능");
}
}
public class Ex04 extends Lec04 {
private int su = 2222;
// 메소드 오버라이드- 부모기능을 재정의
void func01(){
System.out.println("자식 클래스의 기능");
}
//메소드 오버로드. 동일한 이름이기 때문에 --> 접근제한자 상관이 없다.
void func01(int a) {
System.out.println("다른 기능...");
}
public static void main(String[] args) {
Ex04 me = new Ex04();
System.out.println(me.su);
me.func01(123); //문제없이 실행된다.
}
}
출력결과:
부모클래스 객체생성...
자식클래스 객체 생성...
부모클래스의 기능...
내가 생성될때 부모의 객체도 생성하고 있는 것이다.
package com.bit.day08.am;
class Lec05{
public Lec05(int a){
System.out.println("부모클래스 객체생성...");
}
public void func() {
System.out.println("부모클래스의 기능...");
}
}
public class Ex05 extends Lec05{
public Ex05(){ //부모클래스의 생성자의 인자를 바꿨더니 default생성자는 사라지므로 오류
//인자를 써도 오류 : 숨어있는 super()의 인자를 바꿔야 한다.
super(1234); //super를 써서 문제 해결
//인자가 없을 때 숨겨져 있는것은 super();인 것. 인자가 없는 애라서 부모클래스의 생성자 인자가 주어지면 오류가 뜨는 것이다.
//그래서 super에 인자를 줘야 오류가 떨어지지 않는다.
//디폴트 생성자에도 super()가 숨어져 있다.
System.out.println("자식클래스 객체 생성...");
}
public static void main(String[] args) {
Ex05 me = new Ex05(); //부모클래스의 생성자가 출력됐다는 것은 부모의 객체가 만들어졌다는 뜻이다.
me.func();
}
}
//부모클래스의 객체가 생성되는 것이다.
//내가 없으면 차순위로 부모, 부모도 없으면 static(클래스에 대한 정보가 있으니까)
package com.bit.day08.am;
class Lec05{
int su=1111;
public Lec05(){
System.out.println("부모클래스 객체생성...");
}
public void func() {
System.out.println("부모클래스의 기능...");
}
}
public class Ex05 extends Lec05{
int su=2222;
public Ex05(){
super(); //반드시 최상단에 와야한다. 부모 생성자가 먼저 와야 내 객체가 생성되는 것이다.
System.out.println("자식 인자없는 생성자...");
}
public Ex05(int su){
super();
this.su=su;
System.out.println("자식 인자하나 생성자");
}
public static void main(String[] args) {
Ex05 me = new Ex05();
me.func();
}
}
package com.bit.day08.am;
class Lec05{
int su=1111;
public Lec05(){
System.out.println("부모클래스 객체생성...");
}
public void func() {
System.out.println("부모클래스의 기능...");
}
}
//this()가 없는 놈이 super()를 갖고 있는 놈
public class Ex05 extends Lec05{
int su;
public Ex05(){
// super();
this(2222); //오류 : 객체 2개가 찍히게 된다. -->super()와 this()는 둘 중 하나만 존재해야 한다.
System.out.println("자식 인자없는 생성자...");
}
public Ex05(int su){
super();
this.su=su;
System.out.println("자식 인자하나 생성자");
}
public static void main(String[] args) {
Ex05 me = new Ex05();
me.func();
}
}
만약 부모클래스의 생성자가 인자를 갖는다면 밑에서 super(인자)를 명시해줘야 한다.
public Lec05(int a){
System.out.println("부모클래스 객체생성...");
}
그런데 문제는 가리키고 있는 게 없다 --> 그 참조변수 역할을 하는 것이 super 키워드인 것이다.
package com.bit.day08.am;
class Lac06{
int su=1111;
void func(){
System.out.println("부모기능");
}
}
//오버라이드: 부모의 기능에 덧붙여서 자식클래스에서 추가정의. 왜냐면 자식 func 안에서 super를 통해 호출할 수 있으니까.
public class Ex06 extends Lac06 {
int su=2222;
void func(){
super.func(); //부모 func 호출
System.out.println(super.su); //1111출력
System.out.println("자식");
}
public static void main(String[] args) {
Ex06 me = new Ex06();
me.func();
}
}