简体   繁体   English

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

[英]Concrete types and abstract types in Java when compared to other languages

I am preparing for my finals and trying to solve exercise problems on the back of the textbook when i came across this question: 当我遇到以下问题时,我正在准备决赛,并尝试在教科书背面解决运动问题:

In Java, if the concrete type of p is Foo, p.getClass() and Foo.class will return the same thing. 在Java中,如果p的具体类型是Foo,则p.getClass()和Foo.class将返回相同的内容。 Explain why a similar equivalence could not be guaranteed to hold in Ruby, Python, or JavaScript. 解释为什么不能保证在Ruby,Python或JavaScript中保持类似的等效性。

Can anyone shed some light on this. 任何人都可以阐明这一点。 Thanks in advance! 提前致谢!

The answer is strongly typed vs weakly typed programming languages. 答案是强类型编程语言与弱类型编程语言。 In Java (or C++, C#, VB etc.) a type must be explicitly defined at compile time. 在Java(或C ++,C#,VB等)中,必须在编译时明确定义类型。 So let's say you have a class in Java that looks like this: 因此,假设您有一个Java类,如下所示:

class Foo{
    String a;
    public void DoNothing(){}
}

The moment you hit the compile button, your class is fixed; 按下编译按钮后,您的班级就固定了; you cannot change it at runtime. 您不能在运行时更改它。 That is to say, let's say you have a variable p, which is an instance of Foo, you cannot do: 就是说,假设您有一个变量p,它是Foo的一个实例,您不能执行以下操作:

p.b = 12345;

The compile will yell at you. 编译会大喊大叫。 And you know FOR SURE, p will have a property called "a", it HAS to be a String, and a method DoNothing() which returns no type. 而且您肯定知道,p将具有一个称为“ a”的属性,它必须是一个字符串,以及一个不返回任何类型的方法DoNothing()。

JavaScript, on the other hand, does not have a concept of a "class", because you can dynamically add (or remove) properties or fields to an object at runtime. 另一方面,JavaScript没有“类”的概念,因为您可以在运行时动态地向对象添加(或删除)属性或字段。 So you can do: 因此,您可以执行以下操作:

var x = {}; //declares a new object, it is empty right now
x["name"] = "Hello World!";
x.doWork = function() { ... };

The result is, you will not know whether the variable "x" contains the field called "name" or a function called "doWork" until the moment you execute that line at runtime. 结果是,直到在运行时执行该行之前,您都不知道变量“ x”是否包含名为“ name”的字段或包含名为“ doWork”的函数。

Same argument applies for Python and Ruby. 同样的论点适用于Python和Ruby。

Not quite sure what is asked. 不太确定要问什么。

If you have in python 如果您有python

class Foo(object):
    pass

p = Foo()

then p.__class__ would return Foo as an object. 那么p.__class__将返回Foo作为对象。 The class name could be printed with 班级名称可以用

p.__class__.__name__

or on class 或上课

Foo.__name__

Of course in python you can do something like this 当然,在python中,您可以执行以下操作

class Foo2(object):
    pass

p.__class__ = Foo2

But yes, it's dynamic language. 但是,是的,它是动态语言。

So the last option is quite rare and in general I can't see difference. 因此,最后一种选择非常少见,总的来说我看不出有什么区别。

Ruby, Python and JavaScript are all dynamically typed languages, but this is not a question of static vs. dynamic typing. Ruby,Python和JavaScript都是动态类型化的语言,但这不是静态类型还是动态类型的问题。 Rather, I think it is to do with the fact that Java's getClass() is final (cannot be overridden) while the other languages do not have such restrictions: 相反,我认为这与Java的getClass()是最终的(不能被覆盖)而其他语言没有这样的限制有关:

# Ruby
class Foo
  def class­()
    retur­n Strin­g
  end
end
String.new().class() == String # => true
Foo.new().class() == Foo # => false
# Python
class Foo: pass
class Bar: pass
p = Foo()
p.__class__ == Foo # => True
p.__class__ = Bar
p.__class__ == Foo # => False
// JavaScript
function Foo() { }
function Bar() { }
var p = new Foo();
p.constructor == Foo; // => true
p.constructor = Bar;
p.constructor == Foo; // => false

Interestingly, in Python's case setting the __class__ member actually affects method lookup so it could be argued that the concrete type of p is now Bar , which does not violate the equivalence. 有趣的是,在Python的情况下,设置__class__成员实际上会影响方法查找,因此可以说p的具体类型现在是Bar ,这并不违反等效性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM