3

Javaで関数オブジェクトを実装しようとしています。Unitクラスがあり、Unitオブジェクトのほとんどの初期化で使用されるデフォルトの加算関数があります。ただし、いくつかの問題については、別の加算関数が必要です。コードは次のようになります。

public class Unit() {
   public Unit(unitType) {
      if (unitType == "specialType") {
         additionFunc = defaultFunc } else {
         additionFunc = specialFunc }
      }
   }
   public int swim() {
      return additionFunc()
   }
  // definiion of regularFunc
  // definition of specialFunc

}

次に、メインファイルから:

Unit fish = new Unit(regularTyoe);
Unit fatFish = new Unit(specialType);
fish.swim(); //regular function is called
fatFish.swim(); //special function is called

それだけです..これがどのように行われるか知っている人はいますか?

4

7 に答える 7

4

継承メソッドのオーバーライドを検索する必要があります。おそらく、適切なオブジェクト指向プログラミングについても読むのに役立つでしょう。

これを行う適切な方法は次のとおりです。

class Fish {
  public void swim() {
    // normal swim
  }
}

class FatFish extends Fish {
  @Override
  public void swim() {
    // special swim
  }
}

Fish fish = new Fish()
Fish fatFish = new FatFish()
fish.swim()    // normal swim
fatFish.swim() // slow swim
于 2012-07-30T15:37:00.800 に答える
2

Unitを拡張してswim()をオーバーライドする新しいFatFishクラスを作成します。

Unit fish = new Unit();
Unit fatFish = new FatFish();
fish.swim(); //regular function is called
fatFish.swim(); //special function is called
于 2012-07-30T15:33:37.680 に答える
2

問題には多くの解決策があります。そのうちの1つは継承を使用しており、デフォルトの実装を使用してUnit、目的のメソッドを新しいメソッドでオーバーライドするように拡張できます。

基本的には次のようになります。

public class FatFish {
    @Override
    public void swim() {
        // new behavior 
    }
}

もう1つのアプローチは、実行時にアルゴリズムを選択できるStrategyDesignPatternを実装することです。したがって、次のようなことができます。

public interface SwimStrategy {
    void execute();
}

public class FatFishSwimStrategy implements SwimStrategy {
    @Override
    public void execute() {
        // fat fish swim impl
    }

}

public class FishSwimStrategy implements SwimStrategy {
    @Override
    public void execute() {
        // normal fish swim impl
    }

}

public class Fish {

    private final SwimStrategy swimStrategy;

    public Fish(SwimStrategy swimStrategy) {
        this.swimStrategy = swimStrategy;
    }

    public void swim() {
        swimStrategy.execute();
    }

}

オブジェクトをインスタンス化するには、次のようにします。

new Fish(new FatFishSwimStrategy());

または通常の動作の場合:

new Fish(new FishSwimStrategy());
于 2012-07-30T15:44:18.453 に答える
1

単純なifステートメントの使用:

private String unitType;

public Unit(unitType) {
    this.unitType = unitType;      
}

public int swim() {
    if (unitType.equals("specialType") {
        return specialFunc();
    }
    else {
        return regularFunc();
    }
}

または、ポリモーフィズムとファクトリメソッドを使用します。

public abstract class Unit() {

    protected Unit() {
    }

    protected abstract int addition();

    public int swim() {
        return addition();
    }

    public static Unit forType(String unitType) {
        if (unitType.equals("specialType") {
            return new SpecialUnit();
        }
        else {
            return new RegularUnit();
        }
    }

    private static class SpecialUnit extends Unit {
        @Override
        protected addition() {
            // special addition
        }
    }


    private static class RegularUnit extends Unit {
        @Override
        protected addition() {
            // regular addition
        }
    }
}

または、Adder機能インターフェイスを使用して、addition()メソッドを定義し、このインターフェイスの2つの具体的な実装を行います。

private Adder adder;

public Unit(unitType) {
    if (unitType.equals("specialType") {
        this.adder = new SpecialAdder();
    }
    else {
        this.adder = new RegularAdder();
    }  
}

public int swim() {
    return adder.addition();
}

この最後のものは、あなたがあなたの質問で尋ねたものに最も近いものです。関数オブジェクト自体は存在しませんが、インターフェースで置き換えることができます。

于 2012-07-30T15:38:43.477 に答える
1

Javaでこのポリモーフィックな動作を実現するには、2つの方法があります。1つは、継承とクラスの階層セットを使用することです。たとえば、「swim」と呼ばれる抽象メソッドを定義する抽象基本クラスを持つことができます。次に、各具体的な魚のクラスは、この基本クラスを拡張し、swimメソッドを実装します。後で魚のオブジェクトのセットがある場合、それらを基本クラスにアップキャストして、それぞれでswimメソッドを呼び出すことができます。

2番目の方法は、インターフェイスを使用することです。パブリックメソッドswimを宣言するインターフェイス(ISwimなど)を定義します。各魚のクラス(クラス階層の一部であるかどうかに関係なく)は、ISwimインターフェイスを実装します。つまり、swimメソッドを定義します。次に、さまざまなタイプの魚クラスオブジェクトのセットがある場合は、それぞれをISwimインターフェイスにキャストし、各オブジェクトでswimメソッドを呼び出すことができます。

Javaには関数ポインタがないため、検討しているアプローチは言語には不適切です。関数ポインタを使用する言語でも、上記の2つのアプローチが私の意見では最も適切です。

于 2012-07-30T15:39:30.380 に答える
1

これを行う1つの方法は、サブクラスenumのタイプUnitUnitサブクラスを使用することです。

public class Unit {
    public enum UnitType {
        REGULAR {
            public Unit makeUnit() {
                return new RegularUnit();
            }
        },
        SPECIAL {
            public Unit makeUnit() {
                return new SpecialUnit();
            }
        };
        abstract public Unit makeUnit();
    }
    protected Unit() {}
    public abstract int swim();
    private static class RegularUnit extends Unit {
        RegularUnit() {}
        public int swim() {
            return 0;
        }
    }
    private static class SpecialUnit extends Unit {
        SpecialUnit() {}
        public int swim() {
            return 1;
        }
    }
}

Unit fish = UnitType.REGULAR.makeUnit();
Unit fatFish = UnitType.SPECIAL.makeUnit();

別の方法は、Callableオブジェクトを使用することです。

public class Unit {
    public enum UnitType { REGULAR, SPECIAL }
    private Callable<Integer> additionFunc;
    public Unit(UnitType type) {
        switch (type) {
        case REGULAR:
            additionFunc = new Callable<Integer>() {
                public Integer call() {
                    return 0;
                }
            };
            break;
        case SPECIAL:
            additionFunc = new Callable<Integer>() {
                public Integer call() {
                    return 1;
                }
            };
            break;
        }
    }
    public int swim() {
        return additionFunc();
    }
}
于 2012-07-30T15:39:32.883 に答える
1

拡張とファクトリメソッドで実行できると思います。

パブリッククラスユニット{

public static Unit createUnit(UnitType type) {
    if (UnitType.Special == type) {
        return new Unit(type) {
            @Override
            public int swim() {
                System.out.println("special swim");
                return 0;
            }
        };
    }
    return new Unit(UnitType.Default);
}

private UnitType type;

private Unit(UnitType type) {
    this.type = type;
    System.out.println("create unit for " + type);
}

public int swim() {
    System.out.println("default swim");
    return 0;
}

public static void main(String[] args) {
    Unit fish = Unit.createUnit(UnitType.Default);
    Unit fatFish = Unit.createUnit(UnitType.Special);
    fish.swim();
    fatFish.swim();

}

}

これは単純な型の列挙型です:

public enum UnitType {デフォルト、特殊

}

于 2012-07-30T15:43:42.127 に答える