Java为什么要使用对象实例化类?

Java为什么要使用对象实例化类?,java,java-7,Java,Java 7,我目前正在修改JavaSE7认证,任何参加过这些考试的人都知道他们使用的一些代码示例有多么可笑。故意编写难以理解的代码。 最近我看到很多这样编写的代码: Object obj=new Animal(); 这有什么好处?我知道这是一个有效的代码,但是这只是你在考试中永远不会用到的代码之一吗?如果不是,你什么时候以及为什么要这样做?这不是没有用处的事情。它表明Java类型系统允许您将任何对象存储在object类型的变量中,而不仅仅是直接使用new object()实例化的对象,这是可以演示它的最简

我目前正在修改JavaSE7认证,任何参加过这些考试的人都知道他们使用的一些代码示例有多么可笑。故意编写难以理解的代码。 最近我看到很多这样编写的代码:

Object obj=new Animal();

这有什么好处?我知道这是一个有效的代码,但是这只是你在考试中永远不会用到的代码之一吗?如果不是,你什么时候以及为什么要这样做?

这不是没有用处的事情。它表明Java类型系统允许您将任何对象存储在
object
类型的变量中,而不仅仅是直接使用
new object()
实例化的对象,这是可以演示它的最简单示例

每个对象都是
对象
类的子类。它表明,当您将变量的类型声明为某种类型时,您不仅可以将该类型(示例中为对象)放在那里,还可以将任何子类型(示例中为动物)放在那里

虽然对所有对象使用基类似乎并不有用,但更复杂的类层次结构可能会更好地说明这一点

假设你有更多的
动物
仓鼠
。现在让我们假设您还有许多子类,如
仓鼠
(如果有任何不同种类的仓鼠)

现在,如果要在变量中包含
动物
,可以编写:

Animal animal = new Cat();
或:

现在,您的问题的确切代码是:

Object obj = new Animal();
可以通过几种不同的方式使用:

如果您希望确保您使用的是
对象
类公开的接口,并且在继承链的后面没有添加任何内容

您还可以拥有5只狗的阵列:

Dog[] dogs = new Dogs[5];
你可以放狗,但不能放猫或仓鼠

public class Animal { // implicitly extends Object
    // ...
}
public class Dog extends Animal {
    // ...
}
public class Cat extends Animal {
    // ...
}
public class Hamster extends Animal {
    // ...
}
public class Hamster extends Animal {
    // ...
}
Labrador extends Dog {
    // ...
}
// etc.
您可以有一个动物数组,可以放置任何动物,但不能放置其他对象,例如数字:

Animal[] animals = new Animals[5];
现在,为什么会有这样一个数组?例如,如果您的
Animal
类具有
getName
方法,则您可以始终运行:

animals[2].getName();
不管那里有哪种动物。但是如果
Dog
类有一个方法
bark()
,而
Cat
类没有,那么您将无法运行:

animals[2].bark();
(不是没有显式强制转换)即使
Dog
实例确实存储在该索引下的animals中,因为编译器不知道在运行时该数组中会有什么-它所能保证的只是会有一些animal在那里,所以您只能调用那些确保对所有动物都存在的方法


这听起来可能很傻,但你会发现它确实在很多地方被使用。例如,在GUI编程中,您可以有一个滚动面板,在其中可以放置任何组件,如按钮或文本字段,但根本不能放置任何对象,这正是由该机制保证的-例如
JPanel
对象有一个方法
add()
接受类
组件的组件
,但不必使用
新组件()创建,但可以是
JLabel
或另一个
JPanel
它表明
对象
动物
的基类(父类)

换句话说,即使你没有写

public class Animal extends Object {
}
“扩展对象”中添加的编译器;因为,所有类都扩展了
对象


对于Java语言中的所有类来说都是如此,虽然示例在教学中选择得不好,但如果您理解这样一个概念,它(在某些方面)是一种一般的测试方法。很有可能您不会在常规开发中使用此技术。

如果
obj
变量的使用不依赖于它是否是
动物,则这可能很有用。例如,假设您将新对象传递给使用
toString()
打印它的函数。那么,
obj
的确切类别就不相关了。代码说明了这一点。

它基本上是一个动态绑定。。 Object obj=新动物();这意味着您正在为animal类创建对象,其地址存储在引用变量obj中。。 对象obj表示只能通过动物类对象访问对象类的函数。。。。 让我们通过这个小程序来理解

class Object
{
    void fun()
    {
        System.out.println("hello");
    }
}

class Animal extends Object
{
    void fun1()
    {
        System.out.println("hi");
    }

    public static void main(String args[])
    {
        Object obj = new Animal();
        obj.fun();
    }
}

output hello

关于为什么会有这样的代码,我想到的唯一原因是在Java中演示多态性。在任何实际的实现中,使用这样的代码都需要大量的转换,这不是真实世界的模式(或者在非常罕见的情况下)。这取决于接下来是什么。假设我们看到一个
obj.toString()
,输出是什么?毕竟,这是一个考题,用来检查某人是否理解了这些概念。这是针对一个只有对象方面起作用的上下文。比如将对象序列化(存储)到磁盘等。在
List List=new ArrayList()中它有真正的意义:按照契约i.o.实现。或者可能是反向编译器的输出?如果obj的所有剩余用法都只是将强制转换为对象的方法参数(例如,作为哈希表值传递)。同时,您经常可以看到类似于
List x=new ArrayList()的内容;
在真实代码中,您不希望在整个类中包含特定的实现类型。类似的概念适用,可能考试代码只是通过不使用更复杂的层次结构使事情变得更简单。我看不出这是如何回答问题的。如果要使用
对象[]
那么也许我可以扩展我的想象力,但对我来说,以目前的形式,它根本没有解决这个问题。我同意Polygenme所说的,这个问题明确地说明了为什么这个例子会向对象施压,而不是为什么或者如何施压
class Object
{
    void fun()
    {
        System.out.println("hello");
    }
}

class Animal extends Object
{
    void fun1()
    {
        System.out.println("hi");
    }

    public static void main(String args[])
    {
        Object obj = new Animal();
        obj.fun();
    }
}