“Java subtype”和“true subtype”的区别是什么?

6

我刚刚遇到了"Java子类型"和"真子类型"这两个词汇。在一个问题中,清楚地表明它们不是相同的概念。但我找不到关于这两者之间有何区别的解释。

请问有人能够解释一下"Java子类型"和"真子类型"之间的区别吗?

3个回答

9
Java子类型是指扩展另一个类(甚至实现接口)的任何类。真正的子类型并不是语言特定的:
真正的子类型总是可以替换超类型。 “超类型保证的任何属性都必须由子类型保证(真正的子类型化)”

http://www.cs.washington.edu/education/courses/cse331/10au/lectures/subtypingexamples.pdf

该链接包含一个非常有启发性的例子。假设你有一个存储值x和y的Point2D类。现在你可以创建一个子类型Point3D并添加一个值z。如果你不重写任何方法,并小心处理equals和hashcode方法,你可以随时用Point3D实例替换Point2D实例。
当然,这只是一个简单的例子。有人可能会争论为什么不只有Point3D。也许这两个类都提供了一些方法,通过将它们分成两个类来更好地识别属于2D或3D领域。在这种情况下,这可能纯粹是一个设计决策。
class Point2D {
   int x;
   int y;
}

//true subtype
class Point3D extends Point2D {
   int z;
}

如果你有一个人类(Person)的类,然后又有两个子类型:员工(Employee)和客户(Customer),那么就会出现一个更复杂的例子。员工和客户都提供与人类相同的字段和方法。

class Person {
   String name;
   Date birthday;

   @Override
   public boolean equals(Object o){
       //simplified equals implementation, this does not fulfill equals contract!
       return name.equals(((Person)o).name);
   }
}

//true subtype, same behaviour
class Employee extends Person {
   long departmentId;
}

//not a true subtype, different behaviour -> equals
class Customer extends Person {
   long customerId;
   Date lastContact;
   String city;

   public boolean equals(Object o){
       //simplified equals implementation, this does not fulfill equals contract!
       return customerId.equals(((Customer)o).customerId);
   }
} 

在这个例子中,Employee 将是 Person 的真正子类型。然而,Customer 不是真正的子类型,因为 equals 实现不同(很可能 hashCode() 也不同),并且它的行为不同,可能不能始终替代 Person 对象。

如果您有两种类型,它们始终可以互相替换,那么我不清楚为什么您一开始要有这两种类型。 - Peter Lawrey
这是否意味着真正的子类型将返回与超类相同的输入相同的输出,但Java子类型将为具有相同输入的超类方法返回不同的结果? - SIMEL
在我发布的链接中有一个很好的例子。真正的子类型是一个相当理论化的构造。我会添加到答案中以澄清。 - Yashima

0

-1
请查看图片以了解区别。

Java Subtype Vs True Subtype

在这里,即使类 Human 没有使用 extendsimplements 关键字,它仍然具有类 Vertebrate 相似的行为。这被称为真子类型。而类 Squid 使用 extends 关键字扩展类 Vertebrate,这被称为Java子类型


为什么鱿鱼不是脊椎动物的真正子类型? - SIMEL
它是一种子类型,被称为Java子类型,因为您正在使用Java关键字。我也不知道我们在实际中可以在哪里使用它。 - Ravindra Gullapalli
3
第一个子类型不是真正的子类型,因为你需要注意在脊椎动物类中的@effects注释中方法应该返回大于0的值,但继承类返回0,这使得它比原始类更弱! - flashdisk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接