我有一堆我不能改變的類;所有這些類都有一個共同的祖先(Object除外),這些祖先聲明並實現了它們的大部分屬性和方法。帶有不兼容構造函數的java繼承
比方說,我們有一個繼承樹像這樣(只用於說明目的):
class Vehicle
class Bicycle extends Vehicle
class Skateboard extends Vehicle
class Boat extends Vehicle
class Car extends Vehicle
class Aircraft extends Vehicle
class Jetplane extends Aircraft
class Helicopter extends Aircraft
...
class Truck extends Vehicle
...
雖然class Vehicle
其實更像是一個抽象類(它是不是真的,但它永遠不會實例自身代表),偶爾會創建class Aircraft
的對象。
現在的觀點:對象可以有不反映類的相互關係。由於它是相當一類的類,並且集合每隔一段時間都會改變,所以爲實現缺失行爲的每個類維護一個子類是不實際的。
因此,我的方法是讓一個類用作上述類的包裝。 構造函數將相應對象的類作爲參數,然後使用反射對其進行實例化。
class VehicleW
{
// fields
public boolean isInitialized=false;
private Vehicle fVehicle;
...
// constructors
public VehicleW(Class aClass, ...)
{
Class VehicleClass = Vehicle.class;
if (!VehicleClass.isAssignableFrom(aClass))
return;
// <the reflection magic here>
...
// and on success mark this object as usable
isInitialized=true;
}
}
沒有參數的構造函數在這裏沒有意義。但現在class Aircraft
及其子類想要一些額外的屬性,所以我想我可以建立一個class AircraftW extends VehicleW
照顧他們。
然後修改如下:
// fields
private Aircraft fAircraft;
// constructors
public AircraftW(Class aClass, ...)
{
Class AircraftClass = AirCraft.class;
if (!AircraftClass.isAssignableFrom(aClass))
return;
// <the reflection magic here>
...
// and on success mark this object as usable
isInitialized=true;
}
但這種失敗,因爲Java智能插入的祖先,這是不存在的參數的構造函數的調用(和沒有意義,因爲已經說過)。
調用參數化的super()也沒有意義,因爲我初始化了class Vehicle
的字段。好的,我稍後可以在AircraftW()
中將該字段設置爲null
,但這看起來不正確。
有沒有辦法解決這個問題?或者我正在採取絕對錯誤的方法?我想過泛型,但我似乎無法找到使用它的一點。接口?我不是一個Java專家,所以任何建議都是值得歡迎的。
編輯(未解決的(避免解決)術語)好了,下面你找到一個工作程序。我不能把它作爲答案,因爲托馬斯帶領我去了這個代碼......他的答案......我接受了這個解決方案......我看不出有什麼問題。
謝謝,托馬斯,指出我在正確的方向。
對於持懷疑態度,這裏的完整源的測試程序的代碼:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
class Vehicle { public Vehicle(){} }
class Bicycle extends Vehicle { public Bicycle(){} }
class Skateboard extends Vehicle { public Skateboard(){} }
class Boat extends Vehicle { public Boat(){} }
class Car extends Vehicle { public Car(){} }
class Aircraft extends Vehicle { public Aircraft(){} }
class Jetplane extends Aircraft { public Jetplane(){} }
class Helicopter extends Aircraft { public Helicopter(){} }
class Truck extends Vehicle { public Truck(){} }
class VehicleW
{
protected Vehicle fVehicle=null;
public boolean isInitialized=false;
public VehicleW(Class aClass)
{
if (checkVehicle(aClass))
if ((fVehicle=makeVehicle(aClass))!=null)
isInitialized=true;
}
protected boolean checkVehicle(Class aClass)
{
Class tClass = Vehicle.class;
return (tClass.isAssignableFrom(aClass));
}
protected Vehicle makeVehicle(Class aClass)
{
Vehicle tVehicle = null;
System.out.format("trying to create %s\n",aClass.toString());
Constructor c;
try
{
c=aClass.getConstructor();
}
catch(NoSuchMethodException e)
{
System.out.format(" no constructor found\n");
return null;
}
try
{
tVehicle=(Vehicle)c.newInstance();
}
catch(InvocationTargetException e)
{
System.out.println(e.toString());
}
catch(InstantiationException e)
{
System.out.println(e.toString());
}
catch(IllegalAccessException e)
{
System.out.println(e.toString());
}
return tVehicle;
}
public Vehicle getVehicle()
{
if (!isInitialized)
return null;
return fVehicle;
}
public Class getWClass()
{
if (!isInitialized)
return null;
return fVehicle.getClass();
}
}
class AircraftW extends VehicleW
{
public AircraftW(Class aClass)
{
super(aClass);
/*
Class tClass=Aircraft.class;
if (!tClass.isAssignableFrom(aClass))
return;
isInitialized=true;
*/
}
@Override
protected boolean checkVehicle(Class aClass)
{
Class tClass = Aircraft.class;
return (tClass.isAssignableFrom(aClass));
}
}
class program
{
public static void tellme(VehicleW vx)
{
String s = "failed";
if (vx.getVehicle()!=null)
s="succeeded";
System.out.format(" making %s for %s %s\n",
vx.getWClass(),vx.getClass(),s);
}
public static void main(String[] args)
{
VehicleW v1, v2, v3;
AircraftW a1, a2, a3;
v1=new VehicleW(Bicycle.class);
tellme(v1);
v2=new VehicleW(Boat.class);
tellme(v2);
v3=new VehicleW(Helicopter.class);
tellme(v3);
a1=new AircraftW(Helicopter.class);
tellme(a1);
a2=new AircraftW(Aircraft.class);
tellme(a2);
a3=new AircraftW(Truck.class);
tellme(a3);
return;
}
}
和輸出:
trying to create class Bicycle
making class Bicycle for class VehicleW succeeded
trying to create class Boat
making class Boat for class VehicleW succeeded
trying to create class Helicopter
making class Helicopter for class VehicleW succeeded
trying to create class Helicopter
making class Helicopter for class AircraftW succeeded
trying to create class Aircraft
making class Aircraft for class AircraftW succeeded
making null for class AircraftW failed
這種類型的問題的問題是,如果沒有更多關於你正在構建的系統試圖實現什麼的知識很難提出合適的設計(甚至在某種程度上它會是意見)。我想說的是,如果你的構造函數在繼承層次結構中是「不兼容的」,那麼應該告訴你繼承不是用於你正在建模的實體的正確技術 –
不要編輯你的問題到包括單詞*(已解決)*。在下面添加自己的答案,然後將該答案標記爲已接受,以便系統將問題標記爲綠色。 –