java class 상속시 하위 class의 함수를 가져다 쓰는 부분 문의드립니다.

astzlra955의 이미지

안녕하세요.

제가 java에서 아래와 같은 문제가 있어서 문의드립니다.

AAA / BBB 라는 두 class가 있습니다.
AAA 클래스에서는 start( )함수가 존재하고, BBB 클래스에는 bbb01( ) / bbb02( )함수가 존재합니다.
이 함수들은 모두 public static 입니다.
BBB extends AAA 관계이고요.
그리고 이 BBB는 library화 시켜서 소스가 안보이게 해야합니다.
참고로 AAA와 BBB는 같은 package 안에 있습니다.

이 상황에서 실제로 instance 되서 동작하는 것은 BBB 클래스 이고, AAA는 단지 BBB에 extends 하기 위해서만 존재합니다.
BBB 에서는 AAA start( )함수를 call 할 것이고, 이 start 함수는 BBB 클래스의 bbb01( ) / bbb02( )함수를 가져다 사용해야 합니다.

문제는 이렇게 만들어서 build해보니, build는 되는데 runtime에서 오류가 발생합니다.
( 참고로 start( )함수가 동작할때에는 AAA도 BBB도 instance화 되어있지 않습니다. static 함수이고 instance 없이 사용합니다. instance는 그 후에 됩니다. )
java.lang.ClassCastException: AAA cannot be cast to BBB <- 이런 오류입니다.

위 방법에서 어떤 부분이 문제인 것인지 잘 모르겠습니다.
코드를 간략히 나타내면 아래와 같습니다.

class AAA {
public static start() {
BBB.bbb01();
// 기타 코드들...
BBB.bbb02();
}
}

< 아래 BBB 클래스는 jar library로 생성 > class BBB extends AAA { public static bbb01() { } public static bbb02() { } }

이 상태에서 외부에서 BBB.start( ) 를 call 합니다.

아무래도 부모(AAA) class에서 자식(BBB) class를 가져다 사용하는것이 문제가 아닐까 싶은데, 어떻게 이 문제를 해결할 수 있을지 모르겠습니다.

좋은 하루 보내세요

klenui의 이미지

AAA, BBB가 부모 자식 관계가 맞긴 한가요?

astzlra955의 이미지

예 맞습니다.
올려놓은대로 extends로 상속받아 만들었습니다.

klenui의 이미지

코드가 그렇냐는 뜻이 아니라 설계에서 논리적 관계가 부모자식 간이 맞냐는 뜻이었습니다.

StackOverflow에 질문하면 가장 많이 보게 되는 답변인.. 왜 그걸 그렇게 하려고 하느냐.. 뭐 이런 질문이었구요..

제가 질문을 잘 이해한게 맞다면, 부모 자식간에 교차 참조가 가능한가? 라는 내용인 것 같은데, 교차 참조가 일어난다면 부모 자식 관계가 아니지요...
단순히 코드를 share하기 때문에 부모자식 관계로 잡았다면, aggregation 관계라든가 다른 관계가 더 맞지 않겠냐는 뜻이었습니다..

astzlra955의 이미지

답변 감사드립니다.

말씀하신대로 설계상의 오류라고 봐야할 것 같습니다.

library 시킨 부분을 타 업체에서 수정할 수 있도록, 부모 쪽 함수에서 library내부의 함수를 call 하도록 하려고 한건데, 이 부분이 문제인 것 같습니다.

교차 참조가 맞지요....

타 업체에서 수정할 수 있도록 다른 방법을 찾아 봐야 겠네요.

좋은 하루 보내세요.

익명 사용자의 이미지

모든 함수들이 static 으로 선언되어있네요....
윗분 댓글대로 설계적인 관점에서 우선 살펴봐야겠지만, 만약 목적이 자식클래스에서 구현된 기능을 부모가 호출하는게 목적이다 라고 했을 때
전 java는 잘 모르지만... C++로 설명해봅니다.

일단 static은 무의미해보입니다.

#define abstract virtual
#define override virtual

class AAA {
abstract void bbb01() = 0;
abstract void bbb02() = 0;

void start() { this->bbb01(); this->bbb02(); }
};

class BBB : public AAA {
override void bbb01() { printf("bbb01\n"); }
override void bbb02() { printf("bbb02\n"); }
};

BBB bbb;
bbb.start();

// output
bbb01
bbb02

전체적으로 그 코드가 원하는게 뭔지 파악하는게 선행되어야 할 것 같네요.
윗분 말대로 코드가 좀 이상합니다.

astzlra955의 이미지

답변 감사드립니다.

제가 아예 만드는 코드가 아니라 원래 존재하는 class AAA가 있고, 제가 수정하거나 추가한 기능이 있는 BBB Class가 있습니다. BBB는 AAA를 상속받아 사용합니다.

그래서 실제로 사용될 class는 BBB 입니다.
문제는 BBB를 Library로 만들어서 소스를 공개하지 않는 것입니다.

그래서 기존에는 AAA에있는 함수를 overriding 해서 사용했는데, AAA 소스를 수정하면 BBB에서도 적용이되도록 고쳐달라는 요구가 있어서요.

게다가 원본 class AAA의 함수가 static 함수였기 때문에, BBB 에서도 그 함수를 overriding 한 것을 static으로 사용하고 있습니다.

결론적으로 최종 목적은 BBB.aaa( ) 가 호출되면 AAA class의 aaa( ) 함수에서 BBB.bbb01( )과 BBB.bbb02( ) 함수를 call하는 것이었는데, 구조적으로 좀 이상하긴 합니다.

저는 static 함수이므로, 다른 class의 static 함수 call 하듯이 사용하려고 했었거든요.
( instance화 시키지 않고 함수 call )

아무래도 이 방법은 무리인 듯 합니다.

익명 사용자의 이미지

애초에 C++이든 Java든 Overriding 이란 개념 자체가 클래스 인스턴스(객체)의 전유물입니다.
static method가 overriding 될리가 없습니다.. Java에서 컴파일 에러가 없다 해도 해서는 안될 방법이죠.

차라리 BBB가 AAA를 상속받는게 아니고, AAA의 인스턴스를 소유하거나(필요하다면) 호출하는 방법으로 기능구현 하는게 좋을 것 같습니다.

class BBB
{
static void bbb01() {}
static void bbb02() {}
static void aaa() { AAA::aaa(); BBB::bbb01(); BBB::bbb02(); }
}

이렇게 되면 AAA가 수정되어도 BBB에 적용이 되는건 매한가지라고 봅니다.
실제 원하는 기능이 무엇인지 잘 파악할 수가 없어 명쾌한 답변이 어려운점 양해바랍니다.

말씀하신 기능이 C++이라면 함수포인터를 이용해서 구현은 가능합니다.
Java에 delegate 개념이 있는지 모르겠지만, 있다면 그 쪽을 알아보시는것도 좋을 듯 하네요.
1. delgate 원형 선언
2. AAA 클래스 start에서 delegate 타입 파라미터 입력
3. BBB 클래스 start에서 AAA::start(delegate list) 호출
4. AAA 클래스 start에서 입력된 delegate list를 순차 호출 list_iter->pf();

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.