2010-05-13 9 views
5

내 학기 프로젝트의 경우, 팀과 나는 게임 개발 프레임 워크를 포함하고 OOP의 개념을 보여주는 .jar 파일 (실행 가능하지 않은 라이브러리)을 만들어야합니다. FRAMEWORK이되어야하고 다른 팀은 우리 프레임 워크를 사용하고 그 반대로도 사용되어야합니다. 그래서 저는 어떻게 시작해야하는지 알고 싶습니다. 우리는 여러 가지 방법을 생각 : 사용자 정의 적 추상 회원추상 기본 클래스 또는 클래스?

public abstract class Enemy { 
    public Enemy(int x, int y, int health, int attack, ...) { 
     ... 
    } 
    public abstract void draw(); 
    public abstract void destroy(); 
    ... 
} 
public class UserDefinedClass extends Enemy { 
    ... 
    public void draw() { 
     ... 
    } 
    public void destroy() { 
     ... 
    } 
} 

3.을 상속해야한다는 추상 클래스와 일반 클래스

public class Enemy { 
    public Enemy(int x, int y, int health, int attack, ...) { 
     ... 
    } 
    ... 
} 
public class UserDefinedClass extends Enemy { 
    ... 
} 

2. 시작으로
1. 시작합니다 만들기 모두가 상속받은 슈퍼 ABC (추상 기본 클래스)

public abstract class VectorEntity { 
    ... 
} 
public abstract class Enemy extends VectorEntity { 
    ... 
} 
public class Player extends VectorEntity { 
    ... 
} 
public class UserDefinedClass extends Enemy { 
    ... 
} 

어떤 것을 사용해야합니까? 아니면 더 좋은 방법이 있습니까?

답변

6

글쎄, 당신이하고있는 일을 깊이 알지 못해도 말하기가 약간 어렵고, 심지어 주관적이다. 그러나, 당신에게 말할 수있는 몇 가지 사항을 고려해야합니다.

  1. 그들은 실제로 적을 생성 할 예정입니까, 아니면 모든 적을 실제로 파생 된 유형으로해야합니까? 파생 된 유형이 아닌 Enemies를 실제로 인스턴스화하지 않으려는 경우 인터페이스 또는 추상 클래스 여야합니다.

  2. 기본 클래스에서 실제 동작을 제공하려면 분명히 인터페이스가 아닌 클래스 여야합니다.

  3. API가 있어야하지만 구현을 제공하는 데 의미가없는 메소드는 추상적이어야합니다.

  4. 기본 클래스에서 구현하는 것이 좋은 방법은 기본 클래스에서 구현해야합니다. 그리고 그들이 그것을 재정의하는 것이 타당하지 않다면, 최종적으로 만드십시오.

  5. 클래스를 공유하는 공통된 기본 클래스는 실제로 동작을 공유하거나 코드의 어딘가에서 모두 동일하게 처리해야하는 경우에만 의미가 있습니다. 정말 비슷하지 않다면 기본 클래스를 공유해서는 안됩니다. 예를 들어, Enemy와 Player가 모두 표시 가능하다고 가정하면 디스플레이 기능을 처리하는 공통 기본 클래스를 갖는 것이 좋습니다. 그러나 Enemy가 표시 가능한 항목이고 Player가 게임의 컨트롤러처럼 더 추상적 인 개념이었고 표시 할 수없는 경우 기본 클래스를 공유하는 것이 적절하지 않을 수 있습니다. 일반적으로 클래스를 생성 할 때 상속보다는 컴포지션을 선호하는 편이 낫습니다. 따라서 문제의 클래스가 실제로 동작을 공유하지 않고 공통 기본 클래스와 "is-a"관계를 실제로 갖지 않으면 공통 기본 클래스를 공유하지 않아야합니다.

  6. 기본 클래스는 데이터가 아닌 메서드 만 공유하는 것이 좋습니다. 즉, 상속 트리에서는 나뭇잎 만 구체화 할 수있는 것이 가장 좋습니다. equals() 같은 실제 데이터가있는 기본 클래스가있을 때 여러 가지가 있습니다. 그것은 당신이 그것을 할 수 없다는 것을 말하는 것은 아닙니다. 사람들은 항상 그렇게합니다. 그러나 문제가 발생할 수 있으며, 필요하지 않으면 피하는 것이 가장 좋습니다.

  7. 추상적 인 메소드를 대체하는 것이 좋습니다. 그렇지 않으면 파생 클래스에서 기본 클래스의 메서드를 호출하거나 메서드가 수행하는 작업을 완전히 변경하지 않을 수 있습니다.

나는 더 많은 것을 생각해 낼 수 있다고 확신하지만, 프로젝트에 익숙하지 않은 채 오히려 일반적입니다. 당신이 준 3 가지 옵션 중에서 아마도 2와 함께 갈 것입니다. 3 아마 무관 한 클래스를위한 기본 클래스를 만드는 것처럼 보이고, 1은 Enemy가 인스턴스화 될 수있게합니다. 상속 계층 구조의 리프가 인스턴스화 될 수 있도록 명확하게 만들 것입니다. 아마도 기본 클래스의 데이터는 2로 끝날 지 모르지만 추상 메소드 만 재정의 할 가능성이 높으며 파생 클래스에서 변경된 동작에 대한 문제가 줄어 듭니다. 책 "더 효과적인 C++"271 페이지 중

0

내 행동 규칙은 동일한 작업/데이터/방법/기능을 공유하는 둘 이상의 클래스가있는 한 동일한 추상 클래스의 확장이어야한다는 것입니다. 그것이 경우

그래서, 내가 그 일 :

  • 을 모든 클래스 공통점이있는 경우, 한 한 곳에서이 기능/필드/데이터를 수집 최상위 abstract class은.
  • 그렇지 않은 경우 실제로 공통점이있는 클래스 만 하위 수준 abstract class까지 확장해야합니다.

클래스 만 공통적으로 사용할 수있는 방법 만있는 경우 interface을 사용할 수도 있습니다. 그러나 나는 조만간 조만간 interface을 구현하는 클래스가 동일한 private 필드를 가지고 있음을 알게된다. 이 시점에서 interface을으로 변환하여 다른 필드가없는 경우 코드 줄을 저장합니다.

1

네 번째 옵션은 인터페이스를 사용하는 것입니다.

interface Enemy { 

    public void draw(); 

    . . . 

} 

방금 ​​시작한 경우 세 번째 옵션을 사용하지 마십시오. 프레임 워크를 조금만 개발하고 필요가 있는지 확인하십시오.

0

그냥 작은 답 :

"는 hierachy의 끝없는 기본 클래스 개요를 확인하십시오." 나는 너에게 전체 chapert를주기에는 너무 게을러졌지만, autor는 그것에 대한 좋은 이유를 열거한다.

+0

"효과적인 자바"가 있는데이 경우 더 적용 할 수 있습니다. 그것은 비슷하지만 비슷한 것을 말합니다. 자바에 더 특이한 것들을 말합니다 - 기본 클래스가 모두 추상이 아닌 경우, 파생 된 유형과 기본 유형을 혼합 할 때'equals()'가 제대로 작동하지 않는 것과 같은 것입니다. –

관련 문제