ジェネリックメソッドを持つ抽象クラスがあり、ジェネリックパラメーターを特定の型に置き換えることでジェネリックメソッドをオーバーライドしたい。そのため、擬似コードには次のものがあります。
_public abstract class GetAndParse {
public SomeClass var;
public abstract <T extends AnotherClass> void getAndParse(T... args);
}
public class Implementor extends GetAndParse {
// some field declarations
// some method declarations
@Override
public <SpecificClass> void getAndParse(SpecificClass... args) {
// method body making use of args
}
}
_
しかし、何らかの理由で私はこれを行うことはできませんか?何らかの構文エラーを起こしていますか、またはこの種の継承とオーバーライドは許可されていませんか?具体的には、Eclipse IDE=がgetAndParse
を実装することを思い出させ続けるため、_@Override
_に関するエラーが発生します。
上記のコードがどのように機能するかを以下に示します。私のコードのどこかに、GetAndParse
を実装するオブジェクトのインスタンスを期待するメソッドがあります。これは、具体的には、使用できるgetAndParse
メソッドがあることを意味します。そのインスタンスでgetAndParse
を呼び出すと、コンパイラはT
の特定のインスタンスを適切な方法で使用したかどうかを確認するため、特にT
はAnotherClass
を拡張し、SpecificClass
である必要があります。
ここにあるのは、それぞれ個別の型パラメーターを持つ2つの異なるメソッドです。
public abstract <T extends AnotherClass> void getAndParse(Args... args);
これはTという名前の型パラメーターを持ち、AnotherClass
で区切られたメソッドです。つまり、AnotherClass
の各サブタイプは型パラメーターとして許可されます。
public <SpecificClass> void getAndParse(Args... args)
これはSpecificClass
という名前の型パラメーターを持つメソッドであり、Object
で区切られます(つまり、各型は型パラメーターとして許可されます)。これ本当に欲しいですか?
TypeパラメーターはArgs
内で使用されていますか?問題があると思います。
の意味
public abstract <T extends AnotherClass> void getAndParse(T... args);
メソッドのcallerは、これがAnotherClass
のサブタイプである限り、メソッドを呼び出すタイプパラメーターを決定できることです。これは、AnotherClass
型のオブジェクトでメソッドを呼び出すことができることを意味します。
呼び出し元が型パラメーターを決定できるため、サブクラスでパラメーター型をSpecificClass
に絞り込むことはできません。これはメソッドの実装ではなく、同じ名前の別のメソッド(オーバーロード)です。
たぶんあなたはこのようなものが欲しい:
public abstract class GetAndParse<T extends AnotherClass> {
public SomeClass var;
public abstract void getAndParse(T... args);
}
public class Implementor extends GetAndParse<SpecificClass> {
// some field declarations
// some method declarations
@Override
public void getAndParse(SpecificClass... args) {
// method body making use of args
}
}
これで、getAndParse
メソッドは親クラスのメソッドを実装します。
Java Genericsの「Erasure」という概念のため、この問題が発生しています。 Javaは「消去」を使用して下位互換性をサポートします。つまり、ジェネリックを使用しなかったJavaコード。
消去手順:
コンパイラは最初に型チェックを行い、次にすべての型パラメーターを可能な限り削除(消去)し、必要に応じてTypeCastingを挿入します。
例:
public abstract <T extends AnotherClass> void getAndParse(T paramAnotherClass);
となります
public abstract void getAndParse(AnotherClass paramAnotherClass);
クラス「Implementor.Java」では、
コード
public <SpecificClass> void getAndParse(T paramAnotherClass)
となります
public void getAndParse(SpecificClass paramAnotherClass){ }
コンパイラは、抽象メソッドを正しく実装していないことを確認します。抽象メソッドと実装されたメソッドの間に型の不一致があります。これがエラーが表示される理由です。
詳細はこちらをご覧ください。 http://today.Java.net/pub/a/today/2003/12/02/explorations.html
いいえ、無効です。 GetAndParse
参照を持つ誰かが異なるAnotherClass
を拡張するクラスで呼び出した場合はどうなりますか?
誰かがGetAndParse型への参照を持ち、getAndParseメソッドを呼び出そうとすると、それはナンセンスになります。 CatとDogがAnotherClassを拡張する場合。 CatまたはDogのいずれかを使用してGetAndParse#getAndParseを呼び出すことができるはずです。しかし、実装はそれを制限し、互換性を低くしようとしました!
特定のタイプTに対してオーバーライドを使用することはできません。実際には(必要に応じてバイトコードレベルで)タイプ消去のためにメソッドgetAndParse
が1つしかないためです(他の回答を参照)。
public abstract void getAndParse(AnotherClass... args); // (1)
Tのタイプごとに、同じ方法が使用されます。
オーバーロード it(私は思う):
public void getAndParse(SpecificClass... args); // (2)
ただし、これは(1)とは異なるメソッドではありません。antnotは汎用コードによって呼び出されます。
T x = whatever;
object.getAndParse(x); // Calls (1) even if T is derived from SpecificClass
静的メソッドはオーバーライドできません
class Vehicle{
static void park(int location){
System.out.println("Vehicle parking..");
}}
class Car extends Vehicle{
@Override //error
void park(int location) { //error
System.out.println("Car Parking..");
}}
プライベートメソッドはオーバーライドできません
class Vehicle{
private void park(int location){
System.out.println("Vehicle parking..");
}
void callPark(){
park(100);
}}
class Car extends Vehicle{
//@Override
void park(int location) {
System.out.println("Car Parking..");
}}
class Demo {
public static void main(String[] args) {
Vehicle v1=new Car();
v1.callPark();
}}
最終メソッドはオーバーライドできません
class Vehicle{
final void park(int location){
System.out.println("Vehicle parking..");
}}
class Car extends Vehicle{
//@Override
void park(int location) { //error
System.out.println("Car Parking..");
}}