1

タイトルどうしようか迷う…

、、、の 3 つの子クラスがありEventます。どういうわけか、私は子供の 1 人のオブジェクトを取得します。ここで、その子イベントを別のオブジェクトのメソッドに送信して、メソッドでデータを取得できるようにします。データのプルはイベントのタイプに固有であるため、メソッドは子にのみ存在します。WeightEventTimedEventRepEventgetSavedEvents()

私はから始めました

public void setEvent(Event e) {

Eventしかし、それは私の子オブジェクトを(親)オブジェクトにキャストします。

3 つの異なるメソッドを記述することの不足を回避する方法はありますか。子供たちに一人ずつ?

public void setEvent(WeightEvent e) {
public void setEvent(TimedEvent e) {
public void setEvent(RepEvent e) {

アドバイスをありがとう。

-ジョン

4

8 に答える 8

7

参照はキャストされますが、実際のオブジェクトの型は変更されません。参照を渡すと、それは引き続き子オブジェクトのインスタンスへの参照になります。通常は、必要に応じて親型に適切な抽象メソッドを使用して、これで十分です。

ただし、必要なメソッドが子の型に固有であり、それらすべてを一般的に実装できる適切な抽象化を考え出すことができない場合は、コードinstanceof内で使用する必要があるか、またはする必要がありますメソッドをオーバーロードします...イベントの正確なタイプに応じて、さまざまなコードを呼び出す必要があるためです。setEvent

いくつかのメソッド シグネチャを除いてコードを確認できないため、これは少しあいまいです。何をしようとしているのか、特に何を達成する必要があるか、子クラスのさまざまなメソッドが何であるかについて、詳細を教えていただければ、setEventさらにお役に立てるかもしれません。

于 2009-12-17T07:24:42.863 に答える
3

タイプをオンにする代わりに、イベント タイプのタイプごとに異なる方法で定義されたイベントでメソッドを呼び出す必要があります。これをTemplate メソッド パターンと呼びます。(C++ テンプレートとは関係ありません、ところで)

このパターンを使用すると、EventTable クラスは次のようになります。

public class EventTable {
  public void setEvent(Event e) {
    int x = 0;
    columns = e.getFields();
    Event[] savedEvents = e.getSavedEvents();
    for(Event ev : savedEvents) {
      tempdata[x] = ev.getTempData();
      x++;
    }
  }
}

スイッチ全体が getTempData() への 1 回の呼び出しに置き換えられていることに注意してください。このメソッドは、getSavedEvents と同様に Event で抽象化されます。

public abstract class Event {
  public Date getDate() { return(_date); }
  public abstract Event[] getSavedEvents();
  public abstract int[] getTempData();
  public int[] getFormattedDate() {
    ...

}

次に、各サブクラスで getTempData() メソッドを定義します。例えば:

public class WeightEvent extends Event {
  public int getWeight() { return(_weight); }
  public int getReps() { return(_reps); }
  public int[] getTempData() {
    return new int[]{
      getFormattedDate()[0],
      getWeight(),
      getReps()
    };
  }
}

public class TimedEvent extends Event {
  public String getTimeInHMS() { return(_timeString); }
  public int[] getTempData() {
    return new int[]{
      getFormattedDate()[0],
      getTimeInHMS()
    };
  }
}

public class RepEvent extends Event {
  public int getReps() { return(_reps); }
  public int[] getTempData() {
    return new int[]{
      getFormattedDate()[0],
      getReps()
    };
  }
}
于 2009-12-19T05:01:01.780 に答える
1

私はあなたのprobemが変数getSavedEvents()を持っているときに呼び出していると思います。 その場合は、抽象メソッドをに追加します。これも抽象として宣言する必要があります。 Event
getSavedEvents()Event

    public abstract class Event {
        public abstract Events getSavedEvents();
        ...
    }

抽象的Eventであるため、そのインスタンスを作成することはできません。使用するにはサブクラス化する必要があります。それが問題である場合は、例外をスローするか、アプリケーションに適した処理を実行してください(何もせず、nullを返すだけです)Event.getSavedEvents()

    public class Event {
        public Events getSavedEvents() {
            throw new UnsupportedOperationException("must be called in a child class");
            // OR return null;
        ...
    }

getSavedEvents()これで、他のオブジェクトでメソッドを 呼び出すことができます。

    public class OtherObject {
        private Event event;
        public void setEvent(Event e) {
            event = e;
            ...
            Events events = event.getSavesEvents();

の実際のクラスによって実装されたメソッドeが使用されます。たとえば、eがの場合TimedEvent、そのクラスのメソッドが呼び出されます。

于 2009-12-17T10:41:20.423 に答える
0

すべての子がそのメソッドを実装しているため、abstractを使用するとgetSavedEvents()メソッドが役立ちます。

setEvent()のコードは次のとおりです。

public class EventTable {
public void setEvent(Event e) {
 int x = 0;
 int type = e.getEventType();

 columns = e.getFields();
 Event[] savedEvents = e.getSavedEvents();
 for(Event ev : savedEvents) {
  tempdata[x][0] = ev.getFormattedDate()[0];
  switch(type) {
   case EVENTTYPE.WEIGHT:
    tempdata[x][1] = ev.getWeight();
    tempdata[x][2] = ev.getReps();
   break;
   case EVENTTYPE.TIMED:
    tempdata[x][1] = ev.getTimeInHMS();
   break;
   case EVENTTYPE.REP:
    tempdata[x][1] = ev.getReps();
   break;
  }
  x++;
 }
}
}

このコードは、Eventクラスに「abstract」を追加し、getSavedEvents()という抽象メソッドを定義した後に機能します。

次の問題は、getWeight()、getReps()、およびgetTimeInHMS()メソッドです。これらは子イベントのタイプに固有であり、親のEventクラスには存在しません。イベントでそれらを抽象化する場合、getReps()にTimedEventのコンテキストがない場合でも、各子でそれらを定義する必要があります。

public class Event {
 public Date getDate() { return(_date); }
}
public class WeightEvent extends Event {
 public int getWeight() { return(_weight); }
 public int getReps() { return(_reps); }
}
public class TimedEvent extends Event {
 public String getTimeInHMS() { return(_timeString); }
}
public class RepEvent extends Event {
 public int getReps() { return(_reps); }
}

明らかに、省略されたコード。WeightEventsには、日付、重み、および担当者が関連付けられています。TimedEventsには、日付と時間の長さが関連付けられています。RepEventsには、日付と担当者の数が関連付けられています。日付メソッドはイベント間で共通であるため、すべて親にあります。

getWeight()、getReps()を抽象化せず、関連する子でのみ宣言する場合、上記のコピーされたsetEvent()メソッドのEventTableから取得するエラーは次のとおりです。

EventTable.java:124: cannot find symbol
symbol  : method getWeight()
location: class Event
     tempdata[x][1] = ev.getWeight();

-ジョン

于 2009-12-17T18:10:52.720 に答える
0

Event eオブジェクトを子クラスにキャストできinstanceofます。Java の演算子が役立つと思います。

于 2009-12-17T07:25:42.520 に答える
0

訪問者パターンを使用できるかもしれません。

于 2009-12-17T13:30:22.337 に答える
0

インターフェイスの背後にある問題を抽象化できます

interface IEvent
{
    abstract public void doSomething();
}

次に、すべてのイベント クラスにそれを実装させます。

class WeightedEvent implements IEvent
{
    public void doSomething()
    {
        // do something
    }
}

次に、単一のメソッドのみが必要であり、型チェックを行う必要はありません

public void setEvent(IEvent e)
{
    e.doSomething();
}

HTH

于 2009-12-17T07:54:05.360 に答える