与其他语言相比,Java中的具体类型和抽象类型

与其他语言相比,Java中的具体类型和抽象类型,java,javascript,python,oop,object,Java,Javascript,Python,Oop,Object,我正在准备期末考试,试图解决课本背面的练习题,这时我遇到了这个问题: 在Java中,如果p的具体类型是Foo,则p.getClass()和Foo.class 将返回相同的内容。解释为什么类似的等价物不能 保证使用Ruby、Python或JavaScript保存 有人能解释一下吗。提前谢谢 答案是强类型编程语言与弱类型编程语言。在java(或C++、C语言、VB等)中,必须在编译时显式定义一个类型。假设您有一个Java类,它如下所示: class Foo{ String a; pu

我正在准备期末考试,试图解决课本背面的练习题,这时我遇到了这个问题:

在Java中,如果p的具体类型是Foo,则p.getClass()和Foo.class 将返回相同的内容。解释为什么类似的等价物不能 保证使用Ruby、Python或JavaScript保存


有人能解释一下吗。提前谢谢

答案是强类型编程语言与弱类型编程语言。在java(或C++、C语言、VB等)中,必须在编译时显式定义一个类型。假设您有一个Java类,它如下所示:

class Foo{
    String a;
    public void DoNothing(){}
}
当你点击编译按钮时,你的类就被修复了;您不能在运行时更改它。也就是说,假设你有一个变量p,它是Foo的一个实例,你不能:

p.b = 12345;
警察会对你大喊大叫的。您肯定知道,p将有一个名为“a”的属性,它必须是一个字符串,以及一个不返回类型的方法DoNothing()

另一方面,JavaScript没有“类”的概念,因为您可以在运行时向对象动态添加(或删除)属性或字段。因此,您可以:

var x = {}; //declares a new object, it is empty right now
x["name"] = "Hello World!";
x.doWork = function() { ... };
结果是,直到在运行时执行该行时,您才知道变量“x”是否包含名为“name”的字段或名为“doWork”的函数


同样的论点也适用于Python和Ruby。

不太清楚问题是什么

如果您在python中有

class Foo(object):
    pass

p = Foo()
然后
p.。\uuuu class\uuuu
将作为对象返回
Foo
。类名可以打印为

p.__class__.__name__
还是在课堂上

Foo.__name__
当然,在python中,您可以这样做

class Foo2(object):
    pass

p.__class__ = Foo2
但没错,这是一种动态语言


所以最后一个选项非常罕见,一般来说我看不出有什么区别。

Ruby、Python和JavaScript都是动态类型语言,但这不是静态类型与动态类型的问题。相反,我认为这是因为Java的
getClass()
是最终的(不能被重写),而其他语言没有这样的限制:

#Ruby
福班
def类­()
再走
结束
结束
String.new().class()==String#=>true
Foo.new().class()==Foo#=>false
#Python
Foo班:通过
级别栏:通过
p=Foo()
p、 _uuu类uuu==Foo#=>True
p、 _uuuu类uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
p、 _uuu类uuu==Foo#=>False
//JavaScript
函数Foo(){}
函数栏(){}
var p=新的Foo();
p、 构造函数==Foo;//=>真的
p、 构造函数=Bar;
p、 构造函数==Foo;//=>假的

有趣的是,在Python的例子中,设置
\uuuu class\uuuu
成员实际上会影响方法查找,因此可以认为
p
的具体类型现在是
Bar
,这并不违反等价性。

是否存在上下文?(例如,声明
Foo
)@tom没有上下文。这是一个普遍的问题。在您的javascript示例中,
x
的具体类型不是
Foo
,那么“类似等价物”是什么呢?在Ruby中,您可以做得更好:
class Foo;def class()返回字符串end
@tom:嗯。。。你看。。。我不太喜欢那样;)但这绝对不是这里的主题。我对Python示例有点犹豫,因为它似乎实际上改变了
p
的类型。在我的Ruby示例中,具体类型显然没有改变,因为
Foo
中定义的方法仍然在
p
上工作@tom:是的,它改变了类型。事实上你的例子并不是那么。。。猴子和我一样打补丁。这就是我不喜欢的——猴子打补丁。在坏人手中,这可能是非常具有破坏性的。