[완료] 가상 메서드(Virtual Method)를 사용하는 이유는 무엇인가요

jiggol의 이미지

Java 로 GUI 프로그래밍을 해보고 있는데요..
보통 Frame 클래스를 상속하여 사용하는게 대부분인데요

Frame 를 상속받은 클래스가 MyWin 이라고 가정했을때..
Frame aa = new MyWin(); 이런 식으로 객체를 생성하던데..
실제로 MyWin aa = new MyWin(); 해도 별 문제 없이 제대로 구동이 되었습니다.

이것이 자바가 디폴트로 버추얼 메서드로 작동해서 가능하다고 하더군요..
그렇다면 구지 저렇게 객체를 생성할 필요가 있나요?

왜 구지 저렇게 해서 생성을 하는지 궁금합니다.
어짜피 상속을 받으면 부모의 것들을 모두 사용 가능한것이 아닌가요?

익명 사용자의 이미지

C++에서 가상함수를 사용하지 않으면
MyWin *aa = new MyWin(); 이런 식으로 객체를 생성해야하고..
Frame *aa = new MyWin(); 하면 별 문제 있어 의도한대로 구동이 되지않습니다.

이것이 자바가 디폴트로 가상함수(버추얼 메서드)로 작동해서 가능합니다.

jiggol의 이미지


제가 질문을 조금 잘못썻나보네요..
예... C++ 에서 그렇게 사용해야된다고 저도 알고 있습니다. 클래스 선언부에서 virtual 키워드를 이용해야 된다고 하더군요
그렇다면 왜 구지 그렇게 사용하는가 해서 말입니다.

어짜피 부모에게서 상속을 받으면 부모클래스의 모든 기능을 사용가능하게 되는데..
클래스 타입은 부모클래스로 하면서 왜 자식 생성자를 호출하는가 입니다.
그냥.. 클래스타입도 자식클래스로 하면 될텐데 말이죠..

serialx의 이미지

예를들어서 List 같은 상위 클래스(인터페이스였나 -_-) 가 있고, 이를 상속받은 ArrayList 가 있을 때, 보통 개발을 하면서 사용할 객체의 세부사항 (Array 를 사용한 List 라는 사실 같은 것들) 을 별로 생각하고 싶지 않을때가 많죠. 역으로 질문을 해봅시다, '어차피 List 의 기능을 쓸 건데 굳이 왜 ArrayList 라는 구체적인 선언을 하고 그것에 대한 생각을 해야하는가?' 라고 말입니다. C++ 에서도 마찬가지로 상황에 따라서 Interface Class 와 Impl Class 의 독립 구현을 장려하는 경우도 있습니다. C++ 의 경우 virtual 선언을 explicit 하게 하는 이유는 성능상의 튜닝 문제라던지 다양성(-__-;;) 을 위해서 그런거라고 생각하구요. 하위레벨의 언어니까 그정도 유연성은 있어도 상관 없다고 보여집니다.

SoftOn의 이미지

동물 전체에 대한 울음 소리는 뭐라고 할 수 없지만 각각의 동물은 있죠.. -_-;
그리고 각각 동물 마다 이름(종류라던지..)과 같은 공통된 요소도 있죠..
(동물 객체는 만들어지지도 않고.. 만들 필요도 없는 class죠..)

class 동물
{
  virtual void 짖어(void)=0;
  string 이름;
}
 
class 개 : public 동물
{
  void 짖어(void) { 멍멍; };
}
 
class 고양이 : public 동물
{
  void 짖어(void) {냐옹; };
 
void 울어(동물 *p)
{
  p->짖어();   // <-- 타입 케스팅 없이 이렇게 해도 되는지는 오래 되서 기억이;;;
}
 
int main(int argc, char* argv[])
{
  동물 *우리집개, *우리집고양이;
  우리집개 = new 개();
  우리집고양이 = new 고양이();
 
  우리집개->이름 = "여름이";
  우리집고양이->이름 = "가을이";
 
  울어(우리집개);
  울어(우리집고양이);
 
  delete 우리집개;
  delete 우리집고양이;
 
  return 0;
}

semmal의 이미지

다형성(polymorphism)을 쓰지 않는다고 가정하고, 하나의 클래스(class)를 모듈(module)이라 보면, 상속(inheritance)은 자식 모듈에 부모 모듈을 일정한 규칙에 따라 import한 것과 다를바 없습니다.(C로 치자면 #include)
아마도 jiggol님은 상속을 이정도 선에서 이해하고 계신 것 같습니다.

하지만 상속을 쓰려는 목적은 그것이 아니라, 다형성 때문입니다.
예를 들어서, 우리는 라면을 만들 때 다양한 재료를 넣을 수 있습니다. 문제는 프로그래밍을 하면 "다양한"이라는 것에서 먼저 걸려버립니다.
만약 요리방법이 동일한 비빔면, 짜파게티, 신라면이 있다고 칩시다. 라면은 요리 후에는 다른 방법으로 먹는다고 칩시다. 다형성이 없다면 다음과 같은 세 개의 함수가 필요합니다.

cookBiBimMyeon : 비빔스프 -> 비빔면
cookJJaPaGeTi : 짜장스프 -> 짜파게티
cookSinRaMyeon : 매운스프 -> 신라면

저 세 개의 함수는 거의 같은 요리방법을 가지고 있음에도 불구하고, 우리는 세 가지 요리법(Recipe)을 관리해야합니다.
요리법을 하나로 관리하고 싶으면, 라면요리라는 함수 하나로 합치면 됩니다.
cookRaMyeon : Soup -> RaMyeon

하지만, 여기서 스프와 라면에 대해서 알려줘야 합니다. 분명하게 비빔스프, 짜장스프, 매운스프는 서로 다른 오브젝트입니다. 하지만 동일한 위치에서 동일하게 취급되어야 합니다. 만약 스프가 비빔스프, 짜장스프, 매운스프의 부모 클래스라면 컴파일러의 형(type) 검사를 비껴나갈 수 있습니다. 또한 비빔면, 짜파게티, 신라면도 다른 오브젝트입니다. 우리가 라면을 먹게될 때, 즉,
cookRaMyeon(XSoup).eat()

을 하게될 때, 비빔면/짜파게티/신라면이 각각 라면의 자식 클래스라면, 결과가 어떤 라면인지 몰라도 자연스레 각 클래스에서 eat를 정의한 대로 먹게 됩니다. class-based language에서는 다형성을 쓰는 대표적인 두 가지라 이유라 생각됩니다.

보통 타입이 없는(untyped) 언어(정확히는 dynamic typing을 하는 언어)에서는 컴파일 시간에 형(type) 체크를 하지 않습니다. 그래서 실행 시간에 에러가 나거나 의도하지 않은 결과가 나올지언정 재료에 아무거나 넣을 수 있기때문에 첫번째 다형성은 대부분 비껴나갈 수 있습니다. 대신 static typing하는 언어에서 형 검사를 통해 쉽게 발견할 수 있는 문제임에도 때론 골머리를 심하게 앓아야 할 때가 있죠. 어쨌든 이런 언어에서는 첫번째 다형성 문제가 발생하기 않기 때문에, 프로토타입(원본)의 행동을 복제하는 방식으로 두번째 다형성을 씁니다.

어쨌든, 두번째로 언급한 다형성이야 말로 OOL을 쓰는 목적이라 볼 수 있습니다.
------------------------------
How many legs does a dog have?

------------------------------
How many legs does a dog have?

jiggol의 이미지


특히 semmal님께서 제가 잘 모르는 부분을 정확히 짚으신것 같습니다.
무엇을 공부해야 될지 이제 감이 잡히네요.. 정말정말 고개 숙여 감사드립니다.~
좋은하루 되세요~~

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.