2011-04-25 4 views
1

나는 여러개의 자식이있는 추상 부모 클래스를 가지고 있습니다. 그 아이가 그 아이의 모든 경우에 대해 동일한 변수를 가질 수 있기를 바랍니다. 그것은 단지 하드 코드 된 수있을 때 바보 같아 때문에 그것을 이름을 말할 수있는 생성자를 전달하지 싶습니다. 내가 읽은 것에서 다음과 같이 부모 인스턴스 변수를 숨 겼고 원하는대로 작동하지 않습니다.Java 상속 ... 혼란스러운

public abstract class Parent { 
    public String name = "the parent"; 
    public getName(name); 
} 
public class Child1 extends Parent { 
    public String name = "Jon"; 
} 
public class Child2 extends Parent { 
    public String name = "Mary"; 
} 

Child1 c = new Child1(); 
c.getName(); // want this to return "Jon", but instead returns "the parent". 

명확하게하기 위해, 기본적으로 내가 원하는 c.getClass() 같은. getName()하지만 난은 클래스 이름에 따라, 오히려 하드 코딩에 그 결과를 가지고 싶지 않아 값.

감사

+1

정확히 * 무엇이 요청되는지 분명하지 않습니다. getName()이 원하는 것을 반환 할 이유를 명확히 할 수 있습니까? 해야만하는 일련의 어설 션을 작성할 수 있습니까? –

+0

어떤 문제를 해결하려고합니까? 왜 클래스 수준 레이블 (모든 인스턴스에 대해 동일)이 필요한지에 대한 더 나은 예를들 수 있습니까? 어쩌면 우리는 더 나은 대안을 제안 할 수 있습니다. –

+0

레거시 코드를 지원하는 이름이 필요합니다. 즉, 클래스 이름을 c.getClass(). getName()을 통해 직접 사용해야하지만 코드의 나머지 부분은이를 지원하도록 작성되지 않았습니다. – Tyler

답변

3

는 당신이 실제로 위해 노력하고 내용에 따라 몇 가지가 있습니다 솔루션의.

public abstract class Parent { 
    protected Parent(String name) { 
     this.name = name; 
    } 
    public getName() {return name;} 
} 
public class Child1 extends Parent { 
    public Child1() { 
     super("Jon"); 
    } 

} 
public class Child2 extends Parent { 
    public Child2() { 
     super("Mary"); 
    } 
} 

또 다른 방법 상속 like Isaac Truett suggests을 사용하는 것입니다 : 하나는 자식 클래스가 부모에게 이름을 제공하는 것입니다.

+0

이것은 그 것이다! 부모가하는 방식에 대한 나의 가장 큰 관심사는 자식을 확장하지 않는 함수를 호출 할 때 더 조심해야한다는 것입니다. 이는 내가 이해하는 한 클래스 내에서 Getters/Setters를 사용해야한다는 것을 의미합니다 직접 액세스로 직접 멤버 변수에 액세스하는 대신 부모 변수를 가져올 수 있습니다. – Tyler

3

하드 코딩 된 이름이 각 자녀에 static final String을 만들기 :

public class Child1 extends Parent 
{ 
    public static final String NAME = "Jon"; 
} 
0

당신은 당신이 원하는 결과를 얻기 위해 getName 기능을 덮어 쓰기해야합니다. 새로운 문자열 이름이 getName 함수가 실제로 부모 문자열

+0

나는 그것을 알아 차렸다. 나는 가능한 한 많은 코드를 부모님이 지키기를 희망했다. 그래서 나는 그것을 피할 방법을 찾고 있었다. 그것이 Java가 작동하는 방식이라면 그렇게 될 것입니다. 그러나 여러분에게 먼저 물어 보았습니다. – Tyler

+0

@Tyler StriplingWarrior의 대답은 하위 클래스에 최소한의 코드 작성과 관련이 있다고 생각합니다. –

3

대신 필드의 방법을 사용을 읽고 있도록 부모 이름 (변수) 대체되지 않기 때문에 : 자바에서

public abstract class Parent { 
    public String getName() { 
    return "the parent"; 
    } 
} 

public class Child1 extends Parent { 
    public String getName() { 
    return "Jon"; 
    } 
} 
public class Child2 extends Parent { 
    public String getName() { 
    return "Mary"; 
    } 
} 

을, 적어도, 변수가 아닌 메서드 만 재정의 할 수 있습니다.

또 다른 옵션은 부모의 생성자를 매개 변수로 사용하는 것입니다. 이렇게하면 Parent이 추상적이고 모든 생성자가 name 매개 변수를 사용하는 것이 가장 좋습니다. 그런 다음 서브 클래스는 일반적으로 다음과 같은 일을 할 것이다 이름에 통과해야 : Parent 추상적 인 경우

public class Child1 extends Parent { 
    public Child1() { 
    this("Jon"); 
    // ... 
    } 
} 

는 사실, 심지어 메소드 오버라이드 (override) 방식으로, 그것은 좋다

그래서 당신이 getName() 추상적를 만들 수 있습니다.

+0

이 동작이 묻는 것과 반대가 아닙니까? 하지 않아야 간단한 공용 최종 getName() 문제를 해결? – bbaja42

+0

@ bbaja42 질문에 대한 나의 해석은 OP가'getName()'이 호출 된 인스턴스의 클래스를 기반으로 다른 이름을 반환하기를 원한다는 것입니다. 나는 그 "반대"가 무엇인지 확실하지 않습니다. 내가 이해하지 못했던 질문 중 하나는 마지막 문장에서 ".getClass()"입니다. 그것은 오타이거나 Java에서 요청되는 것입니다. 질문의 더 신중한 독서 후에 –

+0

; 당신 말이 맞아요. 반대쪽에서는 objec의 유형에 따라 다른 String이 반환된다는 것을 의미합니다. – bbaja42

6

당신은 부모의 추상 메소드를 선언하고 각각의 아이가 다음과 같이 적절한 이름을 반환하는 방법을 구현할 수 :

public abstract class Parent { 
    public abstract String getName(); 
} 

public class Child1 extends Parent { 
    private static final String NAME = "Jon"; 
    public String getName() { return NAME; } 
} 

public class Child2 extends Parent { 
    private static final String NAME = "Mary"; 
    public String getName() { return NAME; } 
} 
0

왜 생성자를 사용하지 않습니까?

public abstract class Parent { 
    public String name = "the parent"; 
    public String getName() { 
     return name; 
    } 
    public void setName(String s){ 
     name = s; 
    } 
} 
public class Child1 extends Parent { 
    public Child1() { 
     setName("Jon"); 
    } 
} 
public class Child2 extends Parent { 
    public Child2() { 
     setName("Mary"); 
    } 
} 

Child1 c = new Child1(); 
c.getName(); 

// 인쇄 '존'

+0

내 예제는 추상화되어 있지만 실제 구현은 다음과 같이 보일 것입니다 : PhotoClass pc = new PhotoClass ("photo"), 어리석은 것처럼 보이고 개발자는 항상 "photo"또는 다른 단어로 인스턴스화해야한다는 것을 알아야합니다. 그것은 작동하지 않습니다. – Tyler

+0

'PhotoClass'가 질문에 'Parent'와 유사하다고 말한다면, 아니오, 질문에 추상이라고 선언했기 때문에 새로운 PhotoClass ("Photo")를 쓸 수 없습니다. 'Parent'가 abstract가 아니라면, 그것은 질문을 상당히 바꿉니다. –

+0

PhotoClass가 자식입니다. – Tyler

1

getName()에 전화 당신이 아이 내에서 새로운 변수 호출 이름을 만들었습니다 때문에 아이의 이름은 반환하지 않습니다 이유.이 시도 :

public class Child3 extends Parent{ 
    public String name = "Jon"; 

    public String getNames(){ 
     return super.name + " : " + name; 
    } 
} 

당신은 볼 수 있습니다 :

super.name = "Jon"; 
0

당신은 할 수 :

the parent : Jon 

올바른 방법은 부모의 name 변수로 아이의 이름을 설정하는 말을하는 것입니다 Java Reflection을 사용하여이 작업을 수행하는 것은 매우 깨끗한 방법은 아닙니다.

public abstract class Parent { 
    public String name = "the parent"; 
    public String getName() throws Exception { return getClass().getField("name").get(this).toString(); } 
} 

비록 Isaac의 접근 방식이 솔루션에 접근하는 가장 좋은 방법이라고 생각하지만.

+0

아니요. 그냥 싫다. –

+0

@Isaac 살인자가 쉽다. 그는 우리가 먹을 것이 아니라 시금치를 먹을 것을 제안한 것 같지 않다. 가까운 것이지만. :) –

+0

@ josh.trow 나는 시금치를 먹고 싶다. (발사믹 vinaigrette와 함께하시기 바랍니다) 리플렉션을 남용하는 디버그 코드 슬프게도, 후자의 직업은 더 잘 지불합니다. :) –