본문 바로가기
Java

Java(자바) - 상속,접근제한자, 추상클래스 및 오버라이딩

by allwing12 2022. 8. 25.

상속에 대해서 알아보려고 하는데 상속이 뭔지 부터 알아야한다.

상속은 쉽게 표현하면 부모가 가진것을 자식에게 물려주는 것이라고 생각하면 된다.

예를 들어서 차의 종류 중 하나인 세단은 차의 종류 중 하나이고

침대는 가구의 한 종류이면서 침대는 가구이다.

경찰차,소방차,구급차 등등은 자동차에 속할 수 있다.

이렇게 말할 수 있는 관계를 is a 관계 혹은 kind of 관계라고 한다.

 

 

public class Car {
}

public class Bus extends Car {
}

 

 

위의 코드는 Car를 상속받은 bus class 라고 생각하면 된다.

자바는 클래스 이름 뒤에 extends 키워드를 적고 부모클래스 이름을 적게 되면 부모 클래스가 가지고 있는 것을

상속받을 수 있게 되며 부모 클래스인 Car 가 가지고 있는 것을 자식인 Bus class가 사용할 수 있게 된다.

 

 

public class Car{
	public void run () {
    	System.out.println("달리다.");
        }
   }
   
public class BusExam{
	public static void main(String args[]){
    	Bus bus = new Bus();
        bus.run();
        //Bus class 는 아무런 코드를 가지지 않게 되며 그럼에도 run 이라는 메소드를 사용하는데에 문제가 생기지 않는다.
      }
   }

public class Bus extends Car{
	public void ppangppang() {
    	System.out.println("빵빵");
        }
    }

 

Bus는 Car에서 물려받은 run메소드와 ppangppang메소드를 사용할 수 있게 된다.

부모가 가지고 있는 메소드 외에 추가로 메소드를 선언하는 것을 확장했다고 표현한다.

 

추가적으로 접근 제한자라는 것이 있는데 클래스 내에서 멤버의 접근을 제한하는 역할을 한다고 보면 된다.

접근제한자의 종류에는 public과 protected, private, 접근제한자를 적지 않으면 default 접근지정자가 있다.

public은 어떤 클래스든 접근할 수 있다는 것을 의미하며 public void 이런식으로 쓸 수 있다.

protected 는 자기 자신, 같은 패키지, 서로 다른 패키지다 하더라도 상속받은 자식 클래스에서는 접근할 수 있다는 것을 의미하며 private는 자기 자신만 접근할 수 있다는 것을 의미하며 접근제한자를 적지 않으면 default 접근 지정자의 경우에는

자기자신과 같은 패키지에서만 접근할 수 있다는 것을 의미한다.

 

 

 

추상 클래스

추상 클래스는 구체적이지 않은 클래스를 의미하며 독수리,타조는 구체적인 새를 지칭을 하지만

새,포유류 같은 것은 구체적이지 않고 사람마다 다 새에 대한, 포유류에 대한 생각을 하라고 하면

다 다른 생각을 할 것이다, 이런 것을 구현한 클래스를 추상 클래스라고 한다.

추상 클래스를 정의하기 위해서는 abstract 키워드를 이용해서 정의 합니다.

추상 클래스는 미완성의 추상 메소드를 포함할 수 있다.

추상 메소드란, 내용이 없는 메소드이다, 즉 구현이 되지 않은 메소드이다.

추상 메소드는 리턴 타입 앞에 abstract라는 키워드를 붙여야하며 추상 클래스는 인스턴스를 생성할 수 없다.

 

public abstract class Bird {
	public abstract void sing();
    
    public void fly() {
    	System.out.println("날다.");
    }
}

 

추상 클래스를 상속받는 클래스 생성하는 방법으로는

추상 클래스를 상속받은 클래스는 추상 클래스가 갖고 있는 추상 메소드를 반드시 구현해야 한다.

추상 클래스를 상속받고, 추상 클래스가 갖고 있는 추상 메소드를 구현하지 않으면 해당 클래스도 추상 클래스가 된다.

 

 

public class Duck extends Bird {
	@Override // 이 부분은 써도 되고 안써도 되는데 어지간 하면 써주는게 좋다 (헷갈리지 않게!)
    public void sing() {
		System.out.println("꽥꽥!!");
    }
 }

 

public class DuckExam {
	public static void main(String[] args) {
    	Duck duck = new Duck();
        duck.sing();
        duck.fly();
        
        // Bird b = newbird();
   }
}

 

Bird는 추상 클래스이므로 객체를 따로 생성할 수 없다.

 

 

 

오버라이딩

오버라이딩은 부모가 가지고 있는 메소드와 똑같은 모양의 메소드를 자식이 가지고 있는 것이다.

즉, 오버라이딩은 메소드를 재정의하는것이라고 생각하면 된다.

 

//run 메소드를 가지고 있는 Car 클래스
public class Car{
	public void run() {
    	System.out.println("Car의 run메소드");
   }
}


//Car를 상속받는 Bus 클래스
public class Bus extends Car{

}

public class BusExam{
	public static void main(String args[]){
    	Bus bus = new Bus();
        bus.run(); // Car의 run 메소드가 실행이 된다.
     }
 }

 

위의 코드는 메소드 오버라이딩을 통해서 Car 클래스를 상속받은 Bus 클래스가 부모 클래스에 있는 run() 메소드를 사용한거다.

 

Bus클래스에 부모가 가지고 있는 메소드와 모양이 같은 메소드를 선언한 후

public class Bus extends Car{
	public void run(){
    	System.out.println("Bus의 run메소드");
    }
}

public class BusExam{
	public static void main(String args[]){
    	Bus bus = new Bus();
        bus.run(); // Bus run 메소드가 실행된다.
      }
   }

 

BusExam을 실행해보면 Bus의 run메소드가 출력이 된다.

메소드를 오버라이드 하게 되면, 항상 자식클래스에서 정의된 메소드가 호출이 된다.

오버라이딩 한다고 해서 부모의 메소드가 무조건 사라지는 것은 아니며

super 키워드를 이용하면, 부모의 메소드를 호출 할 수 있다.

 

public class Bus extends Car{
	public void run() {
    	**super.run();** //부모의 run()메소드를 호출한다.
        System.out.println("Bus의 run메소드");
     }
 }

 

댓글