2014-09-17 5 views
0

내 arraylist에서 Car 클래스의 메소드에 액세스하려고합니다. 클래스 계층 구조는 본질적으로 : 재판의 많은 통해 나 '오류가Java : arraylist의 객체에서 서브 클래스 메소드에 액세스

Ford vehicle1 = new Ford(id, model, etc); 
Chevy vehicle2 = new Chevy(id, model, etc); 

ArrayList<Vehicle> list = new ArrayList<Vehicle>(); 
list.add(vehicle1); 
list.add(vehicle2); 

:이 예에서

class Vehicle {} 
class Car extends Vehicle {} 
class Chevy extends Car {} 
class Ford extends Car {} 

Car 클래스는 main 방법은 다음과 같습니다 getID()

라는 게터있다 다음과 같이 getID() 메소드에 액세스 할 수 있습니다.

System.out.println("Vehicle ID: " + ((Chevy) list.get(1)).getID()); 

어느 것이 작동하는지 ... 나는 다만 이것이 적당한 방법으로하고 있다고 상상할 수 없다. 이러한 하위 클래스 메서드에 액세스하는 더 좋은 방법이 있습니까?

답변

0

심각한 프로그램의 경우 Vechicle 인터페이스는 모든 차량에 공통적으로 적용되는 모든 행동 방식을 정의해야하며 여기에는 getID() 메소드가 포함되어야합니다. 그러나 어떤 경우에는 만이 특정 유형의 차량에 적용되는 구체적인 방법을 원할 수 있습니다. 하위 클래스 나 하위 인터페이스에서 서브 클래스를 사용하여 Vehicle으로 변경해야합니다. 위의 예를 들어, 메소드를 사용하여 NamedVehicle을 갖고 싶을 수도 있습니다. 인터페이스와 수업을 준비하는 방법은 당신에게 달려 있습니다. 그것이 도움이된다면 브릿지 디자인 패턴을 참조하십시오.

매우 가끔 장소에서 명시 적 캐스트를 원합니다.

0

목록에 하위 클래스 개체를 추가해도 괜찮은 것처럼 보이지만 목록을 반복 할 때 어떤 하위 개체에 액세스할지 모를 것입니다.

다음과 같은 방법으로 부모 참조 점을 자식 객체에 넣을 수 있습니다.

Car vehicle1 = new Ford(id, model, etc); 
Car vehicle2 = new Chevy(id, model, etc); 

다음과 같이 목록에 추가하십시오. 목록을 반복 할 때 instanceof 검사를 기반으로 정보가 유실됩니다.

예 :

Car c = (Car)list.get(0)).getID(); 
if(c instanceof Ford){ 

    Ford f = (Ford)c; 
    System.out.println(f.getId()); 

} 
0

차량이 인터페이스는 (클래스가 인터페이스를 확장 할 수 없습니다, 그들은 그것을 구현)하지 왜? 그런 방법이있는 서브 클래스 (Chevy를 같은) 오류가 발생에 Vehicle 배열 목록 개체를 캐스팅하지 왜

는 지금까지 내가 Car가 수행하는 getId() 동안이없는 Vehicle 이해로, 그입니다. 당신이 한 경우

은 :

System.out.println("Vehicle ID: " + ((Car) list.get(1)).getID()); 

그것은 일 것입니다.다음은 액세스 할 수는 getId() 방법은 Car 클래스에 선언되어 있기 때문에

Car vehicle1 = new Ford(id, model, etc); 
Car vehicle2 = new Chevy(id, model, etc); 

ArrayList<Vehicle> list = new ArrayList<Vehicle>(); 
list.add(vehicle1); 
list.add(vehicle2); 

System.out.println("Vehicle ID: " + list.get(1).getID()); //Chevy ID 
0

:

interface Vehicle{ 
    public int getId(); 
} 

class Car implements Vehicle{ //altough I think this also should be abstract 
    int id; 

    @Override 
    public int getId(){ 
     return id; 
    } 
} 

이 구성 당신이 할 수 있습니다

난 당신이 Vehicle에게 인터페이스를 만들기 위해 제안 이 메서드는 상속을 통해 (의 소스 코드는 액세스 수정 자 protected 또는 public 중 하나로 표시해야합니다.

그래서 Car의 서브 클래스는 getId() 방법에 액세스 할 수 있습니다 그 방법은 따라서 방법의 행동이 현재 개체를 기반대로 계산됩니다 런타임에 관련된 하위 유형에를 오버라이드 (override)가 아니면 Car#getId에 표시된 동작을한다 개체 참조가 아니라 형식.

지금 가장 유명한 OO (개체 지향) 다형성 인 기능 중 하나에 오는

(여러 형태)는 자동차가 필요로하는 모든 Car 하위 유형을 통과하고, 당신이 Car을 예상 할 때 어떤 Car 하위 유형을 반환 할 수있는 예. 그것이 실제 어떤 유형 (Ford, Chevy 당신은 목록의 모든 항목에 어떤 Car 인스턴스 메소드를 호출 한 후 수있을 것입니다 : 그래서

CarArrayList (들)의 모든 Car 하위 유형을 가질 수 sumup하기 그것은 Car의 자식이기 때문에 중요하지 않습니다.

주요 문제는 이제 기술 동작은 다른 측면에 갈 수 없어, 그래서 (당신의 경우 Vehicle)를 부모 참조는하지 않는 한 그 자손 동작 (귀하의 경우에 Car)에 대해 결코 알지 못할 것입니다 노골적인 캐스트가 도로 아래에서 만난다.

은 그럼 당신은 단순히 instantiante에 넣어 필요가됩니다 ArrayListCar으로 일반 유형 (당신이 <Vehicle>, <Car> 말할 때 당신이하고있는 일입니다)를 사용하여 :

public static void main(String[] args) 
{ 
    Ford vehicle1 = new Ford(id, model, etc); 
    Chevy vehicle2 = new Chevy(id, model, etc); 

    ArrayList<Car> list = new ArrayList<Car>(); //Use a Car as generic type so you can call all car methods 
    list.add(vehicle1); 
    list.add(vehicle2); 

    for(Car car : list) 
    { 
    System.out.println(car.getId()); // Iterate over the list and retrieve each element ID 
    } 
} 
관련 문제