我将在代码示例中解释我的问题。我有一个名为getNewBaby()
的静态方法(我无法更改)它只返回一个Animal
类。我需要将那种动物转换为狗。到目前为止,这是我两次失败的尝试:
public static class Animal
{
public void eat(){}
}
public static class Dog extends Animal
{
public Dog(Animal animal)
{
super = animal; // <-- error 1
}
public void bark(){}
}
public static Animal getNewBaby()
{
return new Animal( /* some future parameters */ );
}
public static void main()
{
//Attempt number 1:
Dog puppy1 = (Dog)(getNewBaby()); // <-- error 2
//Attempt number 2:
Dog puppy2 = new Dog(getNewBaby()); // <-- error 3
}
如何在不更改getNewBaby()
方法的任何内容的情况下解决此问题?
答案 0 :(得分:4)
您要做的事情是不可能的:您无法重新初始化super
。
然而,有其他选择(假设您无法修改getNewBaby
):
try
/ catch
声明中附上您的广告,然后抓住ClassCastException
instanceof
检查实际类型,是Animal
,Dog
,Cat
等,并根据您的逻辑{ LI>
Animal
中可以在所有子类上重写的方法,从而解除实现修改强>
以下是一些其他主题 - 有点偏/粗,但可能对您的设计有帮助。
答案 1 :(得分:1)
我可以告诉你为什么有些事情是错的,但是如果没有关于你去哪里的更多信息,我们无法帮助你重新组织你的代码。
关于继承,以下是错误的:
public Dog(Animal animal) {
//...
}
Dog
不应需要创建Animal
,因为 Is-A Animal
,这在这里有意义。
这样的构造更符合composition,但这里不合适,您需要删除extends Animal
类上的Dog
。
super
以下在Java中是不可能的,因为super
只是将this
对象称为超类中的对象的一种方式。您也不能重新生成this
,因为 当前是此对象。
super = animal; // <-- error 1
将Animal
投射到Dog
意味着您知道该对象确实是Dog
,并且您希望编译器承担它(强制转换为因为Java强类型而需要。)
此处getNewBaby()
方法返回Animal
对象,而不是其子类,因此无法在运行时将其强制转换为Dog
(ClassCastException
)因为它只是一个Animal
(顺便说一句,它没有意义。Animal
应该是抽象的。)
答案 2 :(得分:1)
假设我正确理解了您的要求,您可以执行以下操作。而不是尝试将animal
对象分配给super
,而是将animal
对象中的值分配给Dog的超类中的相应变量。
public static class Animal
{
public Animal() {}
public int parameter1 =0;
public Animal(int param1){
this.parameter1 = param1;
}
public void eat(){}
}
public static class Dog extends Animal
{
public Dog(Animal animal) //This is not nice
{
super.parameter1 = animal.parameter1;
}
public void bark(){}
}
public static Animal getNewBaby()
{
return new Animal( 4 /*Some integer value for parameter1*/ );
}
public static void main()
{
Dog puppy2 = new Dog(getNewBaby());
}
答案 3 :(得分:1)
使用您刚刚发布的新信息作为评论(真的需要强调),这里有一个可能适合您的解决方案。
此解决方案使用组合而不是继承。这意味着您的自定义类不会extend
原始类,但包含它的实例,并在内部使用它。
由于Animal-Dog的例子,我过去常常不鼓励你使用构图,这在概念上是错误的,但这是一个不同的用例,所以答案不同; - )
public class EasySocket {
private Socket socket;
public EasySocket(Socket socket) {
this.socket = socket;
}
/*
* Here are your helper methods that use socket's methods: for instance, use
* socket.getInputStream() instead of simply getInputStream(), since you don't inherit
* from the Socket class anymore.
*/
}
然后当您收到Socket
对象时:
Socket socket = someServerSocket.accept();
EasySocket easySocket = new EasySocket(socket);
// use easySocket